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 /cffi/_cffi_include.h | |
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 'cffi/_cffi_include.h')
-rw-r--r-- | cffi/_cffi_include.h | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/cffi/_cffi_include.h b/cffi/_cffi_include.h index 2eeb49b..3129150 100644 --- a/cffi/_cffi_include.h +++ b/cffi/_cffi_include.h @@ -269,6 +269,54 @@ _CFFI_UNUSED_FN static PyObject *_cffi_from_c_char32_t(unsigned int x) return _cffi_from_c_wchar3216_t((int)x); } +union _cffi_union_alignment_u { + unsigned char m_char; + unsigned short m_short; + unsigned int m_int; + unsigned long m_long; + unsigned long long m_longlong; + float m_float; + double m_double; + long double m_longdouble; +}; + +struct _cffi_freeme_s { + struct _cffi_freeme_s *next; + union _cffi_union_alignment_u alignment; +}; + +_CFFI_UNUSED_FN static int +_cffi_convert_array_argument(struct _cffi_ctypedescr *ctptr, PyObject *arg, + char **output_data, Py_ssize_t datasize, + struct _cffi_freeme_s **freeme) +{ + char *p; + if (datasize < 0) + return -1; + + p = *output_data; + if (p == NULL) { + struct _cffi_freeme_s *fp = (struct _cffi_freeme_s *)PyObject_Malloc( + offsetof(struct _cffi_freeme_s, alignment) + (size_t)datasize); + if (fp == NULL) + return -1; + fp->next = *freeme; + *freeme = fp; + p = *output_data = (char *)&fp->alignment; + } + memset((void *)p, 0, (size_t)datasize); + return _cffi_convert_array_from_object(p, ctptr, arg); +} + +_CFFI_UNUSED_FN static void +_cffi_free_array_arguments(struct _cffi_freeme_s *freeme) +{ + do { + void *p = (void *)freeme; + freeme = freeme->next; + PyObject_Free(p); + } while (freeme != NULL); +} /********** end CPython-specific section **********/ #else |