Apache httpd's htdbm support program SDBM delete on 64bit fails with 'Cannot find user'. (create,add,list still work)
 
This is an endian issue as well since htdbm -x works on a 64bit AMD machine, but not sparc or z/OS.
 
dsize.apr_sdbm_datum_t in apr_sdbm.h has int dcl, but should be using apr_size_t to insure the field is not being truncated
in the apr_dbm_exists->vt_sdbm_exists->apr_sdbm_fetch flow.
Below is a test on a sparc 64bit build:
 
$ bin/htdbm -c testorig name01
Enter password        :
Re-type password      :
Database testorig created.
$ bin/htdbm  testorig name02
Enter password        :
Re-type password      :
Database testorig updated.
$ bin/htdbm -l testorig
Dumping records from database -- testorig
    Username                        Comment
    name01
    name02
Total #records : 2
$ bin/htdbm -x testorig name01
Cannot find user 'name01' in database
 
 
 
Patch:

Index: apr-util/include/apr_sdbm.h
===================================================================
--- apr-util/include/apr_sdbm.h (revision 407593)
+++ apr-util/include/apr_sdbm.h (working copy)
@@ -50,7 +50,7 @@
     /** pointer to the data stored/retrieved */
     char *dptr;
     /** size of data */
-    int dsize;
+    apr_size_t dsize;
 } apr_sdbm_datum_t;

 /* The extensions used for the database files */

 

 

 
Update to test routine  testdbm.c to check if apr_dbm_exists and apr_dbm_delete work:


Index: apr-util/test/testdbm.c
===================================================================
--- apr-util/test/testdbm.c     (revision 407593)
+++ apr-util/test/testdbm.c     (working copy)
@@ -190,7 +190,7 @@
     line = (char *) apr_palloc(pool,LINEMAX);

     switch (act->scode) {
-
+
     case DLOOK:
         while (fgets(line, LINEMAX, stdin) != NULL) {
             n = strlen(line) - 1;
@@ -288,7 +288,9 @@
     case DAUTO:
         {
             int i;
+            int exists = 0;
             char *valdata = "0123456789";
+           char keydeldata[] = "KEYTODELETE";
             fprintf(stderr, "Generating data: ");
             for (i = 0; i < 10; i++) {
                 int j;
@@ -330,6 +332,31 @@
                 }
             }
             fputs("OK\n", stderr);
+            fputs("Testing store for deletion: ", stderr);
+            key.dptr = keydeldata;
+           key.dsize = strlen(keydeldata);
+            rv = apr_dbm_store(db, key, val);
+            if (rv != APR_SUCCESS) {
+                prdatum(stderr, key);
+                fprintf(stderr, ": ");
+                oops(db, rv, "store: %s", "failed");
+            }
+            fputs("OK\n", stderr);
+            fputs("Testing exists: ", stderr);
+            exists = apr_dbm_exists(db, key);
+            if (exists == 0) {
+                prdatum(stderr, key);
+                fprintf(stderr, ": ");
+                oops(db, 0, "exist: %s", "failed");
+            }
+            fputs("OK\n", stderr);
+            fputs("Testing deletion: ", stderr);
+            if (apr_dbm_delete(db, key) != APR_SUCCESS) {
+                prdatum(stderr, key);
+                fprintf(stderr, ": ");
+                oops(db, rv, "deletion: %s", "failed");
+            }
+            fputs("OK\n", stderr);
         }
         break;
     }


 
New testdbm.c output without patch:
./testdbm auto SDBM
Generating data: OK
Testing retrieval: OK
Testing store for deletion: OK
Testing exists: KEYTODELETE: testdbm: exist: failed

With patch:
 ./testdbm auto SDBM
Generating data: OK
Testing retrieval: OK
Testing store for deletion: OK
Testing exists: OK
Testing deletion: OK
 
David Jones