summaryrefslogtreecommitdiff
path: root/cffi/_cffi_include.h
diff options
context:
space:
mode:
authorArmin Rigo <arigo@tunes.org>2020-01-19 10:23:34 +0100
committerArmin Rigo <arigo@tunes.org>2020-01-19 10:23:34 +0100
commit4840f2bf291dfa58af123768a66b1a49e3af31a4 (patch)
treea16e1b0cccad87e87267dd092cdd2f79a4380653 /cffi/_cffi_include.h
parent7c871d4fe57e7f6c5d034b22326bc439aa6c6538 (diff)
downloadcffi-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.h48
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