Skip to content

Commit 8db5e70

Browse files
committed
DBA should not convert elements in-place if the key param is an array
Also check that the value can actually be converted to string
1 parent b50dc1e commit 8db5e70

File tree

3 files changed

+116
-7
lines changed

3 files changed

+116
-7
lines changed

ext/dba/dba.c

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,11 @@ ZEND_TSRMLS_CACHE_DEFINE()
8989
ZEND_GET_MODULE(dba)
9090
#endif
9191

92-
/* {{{ php_dba_myke_key */
92+
/* {{{ php_dba_make_key */
9393
static zend_string* php_dba_make_key(HashTable *key)
9494
{
9595
zval *group, *name;
96+
zend_string *group_str, *name_str;
9697
HashPosition pos;
9798

9899
if (zend_hash_num_elements(key) != 2) {
@@ -103,16 +104,29 @@ static zend_string* php_dba_make_key(HashTable *key)
103104
// TODO: Use ZEND_HASH_FOREACH_VAL() API?
104105
zend_hash_internal_pointer_reset_ex(key, &pos);
105106
group = zend_hash_get_current_data_ex(key, &pos);
107+
group_str = zval_try_get_string(group);
108+
if (!group_str) {
109+
return NULL;
110+
}
111+
106112
zend_hash_move_forward_ex(key, &pos);
107113
name = zend_hash_get_current_data_ex(key, &pos);
108-
// TODO: Use zval_try_get_string() or try_convert_to_string() instead?
109-
convert_to_string(group);
110-
convert_to_string(name);
114+
name_str = zval_try_get_string(name);
115+
if (!name_str) {
116+
zend_string_release_ex(group_str, false);
117+
return NULL;
118+
}
119+
111120
// TODO: Check ZSTR_LEN(name) != 0
112-
if (Z_STRLEN_P(group) == 0) {
113-
return zend_string_copy(Z_STR_P(name));
121+
if (ZSTR_LEN(group_str) == 0) {
122+
zend_string_release_ex(group_str, false);
123+
return name_str;
114124
}
115-
return zend_strpprintf(0, "[%s]%s", Z_STRVAL_P(group), Z_STRVAL_P(name));
125+
126+
zend_string *key_str = zend_strpprintf(0, "[%s]%s", ZSTR_VAL(group_str), ZSTR_VAL(name_str));
127+
zend_string_release_ex(group_str, false);
128+
zend_string_release_ex(name_str, false);
129+
return key_str;
116130
}
117131
/* }}} */
118132

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
--TEST--
2+
DBA check behaviour of key as an array with elements not convertable to string
3+
--EXTENSIONS--
4+
dba
5+
--SKIPIF--
6+
<?php
7+
require_once(__DIR__ .'/skipif.inc');
8+
die("info $HND handler used");
9+
?>
10+
--FILE--
11+
<?php
12+
require_once(__DIR__ .'/test.inc');
13+
$db_file = dba_open($db_file, "n", $handler);
14+
15+
if ($db_file === false) {
16+
die('Error creating database');
17+
}
18+
19+
/* Use an object */
20+
$o = new stdClass();
21+
try {
22+
var_dump(dba_insert([$o, 'obj'], 'Test', $db_file));
23+
} catch (\Error $e) {
24+
echo $e::class, ': ', $e->getMessage(), \PHP_EOL;
25+
}
26+
try {
27+
var_dump(dba_insert(['group', $o], 'Test', $db_file));
28+
} catch (\Error $e) {
29+
echo $e::class, ': ', $e->getMessage(), \PHP_EOL;
30+
}
31+
32+
dba_close($db_file);
33+
34+
?>
35+
--CLEAN--
36+
<?php
37+
require(__DIR__ .'/clean.inc');
38+
?>
39+
--EXPECT--
40+
Error: Object of class stdClass could not be converted to string
41+
Error: Object of class stdClass could not be converted to string
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
--TEST--
2+
DBA check behaviour of key as an array with non string elements
3+
--EXTENSIONS--
4+
dba
5+
--SKIPIF--
6+
<?php
7+
require_once(__DIR__ .'/skipif.inc');
8+
die("info $HND handler used");
9+
?>
10+
--FILE--
11+
<?php
12+
require_once(__DIR__ .'/test.inc');
13+
$db_file = dba_open($db_file, "n", $handler);
14+
15+
if ($db_file === false) {
16+
die('Error creating database');
17+
}
18+
19+
$key = [5, 5.21];
20+
21+
var_dump($key);
22+
var_dump(dba_insert($key, 'Test', $db_file));
23+
var_dump($key);
24+
var_dump(dba_fetch($key, $db_file));
25+
var_dump($key);
26+
27+
dba_close($db_file);
28+
29+
?>
30+
--CLEAN--
31+
<?php
32+
require(__DIR__ .'/clean.inc');
33+
?>
34+
--EXPECT--
35+
array(2) {
36+
[0]=>
37+
int(5)
38+
[1]=>
39+
float(5.21)
40+
}
41+
bool(true)
42+
array(2) {
43+
[0]=>
44+
int(5)
45+
[1]=>
46+
float(5.21)
47+
}
48+
string(4) "Test"
49+
array(2) {
50+
[0]=>
51+
int(5)
52+
[1]=>
53+
float(5.21)
54+
}

0 commit comments

Comments
 (0)