mirror of https://github.com/python/cpython
bpo-9263: _PyXXX_CheckConsistency() use _PyObject_ASSERT() (GH-10108)
Use _PyObject_ASSERT() in: * _PyDict_CheckConsistency() * _PyType_CheckConsistency() * _PyUnicode_CheckConsistency() _PyObject_ASSERT() dumps the faulty object if the assertion fails to help debugging.
This commit is contained in:
parent
0862505a03
commit
50fe3f8913
|
@ -439,6 +439,8 @@ static PyObject *empty_values[1] = { NULL };
|
||||||
static int
|
static int
|
||||||
_PyDict_CheckConsistency(PyDictObject *mp)
|
_PyDict_CheckConsistency(PyDictObject *mp)
|
||||||
{
|
{
|
||||||
|
#define ASSERT(expr) _PyObject_ASSERT((PyObject *)mp, (expr))
|
||||||
|
|
||||||
PyDictKeysObject *keys = mp->ma_keys;
|
PyDictKeysObject *keys = mp->ma_keys;
|
||||||
int splitted = _PyDict_HasSplitTable(mp);
|
int splitted = _PyDict_HasSplitTable(mp);
|
||||||
Py_ssize_t usable = USABLE_FRACTION(keys->dk_size);
|
Py_ssize_t usable = USABLE_FRACTION(keys->dk_size);
|
||||||
|
@ -447,23 +449,23 @@ _PyDict_CheckConsistency(PyDictObject *mp)
|
||||||
Py_ssize_t i;
|
Py_ssize_t i;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
assert(0 <= mp->ma_used && mp->ma_used <= usable);
|
ASSERT(0 <= mp->ma_used && mp->ma_used <= usable);
|
||||||
assert(IS_POWER_OF_2(keys->dk_size));
|
ASSERT(IS_POWER_OF_2(keys->dk_size));
|
||||||
assert(0 <= keys->dk_usable
|
ASSERT(0 <= keys->dk_usable
|
||||||
&& keys->dk_usable <= usable);
|
&& keys->dk_usable <= usable);
|
||||||
assert(0 <= keys->dk_nentries
|
ASSERT(0 <= keys->dk_nentries
|
||||||
&& keys->dk_nentries <= usable);
|
&& keys->dk_nentries <= usable);
|
||||||
assert(keys->dk_usable + keys->dk_nentries <= usable);
|
ASSERT(keys->dk_usable + keys->dk_nentries <= usable);
|
||||||
|
|
||||||
if (!splitted) {
|
if (!splitted) {
|
||||||
/* combined table */
|
/* combined table */
|
||||||
assert(keys->dk_refcnt == 1);
|
ASSERT(keys->dk_refcnt == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_PYDICT
|
#ifdef DEBUG_PYDICT
|
||||||
for (i=0; i < keys->dk_size; i++) {
|
for (i=0; i < keys->dk_size; i++) {
|
||||||
Py_ssize_t ix = dk_get_index(keys, i);
|
Py_ssize_t ix = dk_get_index(keys, i);
|
||||||
assert(DKIX_DUMMY <= ix && ix <= usable);
|
ASSERT(DKIX_DUMMY <= ix && ix <= usable);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0; i < usable; i++) {
|
for (i=0; i < usable; i++) {
|
||||||
|
@ -473,32 +475,34 @@ _PyDict_CheckConsistency(PyDictObject *mp)
|
||||||
if (key != NULL) {
|
if (key != NULL) {
|
||||||
if (PyUnicode_CheckExact(key)) {
|
if (PyUnicode_CheckExact(key)) {
|
||||||
Py_hash_t hash = ((PyASCIIObject *)key)->hash;
|
Py_hash_t hash = ((PyASCIIObject *)key)->hash;
|
||||||
assert(hash != -1);
|
ASSERT(hash != -1);
|
||||||
assert(entry->me_hash == hash);
|
ASSERT(entry->me_hash == hash);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* test_dict fails if PyObject_Hash() is called again */
|
/* test_dict fails if PyObject_Hash() is called again */
|
||||||
assert(entry->me_hash != -1);
|
ASSERT(entry->me_hash != -1);
|
||||||
}
|
}
|
||||||
if (!splitted) {
|
if (!splitted) {
|
||||||
assert(entry->me_value != NULL);
|
ASSERT(entry->me_value != NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (splitted) {
|
if (splitted) {
|
||||||
assert(entry->me_value == NULL);
|
ASSERT(entry->me_value == NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (splitted) {
|
if (splitted) {
|
||||||
/* splitted table */
|
/* splitted table */
|
||||||
for (i=0; i < mp->ma_used; i++) {
|
for (i=0; i < mp->ma_used; i++) {
|
||||||
assert(mp->ma_values[i] != NULL);
|
ASSERT(mp->ma_values[i] != NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
#undef ASSERT
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -134,15 +134,19 @@ skip_signature(const char *doc)
|
||||||
static int
|
static int
|
||||||
_PyType_CheckConsistency(PyTypeObject *type)
|
_PyType_CheckConsistency(PyTypeObject *type)
|
||||||
{
|
{
|
||||||
|
#define ASSERT(expr) _PyObject_ASSERT((PyObject *)type, (expr))
|
||||||
|
|
||||||
if (!(type->tp_flags & Py_TPFLAGS_READY)) {
|
if (!(type->tp_flags & Py_TPFLAGS_READY)) {
|
||||||
/* don't check types before PyType_Ready() */
|
/* don't check types before PyType_Ready() */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(!(type->tp_flags & Py_TPFLAGS_READYING));
|
ASSERT(!(type->tp_flags & Py_TPFLAGS_READYING));
|
||||||
assert(type->tp_mro != NULL && PyTuple_Check(type->tp_mro));
|
ASSERT(type->tp_mro != NULL && PyTuple_Check(type->tp_mro));
|
||||||
assert(type->tp_dict != NULL);
|
ASSERT(type->tp_dict != NULL);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
#undef ASSERT
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -363,17 +363,19 @@ PyUnicode_GetMax(void)
|
||||||
int
|
int
|
||||||
_PyUnicode_CheckConsistency(PyObject *op, int check_content)
|
_PyUnicode_CheckConsistency(PyObject *op, int check_content)
|
||||||
{
|
{
|
||||||
|
#define ASSERT(expr) _PyObject_ASSERT(op, (expr))
|
||||||
|
|
||||||
PyASCIIObject *ascii;
|
PyASCIIObject *ascii;
|
||||||
unsigned int kind;
|
unsigned int kind;
|
||||||
|
|
||||||
assert(PyUnicode_Check(op));
|
ASSERT(PyUnicode_Check(op));
|
||||||
|
|
||||||
ascii = (PyASCIIObject *)op;
|
ascii = (PyASCIIObject *)op;
|
||||||
kind = ascii->state.kind;
|
kind = ascii->state.kind;
|
||||||
|
|
||||||
if (ascii->state.ascii == 1 && ascii->state.compact == 1) {
|
if (ascii->state.ascii == 1 && ascii->state.compact == 1) {
|
||||||
assert(kind == PyUnicode_1BYTE_KIND);
|
ASSERT(kind == PyUnicode_1BYTE_KIND);
|
||||||
assert(ascii->state.ready == 1);
|
ASSERT(ascii->state.ready == 1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PyCompactUnicodeObject *compact = (PyCompactUnicodeObject *)op;
|
PyCompactUnicodeObject *compact = (PyCompactUnicodeObject *)op;
|
||||||
|
@ -381,41 +383,41 @@ _PyUnicode_CheckConsistency(PyObject *op, int check_content)
|
||||||
|
|
||||||
if (ascii->state.compact == 1) {
|
if (ascii->state.compact == 1) {
|
||||||
data = compact + 1;
|
data = compact + 1;
|
||||||
assert(kind == PyUnicode_1BYTE_KIND
|
ASSERT(kind == PyUnicode_1BYTE_KIND
|
||||||
|| kind == PyUnicode_2BYTE_KIND
|
|| kind == PyUnicode_2BYTE_KIND
|
||||||
|| kind == PyUnicode_4BYTE_KIND);
|
|| kind == PyUnicode_4BYTE_KIND);
|
||||||
assert(ascii->state.ascii == 0);
|
ASSERT(ascii->state.ascii == 0);
|
||||||
assert(ascii->state.ready == 1);
|
ASSERT(ascii->state.ready == 1);
|
||||||
assert (compact->utf8 != data);
|
ASSERT (compact->utf8 != data);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PyUnicodeObject *unicode = (PyUnicodeObject *)op;
|
PyUnicodeObject *unicode = (PyUnicodeObject *)op;
|
||||||
|
|
||||||
data = unicode->data.any;
|
data = unicode->data.any;
|
||||||
if (kind == PyUnicode_WCHAR_KIND) {
|
if (kind == PyUnicode_WCHAR_KIND) {
|
||||||
assert(ascii->length == 0);
|
ASSERT(ascii->length == 0);
|
||||||
assert(ascii->hash == -1);
|
ASSERT(ascii->hash == -1);
|
||||||
assert(ascii->state.compact == 0);
|
ASSERT(ascii->state.compact == 0);
|
||||||
assert(ascii->state.ascii == 0);
|
ASSERT(ascii->state.ascii == 0);
|
||||||
assert(ascii->state.ready == 0);
|
ASSERT(ascii->state.ready == 0);
|
||||||
assert(ascii->state.interned == SSTATE_NOT_INTERNED);
|
ASSERT(ascii->state.interned == SSTATE_NOT_INTERNED);
|
||||||
assert(ascii->wstr != NULL);
|
ASSERT(ascii->wstr != NULL);
|
||||||
assert(data == NULL);
|
ASSERT(data == NULL);
|
||||||
assert(compact->utf8 == NULL);
|
ASSERT(compact->utf8 == NULL);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert(kind == PyUnicode_1BYTE_KIND
|
ASSERT(kind == PyUnicode_1BYTE_KIND
|
||||||
|| kind == PyUnicode_2BYTE_KIND
|
|| kind == PyUnicode_2BYTE_KIND
|
||||||
|| kind == PyUnicode_4BYTE_KIND);
|
|| kind == PyUnicode_4BYTE_KIND);
|
||||||
assert(ascii->state.compact == 0);
|
ASSERT(ascii->state.compact == 0);
|
||||||
assert(ascii->state.ready == 1);
|
ASSERT(ascii->state.ready == 1);
|
||||||
assert(data != NULL);
|
ASSERT(data != NULL);
|
||||||
if (ascii->state.ascii) {
|
if (ascii->state.ascii) {
|
||||||
assert (compact->utf8 == data);
|
ASSERT (compact->utf8 == data);
|
||||||
assert (compact->utf8_length == ascii->length);
|
ASSERT (compact->utf8_length == ascii->length);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
assert (compact->utf8 != data);
|
ASSERT (compact->utf8 != data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (kind != PyUnicode_WCHAR_KIND) {
|
if (kind != PyUnicode_WCHAR_KIND) {
|
||||||
|
@ -427,16 +429,16 @@ _PyUnicode_CheckConsistency(PyObject *op, int check_content)
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
assert(ascii->wstr == data);
|
ASSERT(ascii->wstr == data);
|
||||||
assert(compact->wstr_length == ascii->length);
|
ASSERT(compact->wstr_length == ascii->length);
|
||||||
} else
|
} else
|
||||||
assert(ascii->wstr != data);
|
ASSERT(ascii->wstr != data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compact->utf8 == NULL)
|
if (compact->utf8 == NULL)
|
||||||
assert(compact->utf8_length == 0);
|
ASSERT(compact->utf8_length == 0);
|
||||||
if (ascii->wstr == NULL)
|
if (ascii->wstr == NULL)
|
||||||
assert(compact->wstr_length == 0);
|
ASSERT(compact->wstr_length == 0);
|
||||||
}
|
}
|
||||||
/* check that the best kind is used */
|
/* check that the best kind is used */
|
||||||
if (check_content && kind != PyUnicode_WCHAR_KIND)
|
if (check_content && kind != PyUnicode_WCHAR_KIND)
|
||||||
|
@ -455,23 +457,25 @@ _PyUnicode_CheckConsistency(PyObject *op, int check_content)
|
||||||
}
|
}
|
||||||
if (kind == PyUnicode_1BYTE_KIND) {
|
if (kind == PyUnicode_1BYTE_KIND) {
|
||||||
if (ascii->state.ascii == 0) {
|
if (ascii->state.ascii == 0) {
|
||||||
assert(maxchar >= 128);
|
ASSERT(maxchar >= 128);
|
||||||
assert(maxchar <= 255);
|
ASSERT(maxchar <= 255);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
assert(maxchar < 128);
|
ASSERT(maxchar < 128);
|
||||||
}
|
}
|
||||||
else if (kind == PyUnicode_2BYTE_KIND) {
|
else if (kind == PyUnicode_2BYTE_KIND) {
|
||||||
assert(maxchar >= 0x100);
|
ASSERT(maxchar >= 0x100);
|
||||||
assert(maxchar <= 0xFFFF);
|
ASSERT(maxchar <= 0xFFFF);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert(maxchar >= 0x10000);
|
ASSERT(maxchar >= 0x10000);
|
||||||
assert(maxchar <= MAX_UNICODE);
|
ASSERT(maxchar <= MAX_UNICODE);
|
||||||
}
|
}
|
||||||
assert(PyUnicode_READ(kind, data, ascii->length) == 0);
|
ASSERT(PyUnicode_READ(kind, data, ascii->length) == 0);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
#undef ASSERT
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue