diff options
author | Armin Rigo <arigo@tunes.org> | 2020-01-19 10:23:34 +0100 |
---|---|---|
committer | Armin Rigo <arigo@tunes.org> | 2020-01-19 10:23:34 +0100 |
commit | 4840f2bf291dfa58af123768a66b1a49e3af31a4 (patch) | |
tree | a16e1b0cccad87e87267dd092cdd2f79a4380653 /c/_cffi_backend.c | |
parent | 7c871d4fe57e7f6c5d034b22326bc439aa6c6538 (diff) | |
download | cffi-4840f2bf291dfa58af123768a66b1a49e3af31a4.tar.gz |
Issue #440
Limit the amount of memory that is requested from alloca()
for temporary conversion of arguments. Non-small requests are
instead handled with PyObject_Malloc() and PyObject_Free().
Diffstat (limited to 'c/_cffi_backend.c')
-rw-r--r-- | c/_cffi_backend.c | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c index 212a019..6826780 100644 --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -2991,6 +2991,10 @@ cdata_call(CDataObject *cd, PyObject *args, PyObject *kwds) CTypeDescrObject *fresult; char *resultdata; char *errormsg; + struct freeme_s { + struct freeme_s *next; + union_alignment alignment; + } *freeme = NULL; if (!(cd->c_type->ct_flags & CT_FUNCTIONPTR)) { PyErr_Format(PyExc_TypeError, "cdata '%s' is not callable", @@ -3111,7 +3115,21 @@ cdata_call(CDataObject *cd, PyObject *args, PyObject *kwds) else if (datasize < 0) goto error; else { - tmpbuf = alloca(datasize); + if (datasize <= 512) { + tmpbuf = alloca(datasize); + } + else { + struct freeme_s *fp = (struct freeme_s *)PyObject_Malloc( + offsetof(struct freeme_s, alignment) + + (size_t)datasize); + if (fp == NULL) { + PyErr_NoMemory(); + goto error; + } + fp->next = freeme; + freeme = fp; + tmpbuf = (char *)&fp->alignment; + } memset(tmpbuf, 0, datasize); *(char **)data = tmpbuf; if (convert_array_from_object(tmpbuf, argtype, obj) < 0) @@ -3156,6 +3174,11 @@ cdata_call(CDataObject *cd, PyObject *args, PyObject *kwds) /* fall-through */ error: + while (freeme != NULL) { + void *p = (void *)freeme; + freeme = freeme->next; + PyObject_Free(p); + } if (buffer) PyObject_Free(buffer); if (fvarargs != NULL) { |