| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 75635c6 commit a285af7
3 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -287,6 +287,21 @@ def callback(check, s): | |||
| 287 | 287 | self.assertEqual(s.second, check.second) | |
| 288 | 288 | self.assertEqual(s.third, check.third) | |
| 289 | 289 | ||
| 290 | + def test_callback_too_many_args(self): | ||
| 291 | + def func(*args): | ||
| 292 | + return len(args) | ||
| 293 | + | ||
| 294 | + CTYPES_MAX_ARGCOUNT = 1024 | ||
| 295 | + proto = CFUNCTYPE(c_int, *(c_int,) * CTYPES_MAX_ARGCOUNT) | ||
| 296 | + cb = proto(func) | ||
| 297 | + args1 = (1,) * CTYPES_MAX_ARGCOUNT | ||
| 298 | + self.assertEqual(cb(*args1), CTYPES_MAX_ARGCOUNT) | ||
| 299 | + | ||
| 300 | + args2 = (1,) * (CTYPES_MAX_ARGCOUNT + 1) | ||
| 301 | + with self.assertRaises(ArgumentError): | ||
| 302 | + cb(*args2) | ||
| 303 | + | ||
| 304 | + | ||
| 290 | 305 | ################################################################ | |
| 291 | 306 | ||
| 292 | 307 | if __name__ == '__main__': | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1 @@ | |||
| 1 | + ``ctypes`` now raises an ``ArgumentError`` when a callback is invoked with more than 1024 arguments. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1073,6 +1073,14 @@ GetComError(HRESULT errcode, GUID *riid, IUnknown *pIunk) | |||
| 1073 | 1073 | #define IS_PASS_BY_REF(x) (x > 8 || !POW2(x)) | |
| 1074 | 1074 | #endif | |
| 1075 | 1075 | ||
| 1076 | + /* | ||
| 1077 | + * bpo-13097: Max number of arguments _ctypes_callproc will accept. | ||
| 1078 | + * | ||
| 1079 | + * This limit is enforced for the `alloca()` call in `_ctypes_callproc`, | ||
| 1080 | + * to avoid allocating a massive buffer on the stack. | ||
| 1081 | + */ | ||
| 1082 | + #define CTYPES_MAX_ARGCOUNT 1024 | ||
| 1083 | + | ||
| 1076 | 1084 | /* | |
| 1077 | 1085 | * Requirements, must be ensured by the caller: | |
| 1078 | 1086 | * - argtuple is tuple of arguments | |
@@ -1108,6 +1116,13 @@ PyObject *_ctypes_callproc(PPROC pProc, | |||
| 1108 | 1116 | ++argcount; | |
| 1109 | 1117 | #endif | |
| 1110 | 1118 | ||
| 1119 | + if (argcount > CTYPES_MAX_ARGCOUNT) | ||
| 1120 | + { | ||
| 1121 | + PyErr_Format(PyExc_ArgError, "too many arguments (%zi), maximum is %i", | ||
| 1122 | + argcount, CTYPES_MAX_ARGCOUNT); | ||
| 1123 | + return NULL; | ||
| 1124 | + } | ||
| 1125 | + | ||
| 1111 | 1126 | args = (struct argument *)alloca(sizeof(struct argument) * argcount); | |
| 1112 | 1127 | if (!args) { | |
| 1113 | 1128 | PyErr_NoMemory(); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments