mirror of
https://github.com/php/php-src.git
synced 2024-11-27 11:53:33 +08:00
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:
parent
a6cc76eeb8
commit
7db32add9b
@ -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
|
||||
|
266
ext/dba/dba.c
266
ext/dba/dba.c
@ -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)
|
||||
|
@ -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 {}
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 (
|
||||
|
@ -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];
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user