Skip to content

Commit 50fe3f8

Browse files
authored
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.
1 parent 0862505 commit 50fe3f8

File tree

3 files changed

+64
-52
lines changed

3 files changed

+64
-52
lines changed

Objects/dictobject.c

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,8 @@ static PyObject *empty_values[1] = { NULL };
439439
static int
440440
_PyDict_CheckConsistency(PyDictObject *mp)
441441
{
442+
#define ASSERT(expr) _PyObject_ASSERT((PyObject *)mp, (expr))
443+
442444
PyDictKeysObject *keys = mp->ma_keys;
443445
int splitted = _PyDict_HasSplitTable(mp);
444446
Py_ssize_t usable = USABLE_FRACTION(keys->dk_size);
@@ -447,23 +449,23 @@ _PyDict_CheckConsistency(PyDictObject *mp)
447449
Py_ssize_t i;
448450
#endif
449451

450-
assert(0 <= mp->ma_used && mp->ma_used <= usable);
451-
assert(IS_POWER_OF_2(keys->dk_size));
452-
assert(0 <= keys->dk_usable
452+
ASSERT(0 <= mp->ma_used && mp->ma_used <= usable);
453+
ASSERT(IS_POWER_OF_2(keys->dk_size));
454+
ASSERT(0 <= keys->dk_usable
453455
&& keys->dk_usable <= usable);
454-
assert(0 <= keys->dk_nentries
456+
ASSERT(0 <= keys->dk_nentries
455457
&& keys->dk_nentries <= usable);
456-
assert(keys->dk_usable + keys->dk_nentries <= usable);
458+
ASSERT(keys->dk_usable + keys->dk_nentries <= usable);
457459

458460
if (!splitted) {
459461
/* combined table */
460-
assert(keys->dk_refcnt == 1);
462+
ASSERT(keys->dk_refcnt == 1);
461463
}
462464

463465
#ifdef DEBUG_PYDICT
464466
for (i=0; i < keys->dk_size; i++) {
465467
Py_ssize_t ix = dk_get_index(keys, i);
466-
assert(DKIX_DUMMY <= ix && ix <= usable);
468+
ASSERT(DKIX_DUMMY <= ix && ix <= usable);
467469
}
468470

469471
for (i=0; i < usable; i++) {
@@ -473,32 +475,34 @@ _PyDict_CheckConsistency(PyDictObject *mp)
473475
if (key != NULL) {
474476
if (PyUnicode_CheckExact(key)) {
475477
Py_hash_t hash = ((PyASCIIObject *)key)->hash;
476-
assert(hash != -1);
477-
assert(entry->me_hash == hash);
478+
ASSERT(hash != -1);
479+
ASSERT(entry->me_hash == hash);
478480
}
479481
else {
480482
/* test_dict fails if PyObject_Hash() is called again */
481-
assert(entry->me_hash != -1);
483+
ASSERT(entry->me_hash != -1);
482484
}
483485
if (!splitted) {
484-
assert(entry->me_value != NULL);
486+
ASSERT(entry->me_value != NULL);
485487
}
486488
}
487489

488490
if (splitted) {
489-
assert(entry->me_value == NULL);
491+
ASSERT(entry->me_value == NULL);
490492
}
491493
}
492494

493495
if (splitted) {
494496
/* splitted table */
495497
for (i=0; i < mp->ma_used; i++) {
496-
assert(mp->ma_values[i] != NULL);
498+
ASSERT(mp->ma_values[i] != NULL);
497499
}
498500
}
499501
#endif
500502

501503
return 1;
504+
505+
#undef ASSERT
502506
}
503507
#endif
504508

Objects/typeobject.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,15 +134,19 @@ skip_signature(const char *doc)
134134
static int
135135
_PyType_CheckConsistency(PyTypeObject *type)
136136
{
137+
#define ASSERT(expr) _PyObject_ASSERT((PyObject *)type, (expr))
138+
137139
if (!(type->tp_flags & Py_TPFLAGS_READY)) {
138140
/* don't check types before PyType_Ready() */
139141
return 1;
140142
}
141143

142-
assert(!(type->tp_flags & Py_TPFLAGS_READYING));
143-
assert(type->tp_mro != NULL && PyTuple_Check(type->tp_mro));
144-
assert(type->tp_dict != NULL);
144+
ASSERT(!(type->tp_flags & Py_TPFLAGS_READYING));
145+
ASSERT(type->tp_mro != NULL && PyTuple_Check(type->tp_mro));
146+
ASSERT(type->tp_dict != NULL);
145147
return 1;
148+
149+
#undef ASSERT
146150
}
147151
#endif
148152

Objects/unicodeobject.c

Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -363,59 +363,61 @@ PyUnicode_GetMax(void)
363363
int
364364
_PyUnicode_CheckConsistency(PyObject *op, int check_content)
365365
{
366+
#define ASSERT(expr) _PyObject_ASSERT(op, (expr))
367+
366368
PyASCIIObject *ascii;
367369
unsigned int kind;
368370

369-
assert(PyUnicode_Check(op));
371+
ASSERT(PyUnicode_Check(op));
370372

371373
ascii = (PyASCIIObject *)op;
372374
kind = ascii->state.kind;
373375

374376
if (ascii->state.ascii == 1 && ascii->state.compact == 1) {
375-
assert(kind == PyUnicode_1BYTE_KIND);
376-
assert(ascii->state.ready == 1);
377+
ASSERT(kind == PyUnicode_1BYTE_KIND);
378+
ASSERT(ascii->state.ready == 1);
377379
}
378380
else {
379381
PyCompactUnicodeObject *compact = (PyCompactUnicodeObject *)op;
380382
void *data;
381383

382384
if (ascii->state.compact == 1) {
383385
data = compact + 1;
384-
assert(kind == PyUnicode_1BYTE_KIND
386+
ASSERT(kind == PyUnicode_1BYTE_KIND
385387
|| kind == PyUnicode_2BYTE_KIND
386388
|| kind == PyUnicode_4BYTE_KIND);
387-
assert(ascii->state.ascii == 0);
388-
assert(ascii->state.ready == 1);
389-
assert (compact->utf8 != data);
389+
ASSERT(ascii->state.ascii == 0);
390+
ASSERT(ascii->state.ready == 1);
391+
ASSERT (compact->utf8 != data);
390392
}
391393
else {
392394
PyUnicodeObject *unicode = (PyUnicodeObject *)op;
393395

394396
data = unicode->data.any;
395397
if (kind == PyUnicode_WCHAR_KIND) {
396-
assert(ascii->length == 0);
397-
assert(ascii->hash == -1);
398-
assert(ascii->state.compact == 0);
399-
assert(ascii->state.ascii == 0);
400-
assert(ascii->state.ready == 0);
401-
assert(ascii->state.interned == SSTATE_NOT_INTERNED);
402-
assert(ascii->wstr != NULL);
403-
assert(data == NULL);
404-
assert(compact->utf8 == NULL);
398+
ASSERT(ascii->length == 0);
399+
ASSERT(ascii->hash == -1);
400+
ASSERT(ascii->state.compact == 0);
401+
ASSERT(ascii->state.ascii == 0);
402+
ASSERT(ascii->state.ready == 0);
403+
ASSERT(ascii->state.interned == SSTATE_NOT_INTERNED);
404+
ASSERT(ascii->wstr != NULL);
405+
ASSERT(data == NULL);
406+
ASSERT(compact->utf8 == NULL);
405407
}
406408
else {
407-
assert(kind == PyUnicode_1BYTE_KIND
409+
ASSERT(kind == PyUnicode_1BYTE_KIND
408410
|| kind == PyUnicode_2BYTE_KIND
409411
|| kind == PyUnicode_4BYTE_KIND);
410-
assert(ascii->state.compact == 0);
411-
assert(ascii->state.ready == 1);
412-
assert(data != NULL);
412+
ASSERT(ascii->state.compact == 0);
413+
ASSERT(ascii->state.ready == 1);
414+
ASSERT(data != NULL);
413415
if (ascii->state.ascii) {
414-
assert (compact->utf8 == data);
415-
assert (compact->utf8_length == ascii->length);
416+
ASSERT (compact->utf8 == data);
417+
ASSERT (compact->utf8_length == ascii->length);
416418
}
417419
else
418-
assert (compact->utf8 != data);
420+
ASSERT (compact->utf8 != data);
419421
}
420422
}
421423
if (kind != PyUnicode_WCHAR_KIND) {
@@ -427,16 +429,16 @@ _PyUnicode_CheckConsistency(PyObject *op, int check_content)
427429
#endif
428430
)
429431
{
430-
assert(ascii->wstr == data);
431-
assert(compact->wstr_length == ascii->length);
432+
ASSERT(ascii->wstr == data);
433+
ASSERT(compact->wstr_length == ascii->length);
432434
} else
433-
assert(ascii->wstr != data);
435+
ASSERT(ascii->wstr != data);
434436
}
435437

436438
if (compact->utf8 == NULL)
437-
assert(compact->utf8_length == 0);
439+
ASSERT(compact->utf8_length == 0);
438440
if (ascii->wstr == NULL)
439-
assert(compact->wstr_length == 0);
441+
ASSERT(compact->wstr_length == 0);
440442
}
441443
/* check that the best kind is used */
442444
if (check_content && kind != PyUnicode_WCHAR_KIND)
@@ -455,23 +457,25 @@ _PyUnicode_CheckConsistency(PyObject *op, int check_content)
455457
}
456458
if (kind == PyUnicode_1BYTE_KIND) {
457459
if (ascii->state.ascii == 0) {
458-
assert(maxchar >= 128);
459-
assert(maxchar <= 255);
460+
ASSERT(maxchar >= 128);
461+
ASSERT(maxchar <= 255);
460462
}
461463
else
462-
assert(maxchar < 128);
464+
ASSERT(maxchar < 128);
463465
}
464466
else if (kind == PyUnicode_2BYTE_KIND) {
465-
assert(maxchar >= 0x100);
466-
assert(maxchar <= 0xFFFF);
467+
ASSERT(maxchar >= 0x100);
468+
ASSERT(maxchar <= 0xFFFF);
467469
}
468470
else {
469-
assert(maxchar >= 0x10000);
470-
assert(maxchar <= MAX_UNICODE);
471+
ASSERT(maxchar >= 0x10000);
472+
ASSERT(maxchar <= MAX_UNICODE);
471473
}
472-
assert(PyUnicode_READ(kind, data, ascii->length) == 0);
474+
ASSERT(PyUnicode_READ(kind, data, ascii->length) == 0);
473475
}
474476
return 1;
477+
478+
#undef ASSERT
475479
}
476480
#endif
477481

0 commit comments

Comments
 (0)