Arghhh!!! It's transparent, not opaque, so this cannot be solved quite
this way until 2.0. I'd be interested to learn which casts masked this
flaw.
In any case - to retain our binary API versioning rules, we need to make
this fix invisible to the user's API. Contributions welcome, or when we
get to integrating this patch, hopefully one of us finds cycles to
transform the apr_sdbm_datum_t on the fly.
Bill
David Jones wrote:
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