oz@nexus.YorkU.CA (Ozan Yigit) (03/08/91)
[sorry to have to crosspost this wide] The recent public distribution of sdbm, an ndbm clone came with a subtle bug [parens, damn parens] that seems to have gone unnoticed for a very long time. I am thankful to Ronald S. H. Khoo (ronald@robobar.co.uk) for discovering this bug. The bug will make some data inaccessible altogether. In one case, 135 entries out of a thousand could not be located in the database. The reason for the bug to remain unnoticed is probably due to the way sdbm [or ndbm] is often utilized: short keys with short-to-medium variable-length data. This use along with sdbm's good page splitting behaviour means the buggy portion of the code that handles multiple split attempts gets used rarely. A patch for this nasty bug is included. FTP: ~ftp/pub/oz/sdbm.shar.Z on nexus.yorku.ca [130.63.9.1] is updated. My sincere apologies for any inconvenience this bug may have caused. oz --- *** sdbm-dist/sdbm.c Thu Dec 13 13:52:45 1990 --- sdbm-work/sdbm.c Fri Mar 8 01:29:40 1991 *************** *** 337,345 **** * need to read in anything. BUT we have to write the current * [deferred] page out, as the window of failure is too great. */ ! db->curbit = 2 * db->curbit + ! (hash & (db->hmask + 1)) ? 2 : 1; ! db->hmask |= (db->hmask + 1); if (lseek(db->pagf, OFF_PAG(db->pagbno), SEEK_SET) < 0 || write(db->pagf, db->pagbuf, PBLKSIZ) < 0) --- 337,345 ---- * need to read in anything. BUT we have to write the current * [deferred] page out, as the window of failure is too great. */ ! db->curbit = 2 * db->curbit + ! ((hash & (db->hmask + 1)) ? 2 : 1); ! db->hmask |= db->hmask + 1; if (lseek(db->pagf, OFF_PAG(db->pagbno), SEEK_SET) < 0 || write(db->pagf, db->pagbuf, PBLKSIZ) < 0) --- In seeking the unattainable, simplicity | Internet: oz@nexus.yorku.ca only gets in the way. -- Alan J. Perlis | Uucp: utai/utzoo!yunexus!oz