diff options
author | Armin Rigo <arigo@tunes.org> | 2019-10-21 11:24:17 +0200 |
---|---|---|
committer | Armin Rigo <arigo@tunes.org> | 2019-10-21 11:24:17 +0200 |
commit | 6ea8b8f9c0bbe87ba21b51c1bb540ea0e69a4e60 (patch) | |
tree | 15f48e8c522fc5a39edc065e7eed73835d98aa4e /c | |
parent | e97940538548db03bdb341a3072e3bf505317d2d (diff) | |
download | cffi-6ea8b8f9c0bbe87ba21b51c1bb540ea0e69a4e60.tar.gz |
Issue #429
There are corner cases in which we can see a recursion on the same types.
Instead of fighting them all, change the logic to complain if we recurse
more than 1000 times.
Diffstat (limited to 'c')
-rw-r--r-- | c/realize_c_type.c | 23 |
1 files changed, 12 insertions, 11 deletions
diff --git a/c/realize_c_type.c b/c/realize_c_type.c index 778f320..82629b7 100644 --- a/c/realize_c_type.c +++ b/c/realize_c_type.c @@ -631,14 +631,6 @@ realize_c_type_or_func_now(builder_c_t *builder, _cffi_opcode_t op, break; } - case 255: /* recursion detection */ - PyErr_Format(PyExc_RuntimeError, - "found a situation in which we try to build a type recursively. " - "This is known to occur e.g. in ``struct s { void(*callable)" - "(struct s); }''. Please report if you get this error and " - "really need support for your case."); - return NULL; - default: PyErr_Format(PyExc_NotImplementedError, "op=%d", (int)_CFFI_GETOP(op)); return NULL; @@ -647,6 +639,8 @@ realize_c_type_or_func_now(builder_c_t *builder, _cffi_opcode_t op, return x; } +static int _realize_recursion_level; + static PyObject * realize_c_type_or_func(builder_c_t *builder, _cffi_opcode_t opcodes[], int index) @@ -660,10 +654,17 @@ realize_c_type_or_func(builder_c_t *builder, return x; } - opcodes[index] = (_cffi_opcode_t)255; /* recursion detection */ + if (_realize_recursion_level >= 1000) { + PyErr_Format(PyExc_RuntimeError, + "type-building recursion too deep or infinite. " + "This is known to occur e.g. in ``struct s { void(*callable)" + "(struct s); }''. Please report if you get this error and " + "really need support for your case."); + return NULL; + } + _realize_recursion_level++; x = realize_c_type_or_func_now(builder, op, opcodes, index); - if (opcodes[index] == (_cffi_opcode_t)255) - opcodes[index] = op; + _realize_recursion_level--; if (x != NULL && opcodes == builder->ctx.types && opcodes[index] != x) { assert((((uintptr_t)x) & 1) == 0); |