You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
If an internal node of a BTree is missing, searching through the BTree will encounter POSKeyError when it calls PER_USE(child). Unfortunately, because POSKeyError is a subclass of KeyError, the get() method will interpret this as a missing key and return the default value. The internal corruption in the BTree goes silently unreported.
if ((r=_BTree_get(self, key, 0, _BGET_REPLACE_TYPE_ERROR)))
returnr;
UNLESS (PyErr_ExceptionMatches(PyExc_KeyError))
returnNULL;
PyErr_Clear();
Py_INCREF(d);
returnd;
}
This script can reproduce it:
fromZODB.DBimportDBfromZODB.utilsimportp64asint2bfromZODB.MappingStorageimportMappingStorageimporttransactionimportBTreesfromZODB.POSExceptionimportPOSKeyErrorBIG=1BIG_UPPER_BOUND=10000000deftest_mod(bt_mod):
db=DB(MappingStorage())
bt=bt_mod.BTree()
ifBIG:
foriinrange(BIG_UPPER_BOUND):
bt[i] =iforiinrange(0, -BIG_UPPER_BOUND, -1):
bt[i] =ielse:
foriinrange(10000):
bt[i] =iconn=db.open()
conn.root.key=bttransaction.commit()
conn.cacheMinimize()
ifBIG:
bt._p_activate() # bring in the rootoss=conn.setstatedefsetstate(*args):
print("Loading", *args)
returnoss(*args)
conn.setstate=setstate# Delete some random leaves, but keep the first node we will try# to access.data=db._storage._data.copy()
db._storage._data.clear()
ifBIG:
foroid_to_keepin0x04, 0x29, 0x52, 0x05:
db._storage._data[int2b(oid_to_keep)] =data[int2b(oid_to_keep)]
print("Getting key")
try:
bt.get(BIG_UPPER_BOUND+1)
exceptPOSKeyErrorase:
print("Got expected POSKeyError", e)
else:
print("HEY NO EXCEPTION!!!")
forbt_modinBTrees.family64.OO, BTrees.family64.II:
test_mod(bt_mod)
With a big tree consisting of internal nodes, no exception is reported to Python:
$ python test.pyGetting keyLoading <BTrees.OOBTree.OOBTree object at 0x185e71370 oid 0x52 in <Connection at 104bc42d0>>Loading <BTrees.OOBTree.OOBTree object at 0x104be8870 oid 0x13b6b2 in <Connection at 104bc42d0>>Couldn't load state for BTrees.OOBTree.OOBTree 0x13b6b2Traceback (most recent call last): File "//lib/python3.8/site-packages/ZODB/Connection.py", line 791, in setstate p, serial = self._storage.load(oid) File "//lib/python3.8/site-packages/ZODB/mvccadapter.py", line 143, in load r = self._storage.loadBefore(oid, self._start) File "//python3.8/site-packages/ZODB/utils.py", line 288, in __call__ return func(*args, **kw) File "//python3.8/site-packages/ZODB/MappingStorage.py", line 168, in loadBefore raise ZODB.POSException.POSKeyError(oid)ZODB.POSException.POSKeyError: 0x13b6b2HEY NO EXCEPTION!!!Getting keyLoading <BTrees.LLBTree.LLBTree object at 0x10484c910 oid 0x5 in <Connection at 104becd70>>Loading <BTrees.LLBTree.LLBTree object at 0x15dac1cd0 oid 0x50d61 in <Connection at 104becd70>>Couldn't load state for BTrees.LLBTree.LLBTree 0x050d61Traceback (most recent call last): File "//python3.8/site-packages/ZODB/Connection.py", line 791, in setstate p, serial = self._storage.load(oid) File "//python3.8/site-packages/ZODB/mvccadapter.py", line 143, in load r = self._storage.loadBefore(oid, self._start) File "//python3.8/site-packages/ZODB/utils.py", line 288, in __call__ return func(*args, **kw) File "//python3.8/site-packages/ZODB/MappingStorage.py", line 168, in loadBefore raise ZODB.POSException.POSKeyError(oid)ZODB.POSException.POSKeyError: 0x050d61HEY NO EXCEPTION!!!
Setting BIG to 0 so that it's the root BTree itself that is missing does raise a POSKeyError.
The text was updated successfully, but these errors were encountered:
(Discovered when researching #82 and #91.)
If an internal node of a BTree is missing, searching through the BTree will encounter
POSKeyError
when it callsPER_USE(child)
. Unfortunately, becausePOSKeyError
is a subclass ofKeyError
, theget()
method will interpret this as a missing key and return the default value. The internal corruption in the BTree goes silently unreported.BTrees/src/BTrees/BTreeTemplate.c
Lines 1970 to 1983 in 9760743
This script can reproduce it:
With a big tree consisting of internal nodes, no exception is reported to Python:
Setting
BIG
to 0 so that it's the root BTree itself that is missing does raise aPOSKeyError
.The text was updated successfully, but these errors were encountered: