[comp.unix.ultrix] important sdbm

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