[comp.archives] [ultrix...] important sdbm

oz@nexus.YorkU.CA (Ozan Yigit) (03/09/91)

Archive-name: database/dbm/sdbm/1991-03-08
Archive: nexus.yorku.ca:/pub/oz/sdbm.shar.Z [130.63.9.1]
Original-posting-by: oz@nexus.YorkU.CA (Ozan Yigit)
Original-subject: important sdbm (ndbm clone) bugfix
Reposted-by: emv@ox.com (Edward Vielmetti)

[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
---
[patch included cause it's short.  --Ed.]

*** 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