Xref: utzoo comp.unix.ultrix:6471 comp.unix.questions:29265 comp.unix.wizards:24390 comp.sources.d:6626 comp.databases:9095 comp.os.minix:15020 comp.windows.x:33776 news.software.b:7038 comp.lang.perl:4445 comp.mail.sendmail:2819 comp.sources.bugs:2865 Path: utzoo!news-server.csri.toronto.edu!helios.physics.utoronto.ca!ists!yunexus!nexus.YorkU.CA!oz From: oz@nexus.YorkU.CA (Ozan Yigit) Newsgroups: comp.unix.ultrix,comp.unix.questions,comp.unix.wizards,comp.sources.d,comp.databases,comp.os.minix,comp.windows.x,news.software.b,comp.lang.perl,comp.mail.sendmail,comp.sources.bugs Subject: important sdbm (ndbm clone) bugfix Message-ID: <21842@yunexus.YorkU.CA> Date: 8 Mar 91 07:30:41 GMT Sender: news@yunexus.YorkU.CA Organization: York U. Communications Research & Development Lines: 50 [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