8000 add a few more checks to safeguard specializations · python/cpython@6d806a2 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6d806a2

Browse files
add a few more checks to safeguard specializations
1 parent 33445d5 commit 6d806a2

File tree

1 file changed

+11
-1
lines changed

1 file changed

+11
-1
lines changed

Python/specialize.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -819,6 +819,7 @@ _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name,
819819
_PyObjectCache *cache2 = &cache[-2].obj;
820820

821821
PyTypeObject *owner_cls = Py_TYPE(owner);
822+
PyDictObject *owner_dict = NULL;
822823
if (PyModule_CheckExact(owner)) {
823824
int err = specialize_module_load_attr(owner, instr, name, cache0, cache1,
824825
LOAD_METHOD, LOAD_METHOD_MODULE);
@@ -846,11 +847,18 @@ _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name,
846847
}
847848
PyObject **owner_dictptr = _PyObject_GetDictPtr(owner);
848849
int owner_has_dict = (owner_dictptr != NULL && *owner_dictptr != NULL);
849-
PyDictObject *owner_dict = owner_has_dict ? (PyDictObject *)*owner_dictptr : NULL;
850+
owner_dict = owner_has_dict ? (PyDictObject *)*owner_dictptr : NULL;
851+
Py_XINCREF(owner_dict); // make sure dict doesn't disappear halfway
850852
// Check for classmethods.
851853
int owner_is_class = PyType_Check(owner);
852854
owner_cls = owner_is_class ? (PyTypeObject *)owner : owner_cls;
853855

856+
if ((owner_cls->tp_flags & Py_TPFLAGS_VALID_VERSION_TAG) == 0 ||
857+
owner_cls->tp_version_tag == 0) {
858+
SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_OUT_OF_VERSIONS);
859+
goto fail;
860+
}
861+
854862
PyObject *descr = NULL;
855863
DesciptorClassification kind = 0;
856864
kind = analyze_descriptor(owner_cls, name, &descr, 0);
@@ -928,11 +936,13 @@ _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name,
928936
LOAD_METHOD_CACHED, _Py_OPARG(*instr));
929937
// Fall through.
930938
success:
939+
Py_XDECREF(owner_dict);
931940
STAT_INC(LOAD_METHOD, specialization_success);
932941
assert(!PyErr_Occurred());
933942
cache0->counter = saturating_start();
934943
return 0;
935944
fail:
945+
Py_XDECREF(owner_dict);
936946
STAT_INC(LOAD_METHOD, specialization_failure);
937947
assert(!PyErr_Occurred());
938948
cache_backoff(cache0);

0 commit comments

Comments
 (0)
0