summaryrefslogtreecommitdiff
path: root/c
diff options
context:
space:
mode:
authorArmin Rigo <arigo@tunes.org>2019-10-21 11:24:17 +0200
committerArmin Rigo <arigo@tunes.org>2019-10-21 11:24:17 +0200
commit6ea8b8f9c0bbe87ba21b51c1bb540ea0e69a4e60 (patch)
tree15f48e8c522fc5a39edc065e7eed73835d98aa4e /c
parente97940538548db03bdb341a3072e3bf505317d2d (diff)
downloadcffi-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.c23
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);