Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Coverity Scan defects in new dict code #72229

Closed
tiran opened this issue Sep 9, 2016 · 9 comments
Closed

Coverity Scan defects in new dict code #72229

tiran opened this issue Sep 9, 2016 · 9 comments
Labels
3.7 (EOL) end of life build The build process and cross-build

Comments

@tiran
Copy link
Member

tiran commented Sep 9, 2016

BPO 28042
Nosy @vstinner, @tiran, @methane, @zhangyangyu

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = <Date 2016-09-21.13:14:49.651>
created_at = <Date 2016-09-09.11:11:10.627>
labels = ['invalid', 'build', '3.7']
title = 'Coverity Scan defects in new dict code'
updated_at = <Date 2016-09-21.13:14:49.650>
user = 'https://github.com/tiran'

bugs.python.org fields:

activity = <Date 2016-09-21.13:14:49.650>
actor = 'christian.heimes'
assignee = 'none'
closed = True
closed_date = <Date 2016-09-21.13:14:49.651>
closer = 'christian.heimes'
components = []
creation = <Date 2016-09-09.11:11:10.627>
creator = 'christian.heimes'
dependencies = []
files = []
hgrepos = []
issue_num = 28042
keywords = []
message_count = 9.0
messages = ['275307', '275548', '275578', '275579', '277127', '277134', '277135', '277137', '277138']
nosy_count = 4.0
nosy_names = ['vstinner', 'christian.heimes', 'methane', 'xiang.zhang']
pr_nums = []
priority = 'high'
resolution = 'not a bug'
stage = 'resolved'
status = 'closed'
superseder = None
type = 'compile error'
url = 'https://bugs.python.org/issue28042'
versions = ['Python 3.6', 'Python 3.7']

@tiran
Copy link
Member Author

tiran commented Sep 9, 2016

Coverity Scan complains about 30 defects in the new code. Inada, I sent you an invite.

30 new defect(s) introduced to Python found with Coverity Scan.
3 defect(s), reported by Coverity Scan earlier, were marked fixed in the recent build analyzed by Coverity Scan.

New defect(s) Reported-by: Coverity Scan
Showing 20 of 30 defect(s)

** CID 1372734: Memory - corruptions (OVERRUN)
/Objects/dictobject.c: 1133 in insertdict_clean()

________________________________________________________________________________________________________
*** CID 1372734:  Memory - corruptions  (OVERRUN)
/Objects/dictobject.c: 1133 in insertdict_clean()
1127     insertdict_clean(PyDictObject *mp, PyObject *key, Py_hash_t hash,
1128                      PyObject *value)
1129     {
1130         size_t i, perturb;
1131         PyDictKeysObject *k = mp->ma_keys;
1132         size_t mask = (size_t)DK_SIZE(k)-1;
>>>     CID 1372734:  Memory - corruptions  (OVERRUN)
>>>     "&mp->ma_keys->dk_indices.as_1[mp->ma_keys->dk_size * ((mp->ma_keys->dk_size <= 255L) ? 1UL : ((mp->ma_keys->dk_size <= 65535L) ? 2UL : ((mp->ma_keys->dk_size <= 4294967295L) ? 4UL : 8UL)))]" evaluates to an address that is at byte offset 255 of an array of 8 bytes.
1133         PyDictKeyEntry *ep0 = DK_ENTRIES(mp->ma_keys);
1134         PyDictKeyEntry *ep;
1135     
1136         assert(k->dk_lookup != NULL);
1137         assert(value != NULL);
1138         assert(key != NULL);

** CID 1372733: Memory - corruptions (OVERRUN)
/Objects/dictobject.c: 1557 in _PyDict_DelItem_KnownHash()

________________________________________________________________________________________________________
*** CID 1372733:  Memory - corruptions  (OVERRUN)
/Objects/dictobject.c: 1557 in _PyDict_DelItem_KnownHash()
1551         mp->ma_used--;
1552         mp->ma_version_tag = DICT_NEXT_VERSION();
1553         if (_PyDict_HasSplitTable(mp)) {
1554             mp->ma_keys->dk_usable = 0;
1555         }
1556         else {
>>>     CID 1372733:  Memory - corruptions  (OVERRUN)
>>>     "&mp->ma_keys->dk_indices.as_1[mp->ma_keys->dk_size * ((mp->ma_keys->dk_size <= 255L) ? 1UL : ((mp->ma_keys->dk_size <= 65535L) ? 2UL : ((mp->ma_keys->dk_size <= 4294967295L) ? 4UL : 8UL)))]" evaluates to an address that is at byte offset 255 of an array of 8 bytes.
1557             ep = &DK_ENTRIES(mp->ma_keys)[ix];
1558             dk_set_index(mp->ma_keys, hashpos, DKIX_DUMMY);
1559             ENSURE_ALLOWS_DELETIONS(mp);
1560             old_key = ep->me_key;
1561             ep->me_key = NULL;
1562             Py_DECREF(old_key);

** CID 1372732: Memory - corruptions (OVERRUN)
/Objects/dictobject.c: 871 in lookdict_split()

________________________________________________________________________________________________________
*** CID 1372732:  Memory - corruptions  (OVERRUN)
/Objects/dictobject.c: 871 in lookdict_split()
865     lookdict_split(PyDictObject *mp, PyObject *key,
866                    Py_hash_t hash, PyObject ***value_addr, Py_ssize_t *hashpos)
867     {
868         size_t i, perturb;
869         size_t mask = DK_MASK(mp->ma_keys);
870         Py_ssize_t ix;
>>>     CID 1372732:  Memory - corruptions  (OVERRUN)
>>>     "&mp->ma_keys->dk_indices.as_1[mp->ma_keys->dk_size * ((mp->ma_keys->dk_size <= 255L) ? 1UL : ((mp->ma_keys->dk_size <= 65535L) ? 2UL : ((mp->ma_keys->dk_size <= 4294967295L) ? 4UL : 8UL)))]" evaluates to an address that is at byte offset 255 of an array of 8 bytes.
871         PyDictKeyEntry *ep, *ep0 = DK_ENTRIES(mp->ma_keys);
872     
873         /* mp must split table */
874         assert(mp->ma_values != NULL);
875         if (!PyUnicode_CheckExact(key)) {
876             ix = lookdict(mp, key, hash, value_addr, hashpos);

** CID 1372731: Memory - corruptions (OVERRUN)
/Objects/dictobject.c: 3433 in dictiter_iternextitem()

________________________________________________________________________________________________________
*** CID 1372731:  Memory - corruptions  (OVERRUN)
/Objects/dictobject.c: 3433 in dictiter_iternextitem()
3427         } else {
3428             result = PyTuple_New(2);
3429             if (result == NULL)
3430                 return NULL;
3431         }
3432         di->len--;
>>>     CID 1372731:  Memory - corruptions  (OVERRUN)
>>>     "&d->ma_keys->dk_indices.as_1[d->ma_keys->dk_size * ((d->ma_keys->dk_size <= 255L) ? 1UL : ((d->ma_keys->dk_size <= 65535L) ? 2UL : ((d->ma_keys->dk_size <= 4294967295L) ? 4UL : 8UL)))]" evaluates to an address that is at byte offset 255 of an array of 8 bytes.
3433         key = DK_ENTRIES(d->ma_keys)[i].me_key;
3434         value = *value_ptr;
3435         Py_INCREF(key);
3436         Py_INCREF(value);
3437         PyTuple_SET_ITEM(result, 0, key);  /* steals reference */
3438         PyTuple_SET_ITEM(result, 1, value);  /* steals reference */

** CID 1372730: Memory - illegal accesses (OVERRUN)
/Objects/dictobject.c: 2333 in PyDict_Merge()

________________________________________________________________________________________________________
*** CID 1372730:  Memory - illegal accesses  (OVERRUN)
/Objects/dictobject.c: 2333 in PyDict_Merge()
2327                    return -1;
2328             ep0 = DK_ENTRIES(other->ma_keys);
2329             for (i = 0, n = other->ma_keys->dk_nentries; i < n; i++) {
2330                 PyObject *key, *value;
2331                 Py_hash_t hash;
2332                 entry = &ep0[i];
>>>     CID 1372730:  Memory - illegal accesses  (OVERRUN)
>>>     Overrunning array of 8 bytes at byte offset 255 by dereferencing pointer "entry".
2333                 key = entry->me_key;
2334                 hash = entry->me_hash;
2335                 if (other->ma_values)
2336                     value = other->ma_values[i];
2337                 else
2338                     value = entry->me_value;

** CID 1372729: Memory - corruptions (OVERRUN)
/Objects/dictobject.c: 2756 in dict_popitem()

________________________________________________________________________________________________________
*** CID 1372729:  Memory - corruptions  (OVERRUN)
/Objects/dictobject.c: 2756 in dict_popitem()
2750                 return NULL;
2751             }
2752         }
2753         ENSURE_ALLOWS_DELETIONS(mp);
2754     
2755         /* Pop last item */
>>>     CID 1372729:  Memory - corruptions  (OVERRUN)
>>>     "&mp->ma_keys->dk_indices.as_1[mp->ma_keys->dk_size * ((mp->ma_keys->dk_size <= 255L) ? 1UL : ((mp->ma_keys->dk_size <= 65535L) ? 2UL : ((mp->ma_keys->dk_size <= 4294967295L) ? 4UL : 8UL)))]" evaluates to an address that is at byte offset 255 of an array of 8 bytes.
2756         ep0 = DK_ENTRIES(mp->ma_keys);
2757         i = mp->ma_keys->dk_nentries - 1;
2758         while (i >= 0 && ep0[i].me_value == NULL) {
2759             i--;
2760         }
2761         assert(i >= 0);

** CID 1372728: Memory - corruptions (OVERRUN)
/Objects/dictobject.c: 1734 in _PyDict_Pop()

________________________________________________________________________________________________________
*** CID 1372728:  Memory - corruptions  (OVERRUN)
/Objects/dictobject.c: 1734 in _PyDict_Pop()
1728         old_value = *value_addr;
1729         *value_addr = NULL;
1730         mp->ma_used--;
1731         mp->ma_version_tag = DICT_NEXT_VERSION();
1732         if (!_PyDict_HasSplitTable(mp)) {
1733             dk_set_index(mp->ma_keys, hashpos, DKIX_DUMMY);
>>>     CID 1372728:  Memory - corruptions  (OVERRUN)
>>>     "&mp->ma_keys->dk_indices.as_1[mp->ma_keys->dk_size * ((mp->ma_keys->dk_size <= 255L) ? 1UL : ((mp->ma_keys->dk_size <= 65535L) ? 2UL : ((mp->ma_keys->dk_size <= 4294967295L) ? 4UL : 8UL)))]" evaluates to an address that is at byte offset 255 of an array of 8 bytes.
1734             ep = &DK_ENTRIES(mp->ma_keys)[ix];
1735             ENSURE_ALLOWS_DELETIONS(mp);
1736             old_key = ep->me_key;
1737             ep->me_key = NULL;
1738             Py_DECREF(old_key);
1739         }

** CID 1372727: Memory - illegal accesses (OVERRUN)
/Objects/dictobject.c: 1200 in dictresize()

________________________________________________________________________________________________________
*** CID 1372727:  Memory - illegal accesses  (OVERRUN)
/Objects/dictobject.c: 1200 in dictresize()
1194          * and that value is stored in me_value.
1195          * Increment ref-counts and copy values here to compensate
1196          * This (resizing a split table) should be relatively rare */
1197         if (oldvalues != NULL) {
1198             for (i = 0; i < oldkeys->dk_nentries; i++) {
1199                 if (oldvalues[i] != NULL) {
>>>     CID 1372727:  Memory - illegal accesses  (OVERRUN)
>>>     Overrunning array of 8 bytes at byte offset 255 by dereferencing pointer "ep0 + i".
1200                     Py_INCREF(ep0[i].me_key);
1201                     ep0[i].me_value = oldvalues[i];
1202                 }
1203             }
1204         }
1205         /* Main loop */

** CID 1372726: Memory - corruptions (OVERRUN)
/Objects/dictobject.c: 479 in new_keys_object()

________________________________________________________________________________________________________
*** CID 1372726:  Memory - corruptions  (OVERRUN)
/Objects/dictobject.c: 479 in new_keys_object()
473         DK_DEBUG_INCREF dk->dk_refcnt = 1;
474         dk->dk_size = size;
475         dk->dk_usable = usable;
476         dk->dk_lookup = lookdict_unicode_nodummy;
477         dk->dk_nentries = 0;
478         memset(&dk->dk_indices.as_1[0], 0xff, es * size);
>>>     CID 1372726:  Memory - corruptions  (OVERRUN)
>>>     Overrunning buffer pointed to by "(PyDictKeyEntry *)&dk->dk_indices.as_1[dk->dk_size * ((dk->dk_size <= 255L) ? 1UL : ((dk->dk_size <= 65535L) ? 2UL : ((dk->dk_size <= 4294967295L) ? 4UL : 8UL)))]" of 8 bytes by passing it to a function which accesses it at byte offset 8. [Note: The source code implementation of the function has been overridden by a builtin model.]
479         memset(DK_ENTRIES(dk), 0, sizeof(PyDictKeyEntry) * usable);
480         return dk;
481     }
482     
483     static void
484     free_keys_object(PyDictKeysObject *keys)

** CID 1372725: Memory - illegal accesses (OVERRUN)
/Objects/dictobject.c: 2039 in dict_keys()

________________________________________________________________________________________________________
*** CID 1372725:  Memory - illegal accesses  (OVERRUN)
/Objects/dictobject.c: 2039 in dict_keys()
2033         else {
2034             value_ptr = &ep[0].me_value;
2035             offset = sizeof(PyDictKeyEntry);
2036         }
2037         for (i = 0, j = 0; i < size; i++) {
2038             if (*value_ptr != NULL) {
>>>     CID 1372725:  Memory - illegal accesses  (OVERRUN)
>>>     Overrunning array of 8 bytes at byte offset 255 by dereferencing pointer "ep + i".
2039                 PyObject *key = ep[i].me_key;
2040                 Py_INCREF(key);
2041                 PyList_SET_ITEM(v, j, key);
2042                 j++;
2043             }
2044             value_ptr = (PyObject **)(((char *)value_ptr) + offset);

** CID 1372724: Memory - corruptions (OVERRUN)
/Objects/dictobject.c: 1684 in _PyDict_Next()

________________________________________________________________________________________________________
*** CID 1372724:  Memory - corruptions  (OVERRUN)
/Objects/dictobject.c: 1684 in _PyDict_Next()
1678         PyDictObject *mp;
1679         PyDictKeyEntry *ep0;
1680         Py_ssize_t i = dict_next(op, *ppos, pvalue);
1681         if (i < 0)
1682             return 0;
1683         mp = (PyDictObject *)op;
>>>     CID 1372724:  Memory - corruptions  (OVERRUN)
>>>     "&mp->ma_keys->dk_indices.as_1[mp->ma_keys->dk_size * ((mp->ma_keys->dk_size <= 255L) ? 1UL : ((mp->ma_keys->dk_size <= 65535L) ? 2UL : ((mp->ma_keys->dk_size <= 4294967295L) ? 4UL : 8UL)))]" evaluates to an address that is at byte offset 255 of an array of 8 bytes.
1684         ep0 = DK_ENTRIES(mp->ma_keys);
1685         *ppos = i+1;
1686         *phash = ep0[i].me_hash;
1687         if (pkey)
1688             *pkey = ep0[i].me_key;
1689         return 1;

** CID 1372723: Memory - illegal accesses (OVERRUN)
/Objects/dictobject.c: 2790 in dict_traverse()

________________________________________________________________________________________________________
*** CID 1372723:  Memory - illegal accesses  (OVERRUN)
/Objects/dictobject.c: 2790 in dict_traverse()
2784         PyDictKeysObject *keys = mp->ma_keys;
2785         PyDictKeyEntry *entries = DK_ENTRIES(mp->ma_keys);
2786         Py_ssize_t i, n = keys->dk_nentries;
2787     
2788         if (keys->dk_lookup == lookdict) {
2789             for (i = 0; i < n; i++) {
>>>     CID 1372723:  Memory - illegal accesses  (OVERRUN)
>>>     Overrunning array of 8 bytes at byte offset 255 by dereferencing pointer "entries + i".
2790                 if (entries[i].me_value != NULL) {
2791                     Py_VISIT(entries[i].me_value);
2792                     Py_VISIT(entries[i].me_key);
2793                 }
2794             }
2795         }

** CID 1372722: Memory - corruptions (OVERRUN)
/Objects/dictobject.c: 3261 in dictiter_iternextkey()

________________________________________________________________________________________________________
*** CID 1372722:  Memory - corruptions  (OVERRUN)
/Objects/dictobject.c: 3261 in dictiter_iternextkey()
3255             i++;
3256         }
3257         di->di_pos = i+1;
3258         if (i > n)
3259             goto fail;
3260         di->len--;
>>>     CID 1372722:  Memory - corruptions  (OVERRUN)
>>>     "&k->dk_indices.as_1[k->dk_size * ((k->dk_size <= 255L) ? 1UL : ((k->dk_size <= 65535L) ? 2UL : ((k->dk_size <= 4294967295L) ? 4UL : 8UL)))]" evaluates to an address that is at byte offset 255 of an array of 8 bytes.
3261         key = DK_ENTRIES(k)[i].me_key;
3262         Py_INCREF(key);
3263         return key;
3264     
3265     fail:
3266         di->di_dict = NULL;

** CID 1372721: Memory - corruptions (OVERRUN)
/Objects/dictobject.c: 626 in lookdict()

________________________________________________________________________________________________________
*** CID 1372721:  Memory - corruptions  (OVERRUN)
/Objects/dictobject.c: 626 in lookdict()
620         PyDictKeyEntry *ep0, *ep;
621         PyObject *startkey;
622     
623     top:
624         dk = mp->ma_keys;
625         mask = DK_MASK(dk);
>>>     CID 1372721:  Memory - corruptions  (OVERRUN)
>>>     "&dk->dk_indices.as_1[dk->dk_size * ((dk->dk_size <= 255L) ? 1UL : ((dk->dk_size <= 65535L) ? 2UL : ((dk->dk_size <= 4294967295L) ? 4UL : 8UL)))]" evaluates to an address that is at byte offset 255 of an array of 8 bytes.
626         ep0 = DK_ENTRIES(dk);
627         i = (size_t)hash & mask;
628     
629         ix = dk_get_index(dk, i);
630         if (ix == DKIX_EMPTY) {
631             if (hashpos != NULL)

** CID 1372720: Memory - corruptions (OVERRUN)
/Objects/dictobject.c: 996 in find_empty_slot()

________________________________________________________________________________________________________
*** CID 1372720:  Memory - corruptions  (OVERRUN)
/Objects/dictobject.c: 996 in find_empty_slot()
990     find_empty_slot(PyDictObject *mp, PyObject *key, Py_hash_t hash,
991                     PyObject ***value_addr, Py_ssize_t *hashpos)
992     {
993         size_t i, perturb;
994         size_t mask = DK_MASK(mp->ma_keys);
995         Py_ssize_t ix;
>>>     CID 1372720:  Memory - corruptions  (OVERRUN)
>>>     "&mp->ma_keys->dk_indices.as_1[mp->ma_keys->dk_size * ((mp->ma_keys->dk_size <= 255L) ? 1UL : ((mp->ma_keys->dk_size <= 65535L) ? 2UL : ((mp->ma_keys->dk_size <= 4294967295L) ? 4UL : 8UL)))]" evaluates to an address that is at byte offset 255 of an array of 8 bytes.
996         PyDictKeyEntry *ep, *ep0 = DK_ENTRIES(mp->ma_keys);
997     
998         assert(hashpos != NULL);
999         assert(key != NULL);
1000         if (!PyUnicode_CheckExact(key))
1001             mp->ma_keys->dk_lookup = lookdict;

** CID 1372719: Memory - illegal accesses (OVERRUN)
/Objects/dictobject.c: 2522 in dict_equal()

________________________________________________________________________________________________________
*** CID 1372719:  Memory - illegal accesses  (OVERRUN)
/Objects/dictobject.c: 2522 in dict_equal()
2516             else
2517                 aval = ep->me_value;
2518             if (aval != NULL) {
2519                 int cmp;
2520                 PyObject *bval;
2521                 PyObject **vaddr;
>>>     CID 1372719:  Memory - illegal accesses  (OVERRUN)
>>>     Overrunning array of 8 bytes at byte offset 255 by dereferencing pointer "ep".
2522                 PyObject *key = ep->me_key;
2523                 /* temporarily bump aval's refcount to ensure it stays
2524                    alive until we're done with it */
2525                 Py_INCREF(aval);
2526                 /* ditto for key */
2527                 Py_INCREF(key);

** CID 1372718: Memory - corruptions (OVERRUN)
/Objects/dictobject.c: 1667 in PyDict_Next()

________________________________________________________________________________________________________
*** CID 1372718:  Memory - corruptions  (OVERRUN)
/Objects/dictobject.c: 1667 in PyDict_Next()
1661         Py_ssize_t i = dict_next(op, *ppos, pvalue);
1662         if (i < 0)
1663             return 0;
1664         mp = (PyDictObject *)op;
1665         *ppos = i+1;
1666         if (pkey)
>>>     CID 1372718:  Memory - corruptions  (OVERRUN)
>>>     "&mp->ma_keys->dk_indices.as_1[mp->ma_keys->dk_size * ((mp->ma_keys->dk_size <= 255L) ? 1UL : ((mp->ma_keys->dk_size <= 65535L) ? 2UL : ((mp->ma_keys->dk_size <= 4294967295L) ? 4UL : 8UL)))]" evaluates to an address that is at byte offset 255 of an array of 8 bytes.
1667             *pkey = DK_ENTRIES(mp->ma_keys)[i].me_key;
1668         return 1;
1669     }
1670     
1671     /* Internal version of PyDict_Next that returns a hash value in addition
1672      * to the key and value.

** CID 1372717: Memory - corruptions (OVERRUN)
/Objects/dictobject.c: 729 in lookdict_unicode()

________________________________________________________________________________________________________
*** CID 1372717:  Memory - corruptions  (OVERRUN)
/Objects/dictobject.c: 729 in lookdict_unicode()
723     lookdict_unicode(PyDictObject *mp, PyObject *key,
724                      Py_hash_t hash, PyObject ***value_addr, Py_ssize_t *hashpos)
725     {
726         size_t i, perturb;
727         size_t mask = DK_MASK(mp->ma_keys);
728         Py_ssize_t ix, freeslot;
>>>     CID 1372717:  Memory - corruptions  (OVERRUN)
>>>     "&mp->ma_keys->dk_indices.as_1[mp->ma_keys->dk_size * ((mp->ma_keys->dk_size <= 255L) ? 1UL : ((mp->ma_keys->dk_size <= 65535L) ? 2UL : ((mp->ma_keys->dk_size <= 4294967295L) ? 4UL : 8UL)))]" evaluates to an address that is at byte offset 255 of an array of 8 bytes.
729         PyDictKeyEntry *ep, *ep0 = DK_ENTRIES(mp->ma_keys);
730     
731         assert(mp->ma_values == NULL);
732         /* Make sure this function doesn't have to handle non-unicode keys,
733            including subclasses of str; e.g., one reason to subclass
734            unicodes is to override __eq__, and for speed we don't cater to

** CID 1372716: Memory - corruptions (OVERRUN)
/Objects/dictobject.c: 1255 in make_keys_shared()

________________________________________________________________________________________________________
*** CID 1372716:  Memory - corruptions  (OVERRUN)
/Objects/dictobject.c: 1255 in make_keys_shared()
1249                 /* Remove dummy keys */
1250                 if (dictresize(mp, DK_SIZE(mp->ma_keys)))
1251                     return NULL;
1252             }
1253             assert(mp->ma_keys->dk_lookup == lookdict_unicode_nodummy);
1254             /* Copy values into a new array */
>>>     CID 1372716:  Memory - corruptions  (OVERRUN)
>>>     "&mp->ma_keys->dk_indices.as_1[mp->ma_keys->dk_size * ((mp->ma_keys->dk_size <= 255L) ? 1UL : ((mp->ma_keys->dk_size <= 65535L) ? 2UL : ((mp->ma_keys->dk_size <= 4294967295L) ? 4UL : 8UL)))]" evaluates to an address that is at byte offset 255 of an array of 8 bytes.
1255             ep0 = DK_ENTRIES(mp->ma_keys);
1256             size = USABLE_FRACTION(DK_SIZE(mp->ma_keys));
1257             values = new_values(size);
1258             if (values == NULL) {
1259                 PyErr_SetString(PyExc_MemoryError,
1260                     "Not enough memory to allocate new values array");

** CID 1372715: Memory - corruptions (OVERRUN)
/Objects/dictobject.c: 962 in _PyDict_MaybeUntrack()

________________________________________________________________________________________________________
*** CID 1372715:  Memory - corruptions  (OVERRUN)
/Objects/dictobject.c: 962 in _PyDict_MaybeUntrack()
956         PyDictKeyEntry *ep0;
957     
958         if (!PyDict_CheckExact(op) || !_PyObject_GC_IS_TRACKED(op))
959             return;
960     
961         mp = (PyDictObject *) op;
>>>     CID 1372715:  Memory - corruptions  (OVERRUN)
>>>     "&mp->ma_keys->dk_indices.as_1[mp->ma_keys->dk_size * ((mp->ma_keys->dk_size <= 255L) ? 1UL : ((mp->ma_keys->dk_size <= 65535L) ? 2UL : ((mp->ma_keys->dk_size <= 4294967295L) ? 4UL : 8UL)))]" evaluates to an address that is at byte offset 255 of an array of 8 bytes.
962         ep0 = DK_ENTRIES(mp->ma_keys);
963         numentries = mp->ma_keys->dk_nentries;
964         if (_PyDict_HasSplitTable(mp)) {
965             for (i = 0; i < numentries; i++) {
966                 if ((value = mp->ma_values[i]) == NULL)
967                     continue;

@tiran tiran added the build The build process and cross-build label Sep 9, 2016
@methane
Copy link
Member

methane commented Sep 10, 2016

Inada, I sent you an invite.

Does the invite sent me by email?
I'm sorry, but I may lost the mail.

@tiran
Copy link
Member Author

tiran commented Sep 10, 2016

No problem, you can apply for membership at https://scan.coverity.com/projects/python . I'll approve you later today.

@vstinner
Copy link
Member

>> "&mp->ma_keys->dk_indices.as_1[mp->ma_keys->dk_size * ((mp->ma_keys->dk_size <= 255L) ? 1UL : ((mp->ma_keys->dk_size <= 65535L) ? 2UL : ((mp->ma_keys->dk_size <= 4294967295L) ? 4UL : 8UL)))]" evaluates to an address that is at byte offset 255 of an array of 8 bytes.

Oh. That's why dictobject.c uses a trick. The C structure uses a fixed buffer of 8 bytes, but the actual allocated memory block has the right size. All these warnings are false positive, don't worry :-)

We might use C99 "buffer[]" syntax, remove dk_indices from the structure, ignore the false alarm, or write a Coverity model for this one. Right now, I would prefer to not touch the C code just for a false alarm ;-)

@tiran
Copy link
Member Author

tiran commented Sep 21, 2016

The warnings are false positives. Coverity does not understand the relationship between dict size and union members. I have closed all issues related to DK_ENTRIES().

There is still one issue left that seems worth looking into:

  1. negative_return_fn: Function lookdict_index(mp->ma_keys, ep->me_hash, i) returns a negative number. [show details]
    16. var_assign: Assigning: signed variable j = lookdict_index.
    2862 j = lookdict_index(mp->ma_keys, ep->me_hash, i);
    2863 assert(j >= 0);
    2864 assert(dk_get_index(mp->ma_keys, j) == i);
    CID 1372706 (Support "bpo-" in Misc/NEWS #1 of 1): Improper use of negative value (NEGATIVE_RETURNS)17. negative_returns: Passing variable j to a parameter that cannot be negative. [show details]
    2865 dk_set_index(mp->ma_keys, j, DKIX_DUMMY);

@tiran tiran added the 3.7 (EOL) end of life label Sep 21, 2016
@methane
Copy link
Member

methane commented Sep 21, 2016

Thanks. It seems coverity doesn't understand assert(j >= 0);
Can I tell it to coverity from source code?

@tiran
Copy link
Member Author

tiran commented Sep 21, 2016

Coverity ignores asserts() because they are not in the final code. If you are sure that 'j' can never be < 0, then I can simply ignore the issue.

@methane
Copy link
Member

methane commented Sep 21, 2016

OK, I ignored it on Coverity site.

@tiran
Copy link
Member Author

tiran commented Sep 21, 2016

Perfect :)

@tiran tiran closed this as completed Sep 21, 2016
@tiran tiran added the invalid label Sep 21, 2016
@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.7 (EOL) end of life build The build process and cross-build
Projects
None yet
Development

No branches or pull requests

3 participants