Refactor dba_(p)open() to be more sensible (#7610)

Actually use ZPP
Throw ValueErrors for invalid values
Use dedicated struc members for file permission and map size instead of a zval stack
This commit is contained in:
George Peter Banyard 2021-11-06 23:09:40 +00:00 committed by GitHub
parent a6cc76eeb8
commit 7db32add9b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 293 additions and 262 deletions

View File

@ -77,6 +77,8 @@ PHP 8.2 UPGRADE NOTES
========================================
- DBA
. dba_open() and dba_popen() now have the following enforced function signature
dba_open(string $path, string $mode, ?string $handler = null, int $permission = 0o644, int $map_size = 0)
. dba_fetch()'s optional skip argument is now at the end in line with
PHP userland semantics its signature now is:
dba_fetch(string|array $key, $dba, int $skip = 0): string|false

View File

@ -433,8 +433,6 @@ static void php_dba_update(INTERNAL_FUNCTION_PARAMETERS, int mode)
}
/* }}} */
#define FREENOW if(args) {int i; for (i=0; i<ac; i++) { zval_ptr_dtor(&args[i]); } efree(args);} if(key) efree(key)
/* {{{ php_find_dbm */
dba_info *php_dba_find(const char* path)
{
@ -459,20 +457,18 @@ dba_info *php_dba_find(const char* path)
}
/* }}} */
#define FREE_PERSISTENT_RESOURCE_KEY() if (persistent_resource_key) {zend_string_release_ex(persistent_resource_key, false);}
/* {{{ php_dba_open */
static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, int persistent)
static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, bool persistent)
{
zval *args = NULL;
int ac = ZEND_NUM_ARGS();
dba_mode_t modenr;
dba_info *info, *other;
dba_handler *hptr;
char *key = NULL, *error = NULL;
size_t keylen = 0;
int i;
int lock_mode, lock_flag, lock_dbf = 0;
char *error = NULL;
int lock_mode, lock_flag = 0;
char *file_mode;
char mode[4], *pmode, *lock_file_mode = NULL;
char *lock_file_mode = NULL;
int persistent_flag = persistent ? STREAM_OPEN_PERSISTENT : 0;
zend_string *opened_path = NULL;
char *lock_name;
@ -481,47 +477,57 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, int persistent)
bool need_creation = 0;
#endif
if (ac < 2) {
WRONG_PARAM_COUNT;
zend_string *path;
zend_string *mode;
zend_string *handler_str = NULL;
zend_long permission = 0644;
zend_long map_size = 0;
zend_string *persistent_resource_key = NULL;
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "PS|S!ll", &path, &mode, &handler_str,
&permission, &map_size)) {
RETURN_THROWS();
}
/* we pass additional args to the respective handler */
args = safe_emalloc(ac, sizeof(zval), 0);
if (zend_get_parameters_array_ex(ac, args) != SUCCESS) {
efree(args);
WRONG_PARAM_COUNT;
if (ZSTR_LEN(path) == 0) {
zend_argument_value_error(1, "cannot be empty");
RETURN_THROWS();
}
/* we only take string arguments */
for (i = 0; i < ac; i++) {
ZVAL_STR(&args[i], zval_get_string(&args[i]));
keylen += Z_STRLEN(args[i]);
if (ZSTR_LEN(mode) == 0) {
zend_argument_value_error(2, "cannot be empty");
RETURN_THROWS();
}
/* Exception during string conversion */
if (EG(exception)) {
FREENOW;
if (handler_str && ZSTR_LEN(handler_str) == 0) {
zend_argument_value_error(3, "cannot be empty");
RETURN_THROWS();
}
// TODO Check Value for permission
if (map_size < 0) {
zend_argument_value_error(5, "must be greater or equal than 0");
RETURN_THROWS();
}
if (persistent) {
zend_resource *le;
/* calculate hash */
key = safe_emalloc(keylen, 1, 1);
key[keylen] = '\0';
keylen = 0;
for(i = 0; i < ac; i++) {
memcpy(key+keylen, Z_STRVAL(args[i]), Z_STRLEN(args[i]));
keylen += Z_STRLEN(args[i]);
if (handler_str) {
persistent_resource_key = zend_string_concat3(
ZSTR_VAL(path), ZSTR_LEN(path),
ZSTR_VAL(mode), ZSTR_LEN(mode),
ZSTR_VAL(handler_str), ZSTR_LEN(handler_str)
);
} else {
persistent_resource_key = zend_string_concat2(
ZSTR_VAL(path), ZSTR_LEN(path),
ZSTR_VAL(mode), ZSTR_LEN(mode)
);
}
/* try to find if we already have this link in our persistent list */
if ((le = zend_hash_str_find_ptr(&EG(persistent_list), key, keylen)) != NULL) {
FREENOW;
if ((le = zend_hash_find_ptr(&EG(persistent_list), persistent_resource_key)) != NULL) {
FREE_PERSISTENT_RESOURCE_KEY();
if (le->type != le_pdb) {
// TODO This should never happen
RETURN_FALSE;
}
@ -529,28 +535,29 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, int persistent)
GC_ADDREF(le);
RETURN_RES(zend_register_resource(info, le_pdb));
return;
}
}
if (ac==2) {
if (!handler_str) {
hptr = DBA_G(default_hptr);
if (!hptr) {
php_error_docref2(NULL, Z_STRVAL(args[0]), Z_STRVAL(args[1]), E_WARNING, "No default handler selected");
FREENOW;
php_error_docref(NULL, E_WARNING, "No default handler selected");
FREE_PERSISTENT_RESOURCE_KEY();
RETURN_FALSE;
}
ZEND_ASSERT(hptr->name);
} else {
for (hptr = handler; hptr->name && strcasecmp(hptr->name, Z_STRVAL(args[2])); hptr++);
/* Loop through global static var handlers to see if such a handler exists */
for (hptr = handler; hptr->name && strcasecmp(hptr->name, ZSTR_VAL(handler_str)); hptr++);
if (!hptr->name) {
php_error_docref(NULL, E_WARNING, "Handler \"%s\" is not available", ZSTR_VAL(handler_str));
FREE_PERSISTENT_RESOURCE_KEY();
RETURN_FALSE;
}
}
if (!hptr->name) {
php_error_docref2(NULL, Z_STRVAL(args[0]), Z_STRVAL(args[1]), E_WARNING, "No such handler: %s", Z_STRVAL(args[2]));
FREENOW;
RETURN_FALSE;
}
/* Check mode: [rwnc][fl]?t?
/* Check mode: [rwnc][dl-]?t?
* r: Read
* w: Write
* n: Create/Truncate
@ -562,38 +569,68 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, int persistent)
*
* t: test open database, warning if locked
*/
strlcpy(mode, Z_STRVAL(args[1]), sizeof(mode));
pmode = &mode[0];
if (pmode[0] && (pmode[1]=='d' || pmode[1]=='l' || pmode[1]=='-')) { /* force lock on db file or lck file or disable locking */
switch (pmode[1]) {
case 'd':
lock_dbf = 1;
if ((hptr->flags & DBA_LOCK_ALL) == 0) {
lock_flag = (hptr->flags & DBA_LOCK_ALL);
bool is_test_lock = false;
bool is_db_lock = false;
bool is_lock_ignored = false;
// bool is_file_lock = false;
if (ZSTR_LEN(mode) == 0) {
zend_argument_value_error(2, "cannot be empty");
FREE_PERSISTENT_RESOURCE_KEY();
RETURN_THROWS();
}
if (ZSTR_LEN(mode) > 3) {
zend_argument_value_error(2, "must be at most 3 characters");
FREE_PERSISTENT_RESOURCE_KEY();
RETURN_THROWS();
}
if (ZSTR_LEN(mode) == 3) {
if (ZSTR_VAL(mode)[2] != 't') {
zend_argument_value_error(2, "third character must be \"t\"");
FREE_PERSISTENT_RESOURCE_KEY();
RETURN_THROWS();
}
is_test_lock = true;
}
if (ZSTR_LEN(mode) >= 2) {
switch (ZSTR_VAL(mode)[1]) {
case 't':
is_test_lock = true;
break;
}
ZEND_FALLTHROUGH;
case 'l':
lock_flag = DBA_LOCK_ALL;
if ((hptr->flags & DBA_LOCK_ALL) == 0) {
php_error_docref2(NULL, Z_STRVAL(args[0]), Z_STRVAL(args[1]), E_NOTICE, "Handler %s does locking internally", hptr->name);
}
break;
default:
case '-':
if ((hptr->flags & DBA_LOCK_ALL) == 0) {
php_error_docref2(NULL, Z_STRVAL(args[0]), Z_STRVAL(args[1]), E_WARNING, "Locking cannot be disabled for handler %s", hptr->name);
FREENOW;
RETURN_FALSE;
}
lock_flag = 0;
case '-':
if ((hptr->flags & DBA_LOCK_ALL) == 0) {
php_error_docref(NULL, E_WARNING, "Locking cannot be disabled for handler %s", hptr->name);
FREE_PERSISTENT_RESOURCE_KEY();
RETURN_FALSE;
}
is_lock_ignored = true;
lock_flag = 0;
break;
case 'd':
is_db_lock = true;
if ((hptr->flags & DBA_LOCK_ALL) == 0) {
lock_flag = (hptr->flags & DBA_LOCK_ALL);
break;
}
ZEND_FALLTHROUGH;
case 'l':
// is_file_lock = true;
lock_flag = DBA_LOCK_ALL;
if ((hptr->flags & DBA_LOCK_ALL) == 0) {
php_error_docref(NULL, E_NOTICE, "Handler %s does locking internally", hptr->name);
}
break;
default:
zend_argument_value_error(2, "second character must be one of \"d\", \"l\", \"-\", or \"t\"");
FREE_PERSISTENT_RESOURCE_KEY();
RETURN_THROWS();
}
} else {
lock_flag = (hptr->flags&DBA_LOCK_ALL);
lock_dbf = 1;
is_db_lock = true;
}
switch (*pmode++) {
switch (ZSTR_VAL(mode)[0]) {
case 'r':
modenr = DBA_READER;
lock_mode = (lock_flag & DBA_LOCK_READER) ? LOCK_SH : 0;
@ -608,13 +645,13 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, int persistent)
#ifdef PHP_WIN32
if (hptr->flags & (DBA_NO_APPEND|DBA_CAST_AS_FD)) {
php_stream_statbuf ssb;
need_creation = (SUCCESS != php_stream_stat_path(Z_STRVAL(args[0]), &ssb));
need_creation = (SUCCESS != php_stream_stat_path(ZSTR_VAL(path), &ssb));
}
#endif
modenr = DBA_CREAT;
lock_mode = (lock_flag & DBA_LOCK_CREAT) ? LOCK_EX : 0;
if (lock_mode) {
if (lock_dbf) {
if (is_db_lock) {
/* the create/append check will be done on the lock
* when the lib opens the file it is already created
*/
@ -653,54 +690,45 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, int persistent)
file_mode = "w+b";
break;
default:
php_error_docref2(NULL, Z_STRVAL(args[0]), Z_STRVAL(args[1]), E_WARNING, "Illegal DBA mode");
FREENOW;
RETURN_FALSE;
zend_argument_value_error(2, "first character must be one of \"r\", \"w\", \"c\", or \"n\"");
FREE_PERSISTENT_RESOURCE_KEY();
RETURN_THROWS();
}
if (!lock_file_mode) {
lock_file_mode = file_mode;
}
if (*pmode=='d' || *pmode=='l' || *pmode=='-') {
pmode++; /* done already - skip here */
}
if (*pmode=='t') {
pmode++;
if (!lock_flag) {
php_error_docref2(NULL, Z_STRVAL(args[0]), Z_STRVAL(args[1]), E_WARNING, "You cannot combine modifiers - (no lock) and t (test lock)");
FREENOW;
RETURN_FALSE;
if (is_test_lock) {
if (is_lock_ignored) {
zend_argument_value_error(2, "cannot combine mode \"-\" (no lock) and \"t\" (test lock)");
FREE_PERSISTENT_RESOURCE_KEY();
RETURN_THROWS();
}
if (!lock_mode) {
if ((hptr->flags & DBA_LOCK_ALL) == 0) {
php_error_docref2(NULL, Z_STRVAL(args[0]), Z_STRVAL(args[1]), E_WARNING, "Handler %s uses its own locking which doesn't support mode modifier t (test lock)", hptr->name);
FREENOW;
php_error_docref(NULL, E_WARNING, "Handler %s uses its own locking which doesn't support mode modifier t (test lock)", hptr->name);
FREE_PERSISTENT_RESOURCE_KEY();
RETURN_FALSE;
} else {
php_error_docref2(NULL, Z_STRVAL(args[0]), Z_STRVAL(args[1]), E_WARNING, "Handler %s doesn't uses locking for this mode which makes modifier t (test lock) obsolete", hptr->name);
FREENOW;
php_error_docref(NULL, E_WARNING, "Handler %s doesn't uses locking for this mode which makes modifier t (test lock) obsolete", hptr->name);
FREE_PERSISTENT_RESOURCE_KEY();
RETURN_FALSE;
}
} else {
lock_mode |= LOCK_NB; /* test =: non blocking */
}
}
if (*pmode) {
php_error_docref2(NULL, Z_STRVAL(args[0]), Z_STRVAL(args[1]), E_WARNING, "Illegal DBA mode");
FREENOW;
RETURN_FALSE;
}
info = pemalloc(sizeof(dba_info), persistent);
memset(info, 0, sizeof(dba_info));
info->path = pestrdup(Z_STRVAL(args[0]), persistent);
info->path = pestrdup(ZSTR_VAL(path), persistent);
info->mode = modenr;
info->argc = ac - 3;
info->argv = args + 3;
info->file_permission = permission;
info->map_size = map_size;
info->flags = (hptr->flags & ~DBA_LOCK_ALL) | (lock_flag & DBA_LOCK_ALL) | (persistent ? DBA_PERSISTENT : 0);
info->lock.mode = lock_mode;
/* if any open call is a locking call:
* check if we already habe a locking call open that should block this call
* check if we already have a locking call open that should block this call
* the problem is some systems would allow read during write
*/
if (hptr->flags & DBA_LOCK_ALL) {
@ -717,8 +745,8 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, int persistent)
restart:
#endif
if (!error && lock_mode) {
if (lock_dbf) {
lock_name = Z_STRVAL(args[0]);
if (is_db_lock) {
lock_name = ZSTR_VAL(path);
} else {
spprintf(&lock_name, 0, "%s.lck", info->path);
if (!strcmp(file_mode, "r")) {
@ -740,7 +768,7 @@ restart:
if (!info->lock.fp) {
info->lock.fp = php_stream_open_wrapper(lock_name, lock_file_mode, STREAM_MUST_SEEK|REPORT_ERRORS|IGNORE_PATH|persistent_flag, &opened_path);
if (info->lock.fp) {
if (lock_dbf) {
if (is_db_lock) {
/* replace the path info with the real path of the opened file */
pefree(info->path, persistent);
info->path = pestrndup(ZSTR_VAL(opened_path), ZSTR_LEN(opened_path), persistent);
@ -750,13 +778,13 @@ restart:
zend_string_release_ex(opened_path, 0);
}
}
if (!lock_dbf) {
if (!is_db_lock) {
efree(lock_name);
}
if (!info->lock.fp) {
dba_close(info);
/* stream operation already wrote an error message */
FREENOW;
FREE_PERSISTENT_RESOURCE_KEY();
RETURN_FALSE;
}
if (!php_stream_supports_lock(info->lock.fp)) {
@ -769,7 +797,7 @@ restart:
/* centralised open stream for builtin */
if (!error && (hptr->flags&DBA_STREAM_OPEN)==DBA_STREAM_OPEN) {
if (info->lock.fp && lock_dbf) {
if (info->lock.fp && is_db_lock) {
info->fp = info->lock.fp; /* use the same stream for locking and database access */
} else {
info->fp = php_stream_open_wrapper(info->path, file_mode, STREAM_MUST_SEEK|REPORT_ERRORS|IGNORE_PATH|persistent_flag, NULL);
@ -777,7 +805,7 @@ restart:
if (!info->fp) {
dba_close(info);
/* stream operation already wrote an error message */
FREENOW;
FREE_PERSISTENT_RESOURCE_KEY();
RETURN_FALSE;
}
if (hptr->flags & (DBA_NO_APPEND|DBA_CAST_AS_FD)) {
@ -787,7 +815,7 @@ restart:
if (SUCCESS != php_stream_cast(info->fp, PHP_STREAM_AS_FD, (void*)&info->fd, 1)) {
php_error_docref(NULL, E_WARNING, "Could not cast stream");
dba_close(info);
FREENOW;
FREE_PERSISTENT_RESOURCE_KEY();
RETURN_FALSE;
#ifdef F_SETFL
} else if (modenr == DBA_CREAT) {
@ -819,29 +847,27 @@ restart:
if (error || hptr->open(info, &error) != SUCCESS) {
dba_close(info);
php_error_docref2(NULL, Z_STRVAL(args[0]), Z_STRVAL(args[1]), E_WARNING, "Driver initialization failed for handler: %s%s%s", hptr->name, error?": ":"", error?error:"");
FREENOW;
php_error_docref(NULL, E_WARNING, "Driver initialization failed for handler: %s%s%s", hptr->name, error?": ":"", error?error:"");
FREE_PERSISTENT_RESOURCE_KEY();
RETURN_FALSE;
}
info->hnd = hptr;
info->argc = 0;
info->argv = NULL;
if (persistent) {
if (zend_register_persistent_resource(key, keylen, info, le_pdb) == NULL) {
ZEND_ASSERT(persistent_resource_key);
if (zend_register_persistent_resource_ex(persistent_resource_key, info, le_pdb) == NULL) {
dba_close(info);
php_error_docref2(NULL, Z_STRVAL(args[0]), Z_STRVAL(args[1]), E_WARNING, "Could not register persistent resource");
FREENOW;
php_error_docref(NULL, E_WARNING, "Could not register persistent resource");
FREE_PERSISTENT_RESOURCE_KEY();
RETURN_FALSE;
}
FREE_PERSISTENT_RESOURCE_KEY();
}
RETVAL_RES(zend_register_resource(info, (persistent ? le_pdb : le_db)));
FREENOW;
RETURN_RES(zend_register_resource(info, (persistent ? le_pdb : le_db)));
}
/* }}} */
#undef FREENOW
/* {{{ Opens path using the specified handler in mode persistently */
PHP_FUNCTION(dba_popen)

View File

@ -2,23 +2,11 @@
/** @generate-class-entries */
/**
* @param string $path
* @param string $mode
* @param string $handler
* @param string $handler_params
* @return resource|false
*/
function dba_popen($path, $mode, $handler = UNKNOWN, ...$handler_params) {}
/** @return resource|false */
function dba_popen(string $path, string $mode, ?string $handler = null, int $permission = 0o644, int $map_size = 0) {}
/**
* @param string $path
* @param string $mode
* @param string $handler
* @param string $handler_params
* @return resource|false
*/
function dba_open($path, $mode, $handler = UNKNOWN, ...$handler_params) {}
/** @return resource|false */
function dba_open(string $path, string $mode, ?string $handler = null, int $permission = 0o644, int $map_size = 0) {}
/** @param resource $dba */
function dba_close($dba): void {}

View File

@ -1,11 +1,12 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: b5e8100725ae7e93f3ae4a599d88e6578884d0d4 */
* Stub hash: db8b6f51859bc3334abafcc0ee645e614c6f1c59 */
ZEND_BEGIN_ARG_INFO_EX(arginfo_dba_popen, 0, 0, 2)
ZEND_ARG_INFO(0, path)
ZEND_ARG_INFO(0, mode)
ZEND_ARG_INFO(0, handler)
ZEND_ARG_VARIADIC_INFO(0, handler_params)
ZEND_ARG_TYPE_INFO(0, path, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, mode, IS_STRING, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, handler, IS_STRING, 1, "null")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, permission, IS_LONG, 0, "0644")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, map_size, IS_LONG, 0, "0")
ZEND_END_ARG_INFO()
#define arginfo_dba_open arginfo_dba_popen

View File

@ -41,11 +41,7 @@ DBA_OPEN_FUNC(db1)
DB *db;
int gmode;
int filemode = 0644;
if (info->argc > 0) {
filemode = zval_get_long(&info->argv[0]);
}
int filemode = info->file_permission;
gmode = 0;
switch (info->mode) {

View File

@ -39,7 +39,7 @@ DBA_OPEN_FUNC(db2)
DB *dbp;
DBTYPE type;
int gmode = 0;
int filemode = 0644;
int filemode = info->file_permission;
struct stat check_stat;
int s = VCWD_STAT(info->path, &check_stat);
@ -61,10 +61,6 @@ DBA_OPEN_FUNC(db2)
return FAILURE;/* not possible */
}
if (info->argc > 0) {
filemode = zval_get_long(&info->argv[0]);
}
if (db_open(info->path, type, gmode, filemode, NULL, NULL, &dbp)) {
return FAILURE;
}

View File

@ -51,7 +51,7 @@ DBA_OPEN_FUNC(db3)
DB *dbp = NULL;
DBTYPE type;
int gmode = 0, err;
int filemode = 0644;
int filemode = info->file_permission;
struct stat check_stat;
int s = VCWD_STAT(info->path, &check_stat);
@ -73,10 +73,6 @@ DBA_OPEN_FUNC(db3)
return FAILURE; /* not possible */
}
if (info->argc > 0) {
filemode = zval_get_long(&info->argv[0]);
}
#ifdef DB_FCNTL_LOCKING
gmode |= DB_FCNTL_LOCKING;
#endif

View File

@ -65,7 +65,7 @@ DBA_OPEN_FUNC(db4)
DB *dbp = NULL;
DBTYPE type;
int gmode = 0, err;
int filemode = 0644;
int filemode = info->file_permission;
struct stat check_stat;
int s = VCWD_STAT(info->path, &check_stat);
@ -106,10 +106,6 @@ DBA_OPEN_FUNC(db4)
gmode |= DB_THREAD;
}
if (info->argc > 0) {
filemode = zval_get_long(&info->argv[0]);
}
if ((err=db_create(&dbp, NULL, 0)) == 0) {
dbp->set_errcall(dbp, php_dba_db4_errcall_fcn);
if (

View File

@ -50,11 +50,7 @@ typedef struct {
DBA_OPEN_FUNC(dbm)
{
int fd;
int filemode = 0644;
if(info->argc > 0) {
filemode = zval_get_long(&info->argv[0]);
}
int filemode = info->file_permission;
if(info->mode == DBA_TRUNC) {
char buf[MAXPATHLEN];

View File

@ -36,7 +36,7 @@ DBA_OPEN_FUNC(gdbm)
{
GDBM_FILE dbf;
int gmode = 0;
int filemode = 0644;
int filemode = info->file_permission;
gmode = info->mode == DBA_READER ? GDBM_READER :
info->mode == DBA_WRITER ? GDBM_WRITER :
@ -46,10 +46,6 @@ DBA_OPEN_FUNC(gdbm)
if(gmode == -1)
return FAILURE; /* not possible */
if(info->argc > 0) {
filemode = zval_get_long(&info->argv[0]);
}
dbf = gdbm_open(info->path, 0, gmode, filemode, NULL);
if(dbf) {

View File

@ -40,21 +40,11 @@ DBA_OPEN_FUNC(lmdb)
{
MDB_env *env;
MDB_txn *txn;
int rc, mode = 0644, flags = MDB_NOSUBDIR;
zend_long mapsize = 0;
int rc, flags = MDB_NOSUBDIR;
int mode = info->file_permission;
zend_long map_size = info->map_size;
if(info->argc > 0) {
mode = zval_get_long(&info->argv[0]);
if (info->argc > 1) {
mapsize = zval_get_long(&info->argv[1]);
if (mapsize < 0) {
*error = "mapsize must be greater than or equal to zero";
return FAILURE;
}
}
/* TODO implement handling of the additional flags. */
}
ZEND_ASSERT(map_size >= 0);
rc = mdb_env_create(&env);
if (rc) {
@ -62,8 +52,8 @@ DBA_OPEN_FUNC(lmdb)
return FAILURE;
}
if (mapsize > 0) {
rc = mdb_env_set_mapsize(env, (size_t) mapsize);
if (map_size > 0) {
rc = mdb_env_set_mapsize(env, (size_t) map_size);
if (rc) {
*error = mdb_strerror(rc);
return FAILURE;

View File

@ -32,7 +32,7 @@ DBA_OPEN_FUNC(ndbm)
{
DBM *dbf;
int gmode = 0;
int filemode = 0644;
int filemode = info->file_permission;
dba_info *pinfo = (dba_info *) info;
switch(info->mode) {
@ -52,10 +52,6 @@ DBA_OPEN_FUNC(ndbm)
return FAILURE; /* not possible */
}
if(info->argc > 0) {
filemode = zval_get_long(&info->argv[0]);
}
dbf = dbm_open(info->path, gmode, filemode);
pinfo->dbf = dbf;

View File

@ -43,9 +43,8 @@ typedef struct dba_info {
dba_mode_t mode;
php_stream *fp; /* this is the database stream for builtin handlers */
int fd;
/* arg[cv] are only available when the dba_open handler is called! */
int argc;
zval *argv;
int file_permission;
zend_long map_size;
/* private */
int flags; /* whether and how dba did locking and other flags*/
struct dba_handler *hnd;

View File

@ -1,24 +0,0 @@
--TEST--
Bug #72157 (use-after-free caused by dba_open)
--EXTENSIONS--
dba
--SKIPIF--
<?php
require_once(__DIR__ .'/skipif.inc');
?>
--FILE--
<?php
$var0 = fopen(__FILE__,"r");
$var5 = dba_open(null,$var0);
$var5 = dba_open(null,$var0);
$var5 = dba_open(null,$var0);
$var5 = dba_open($var0,$var0);
?>
--EXPECTF--
Warning: dba_open(,Resource id #5): Illegal DBA mode in %sbug72157.php on line %d
Warning: dba_open(,Resource id #5): Illegal DBA mode in %sbug72157.php on line %d
Warning: dba_open(,Resource id #5): Illegal DBA mode in %sbug72157.php on line %d
Warning: dba_open(Resource id #5,Resource id #5): Illegal DBA mode in %sbug72157.php on line %d

View File

@ -12,10 +12,100 @@ die("info $HND handler used");
require_once(__DIR__ .'/test.inc');
echo "database handler: $handler\n";
var_dump(dba_open($db_file, 'n'));
echo '=== Invalid arguments dba_open() ===', \PHP_EOL;
var_dump(dba_open($db_file, 'n', 'bogus'));
var_dump(dba_open($db_file, 'q', $handler));
var_dump(dba_open($db_file, 'nq', $handler));
var_dump(dba_open($db_file, 'n', $handler, 2, 3, 4, 5, 6, 7, 8));
try {
var_dump(dba_open('', 'nq'));
} catch (\ValueError $e) {
echo $e->getMessage(), \PHP_EOL;
}
try {
var_dump(dba_open($db_file, ''));
} catch (\ValueError $e) {
echo $e->getMessage(), \PHP_EOL;
}
try {
var_dump(dba_open($db_file, 'nq', ''));
} catch (\ValueError $e) {
echo $e->getMessage(), \PHP_EOL;
}
try {
var_dump(dba_open($db_file, 'q'));
} catch (\ValueError $e) {
echo $e->getMessage(), \PHP_EOL;
}
try {
var_dump(dba_open($db_file, 'nq'));
} catch (\ValueError $e) {
echo $e->getMessage(), \PHP_EOL;
}
try {
var_dump(dba_open($db_file, 'rdq'));
} catch (\ValueError $e) {
echo $e->getMessage(), \PHP_EOL;
}
try {
var_dump(dba_open($db_file, 'n-t'));
} catch (\ValueError $e) {
echo $e->getMessage(), \PHP_EOL;
}
try {
var_dump(dba_open($db_file, 'r', $handler, 0o644, -10));
} catch (\ValueError $e) {
echo $e->getMessage(), \PHP_EOL;
}
echo '=== Invalid arguments dba_popen() ===', \PHP_EOL;
var_dump(dba_popen($db_file, 'n', 'bogus'));
try {
var_dump(dba_popen('', 'nq'));
} catch (\ValueError $e) {
echo $e->getMessage(), \PHP_EOL;
}
try {
var_dump(dba_popen($db_file, ''));
} catch (\ValueError $e) {
echo $e->getMessage(), \PHP_EOL;
}
try {
var_dump(dba_popen($db_file, 'nq', ''));
} catch (\ValueError $e) {
echo $e->getMessage(), \PHP_EOL;
}
try {
var_dump(dba_popen($db_file, 'q'));
} catch (\ValueError $e) {
echo $e->getMessage(), \PHP_EOL;
}
try {
var_dump(dba_popen($db_file, 'nq'));
} catch (\ValueError $e) {
echo $e->getMessage(), \PHP_EOL;
}
try {
var_dump(dba_popen($db_file, 'rdq'));
} catch (\ValueError $e) {
echo $e->getMessage(), \PHP_EOL;
}
try {
var_dump(dba_popen($db_file, 'n-t'));
} catch (\ValueError $e) {
echo $e->getMessage(), \PHP_EOL;
}
try {
var_dump(dba_popen($db_file, 'r', $handler, 0o644, -10));
} catch (\ValueError $e) {
echo $e->getMessage(), \PHP_EOL;
}
?>
--CLEAN--
<?php
@ -24,13 +114,27 @@ require(__DIR__ .'/clean.inc');
--EXPECTF--
database handler: flatfile
resource(%d) of type (dba)
=== Invalid arguments dba_open() ===
Warning: dba_open(%stest0.dbm,n): No such handler: bogus in %sdba011.php on line %d
Warning: dba_open(): Handler "bogus" is not available in %sdba011.php on line %d
bool(false)
dba_open(): Argument #1 ($path) cannot be empty
dba_open(): Argument #2 ($mode) cannot be empty
dba_open(): Argument #3 ($handler) cannot be empty
dba_open(): Argument #2 ($mode) first character must be one of "r", "w", "c", or "n"
dba_open(): Argument #2 ($mode) second character must be one of "d", "l", "-", or "t"
dba_open(): Argument #2 ($mode) third character must be "t"
dba_open(): Argument #2 ($mode) cannot combine mode "-" (no lock) and "t" (test lock)
dba_open(): Argument #5 ($map_size) must be greater or equal than 0
=== Invalid arguments dba_popen() ===
Warning: dba_open(%stest0.dbm,q): Illegal DBA mode in %sdba011.php on line %d
Warning: dba_popen(): Handler "bogus" is not available in %sdba011.php on line %d
bool(false)
Warning: dba_open(%stest0.dbm,nq): Illegal DBA mode in %sdba011.php on line %d
bool(false)
resource(%d) of type (dba)
dba_popen(): Argument #1 ($path) cannot be empty
dba_popen(): Argument #2 ($mode) cannot be empty
dba_popen(): Argument #3 ($handler) cannot be empty
dba_popen(): Argument #2 ($mode) first character must be one of "r", "w", "c", or "n"
dba_popen(): Argument #2 ($mode) second character must be one of "d", "l", "-", or "t"
dba_popen(): Argument #2 ($mode) third character must be "t"
dba_popen(): Argument #2 ($mode) cannot combine mode "-" (no lock) and "t" (test lock)
dba_popen(): Argument #5 ($map_size) must be greater or equal than 0

View File

@ -40,5 +40,5 @@ Warning: ini_set(): No such handler: does_not_exist in %sdba012.php on line %d
resource(%d) of type (dba)
Test 2
Warning: dba_open(%stest0.dbm,n): No default handler selected in %sdba012.php on line %d
Warning: dba_open(): No default handler selected in %sdba012.php on line %d
bool(false)

View File

@ -1,27 +0,0 @@
--TEST--
DBA lock modifier error message test
--EXTENSIONS--
dba
--SKIPIF--
<?php
$handler = "flatfile";
require_once(__DIR__ .'/skipif.inc');
?>
--FILE--
<?php
$handler = "flatfile";
require_once(__DIR__ .'/test.inc');
echo "database handler: $handler\n";
$db_file1 = dba_popen($db_filename, 'n-t', 'flatfile');
?>
--CLEAN--
<?php
require(__DIR__ .'/clean.inc');
?>
--EXPECTF--
database handler: flatfile
Warning: dba_popen(%stest0.dbm,n-t): You cannot combine modifiers - (no lock) and t (test lock) in %sdba016.php on line %d

View File

@ -78,12 +78,12 @@ bool(true)
bool(true)
Test 1
Warning: dba_open(%stest0.dbm,c): Driver initialization failed for handler: cdb: Update operations are not supported in %sdba_cdb_001.php on line %d
Warning: dba_open(): Driver initialization failed for handler: cdb: Update operations are not supported in %sdba_cdb_001.php on line %d
Failed to open DB
Test 2
Warning: dba_insert(): You cannot perform a modification to a database without proper access in %sdba_cdb_001.php on line %d
Test 3
Warning: dba_open(%stest0.dbm,w): Driver initialization failed for handler: cdb: Update operations are not supported in %sdba_cdb_001.php on line %d
Warning: dba_open(): Driver initialization failed for handler: cdb: Update operations are not supported in %sdba_cdb_001.php on line %d
Failed to open DB

View File

@ -41,6 +41,6 @@ require(__DIR__ .'/clean.inc');
database handler: db4
int(14)
Warning: dba_open(%stest0.dbm,c): Driver initialization failed for handler: db4: Invalid argument in %sdba_db4_003.php on line %d
Warning: dba_open(): Driver initialization failed for handler: db4: Invalid argument in %sdba_db4_003.php on line %d
Error creating %stest0.dbm
Dummy contents

View File

@ -37,5 +37,5 @@ require(__DIR__ .'/clean.inc');
database handler: db4
int(14)
Warning: dba_popen(%stest0.dbm,c): Driver initialization failed for handler: db4: Invalid argument in %sdba_db4_007.php on line %d
Warning: dba_popen(): Driver initialization failed for handler: db4: Invalid argument in %sdba_db4_007.php on line %d
Error creating %stest0.dbm

View File

@ -29,5 +29,5 @@ require(__DIR__ .'/clean.inc');
--EXPECTF--
database handler: db4
Warning: dba_open(%stest0.dbm,rl): Driver initialization failed for handler: db4: No such file or directory in %sdba_db4_012.php on line %d
Warning: dba_open(): Driver initialization failed for handler: db4: No such file or directory in %sdba_db4_012.php on line %d
Error creating %stest0.dbm

View File

@ -30,5 +30,5 @@ require(__DIR__ .'/clean.inc');
--EXPECTF--
database handler: db4
Warning: dba_open(%stest0.dbm,wl): Driver initialization failed for handler: db4: No such file or directory in %sdba_db4_014.php on line %d
Warning: dba_open(): Driver initialization failed for handler: db4: No such file or directory in %sdba_db4_014.php on line %d
Error creating %stest0.dbm