Author: Armin Rigo <[email protected]>
Branch:
Changeset: r3301:3873bbdd3b9e
Date: 2019-10-21 11:24 +0200
http://bitbucket.org/cffi/cffi/changeset/3873bbdd3b9e/
Log: 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.
diff --git a/c/realize_c_type.c b/c/realize_c_type.c
--- a/c/realize_c_type.c
+++ b/c/realize_c_type.c
@@ -631,14 +631,6 @@
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 @@
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 @@
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);
diff --git a/testing/cffi1/test_re_python.py b/testing/cffi1/test_re_python.py
--- a/testing/cffi1/test_re_python.py
+++ b/testing/cffi1/test_re_python.py
@@ -75,6 +75,7 @@
struct with_union { union { int a; char b; }; };
union with_struct { struct { int a; char b; }; };
struct NVGcolor { union { float rgba[4]; struct { float r,g,b,a; }; }; };
+ typedef struct selfref { struct selfref *next; } *selfref_ptr_t;
""")
ffi.set_source('re_python_pysrc', None)
ffi.emit_python_code(str(tmpdir.join('re_python_pysrc.py')))
@@ -254,3 +255,8 @@
assert ffi.offsetof("struct NVGcolor", "g") == FLOAT
assert ffi.offsetof("struct NVGcolor", "b") == FLOAT * 2
assert ffi.offsetof("struct NVGcolor", "a") == FLOAT * 3
+
+def test_selfref():
+ # based on issue #429
+ from re_python_pysrc import ffi
+ ffi.new("selfref_ptr_t")
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit