php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #26304 Unexpected data loss when opening dba file
Submitted: 2003-11-18 12:09 UTC Modified: 2003-12-14 17:17 UTC
Votes:2
Avg. Score:4.5 ± 0.5
Reproduced:2 of 2 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: vesely at tana dot it Assigned: helly
Status: Closed Package: DBM/DBA related
PHP Version: 4.3.4 OS: *
Private report: No CVE-ID:
 [2003-11-18 12:09 UTC] vesely at tana dot it
Description:
------------
Opening a file in 'c' mode (see example below)
truncates the file!! The docs say '"c" for read/write
access and database creation if it doesn't currently exist.'

I cannot understand that comment at line 658 in
ext/dba/dba.c, as it seems to imply that truncating
the database is necessary for locking it (??).

Reproduce code:
---------------
dba_open("important_data.db", "c", "db4");

Expected result:
----------------
open db (create if doesn't exist)

Actual result:
--------------
truncated db

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2003-11-18 12:59 UTC] vesely at tana dot it
Also, that correction around line 67 in dba_db4.c
(DBA_OPEN_FUNC) is bogus: if stat returns 0 you want
to say DB_UNKNOWN, since you cannot say it is DB_BTREE
when it was created by some other program.

To reproduce the bug you should create a DB with a different
type, e.g. in C if you just include db.h and then call
the dbm_open compatibility layer. The Sleepycat message
will then say "call implies an access method which is
inconsistent with previous calls."
 [2003-11-19 00:32 UTC] vorlon at debian dot org
This bug has also been reported at <http://bugs.debian.org/221559>.

The source of this behavior is quite clear -- 
ext/dba/dba.c:

case 'c':
        modenr = DBA_CREAT;
        lock_mode = (lock_flag & DBA_LOCK_CREAT) ? LOCK_EX : 0;
        file_mode = "a+b";
if (!lock_mode || !lock_dbf) {
        break;
}
/* When we lock the db file it will be created before the handler
 * even tries to open it, hence we must change to truncate mode.
 */
case 'n':
        modenr = DBA_TRUNC;
        lock_mode = (lock_flag & DBA_LOCK_TRUNC) ? LOCK_EX : 0;
        file_mode = "w+b";
        break;

So unless locking is explicitly disabled (or explicitly configured to use an external lockfile), 'CREAT' mode results in automatic truncation of the database?  What kind of sense does that make?

The behavior on the HEAD branch looks correct, but doesn't seem to interact well with the 4.3 version of the code ("Driver initialization failed for handler: db4: Bad file descriptor").  The current behavior certainly is NOT correct, for db4.
 [2003-11-19 22:14 UTC] vorlon at debian dot org
Correction, the "bad file descriptor" error came from excessive fiddling with my test case.  The lock handling when opening with mode 'c' in CVS HEAD appears to be correct for db4.
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Sat Apr 19 17:01:54 2014 UTC