diff options
author | Peter Lazorchak <lazorchakp@gmail.com> | 2024-02-06 13:58:30 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-06 13:58:30 (GMT) |
commit | a11312456d05a06feed00ee9e530e50fcadb7011 (patch) | |
tree | 80c7f99f90e503de19a2779f2b16569964437b0f /Python | |
parent | 2e99ba9e90ba636dac9ad955ca1d9d67fc72b841 (diff) | |
download | cpython-a11312456d05a06feed00ee9e530e50fcadb7011.zip cpython-a11312456d05a06feed00ee9e530e50fcadb7011.tar.gz cpython-a11312456d05a06feed00ee9e530e50fcadb7011.tar.bz2 |
[3.11] gh-89811: Check for valid tp_version_tag in specializer (GH-115045)
* gh-89811: Check for valid tp_version_tag in specializer (GH-113558)
* gh-113937 Fix failures in type cache tests due to re-running (GH-113953)
* Update backported code for 3.11 specifically
Diffstat (limited to 'Python')
-rw-r--r-- | Python/specialize.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/Python/specialize.c b/Python/specialize.c index 4a5213c..3441e84 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -481,6 +481,7 @@ miss_counter_start(void) { #define SPEC_FAIL_UNPACK_SEQUENCE_ITERATOR 8 #define SPEC_FAIL_UNPACK_SEQUENCE_SEQUENCE 9 +static uint32_t type_get_version(PyTypeObject *t, int opcode); static int specialize_module_load_attr(PyObject *owner, _Py_CODEUNIT *instr, @@ -673,6 +674,9 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) } PyObject *descr; DescriptorClassification kind = analyze_descriptor(type, name, &descr, 0); + if (type_get_version(type, LOAD_ATTR) == 0) { + goto fail; + } switch(kind) { case OVERRIDING: SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_OVERRIDING_DESCRIPTOR); @@ -766,6 +770,9 @@ _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) } PyObject *descr; DescriptorClassification kind = analyze_descriptor(type, name, &descr, 1); + if (type_get_version(type, STORE_ATTR) == 0) { + goto fail; + } switch(kind) { case OVERRIDING: SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_ATTR_OVERRIDING_DESCRIPTOR); @@ -889,6 +896,9 @@ specialize_class_load_method(PyObject *owner, _Py_CODEUNIT *instr, PyObject *descr = NULL; DescriptorClassification kind = 0; kind = analyze_descriptor((PyTypeObject *)owner, name, &descr, 0); + if (type_get_version((PyTypeObject *)owner, LOAD_METHOD) == 0) { + return -1; + } switch (kind) { case METHOD: case NON_DESCRIPTOR: @@ -950,6 +960,9 @@ _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) PyObject *descr = NULL; DescriptorClassification kind = 0; kind = analyze_descriptor(owner_cls, name, &descr, 0); + if (type_get_version(owner_cls, LOAD_METHOD) == 0) { + goto fail; + } assert(descr != NULL || kind == ABSENT || kind == GETSET_OVERRIDDEN); if (kind != METHOD) { SPECIALIZATION_FAIL(LOAD_METHOD, load_method_fail_kind(kind)); @@ -1183,6 +1196,18 @@ function_kind(PyCodeObject *code) { return SIMPLE_FUNCTION; } +/* Returning 0 indicates a failure. */ +static uint32_t +type_get_version(PyTypeObject *t, int opcode) +{ + uint32_t version = t->tp_version_tag; + if (version == 0) { + SPECIALIZATION_FAIL(opcode, SPEC_FAIL_OUT_OF_VERSIONS); + return 0; + } + return version; +} + int _Py_Specialize_BinarySubscr( PyObject *container, PyObject *sub, _Py_CODEUNIT *instr) @@ -1231,6 +1256,9 @@ _Py_Specialize_BinarySubscr( SPECIALIZATION_FAIL(BINARY_SUBSCR, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS); goto fail; } + if (type_get_version(cls, BINARY_SUBSCR) == 0) { + goto fail; + } assert(cls->tp_version_tag != 0); write_u32(cache->type_version, cls->tp_version_tag); int version = _PyFunction_GetVersionForCurrentState(func); |