diff --git a/ext/dba/dba.c b/ext/dba/dba.c index a70951467be5..5f305b8b89ba 100644 --- a/ext/dba/dba.c +++ b/ext/dba/dba.c @@ -92,41 +92,44 @@ ZEND_GET_MODULE(dba) /* {{{ php_dba_make_key */ static zend_string* php_dba_make_key(const HashTable *key) { - zval *group, *name; - zend_string *group_str, *name_str; - HashPosition pos; - - if (zend_hash_num_elements(key) != 2) { - zend_argument_error(NULL, 1, "must have exactly two elements: \"key\" and \"name\""); - return NULL; - } - - // TODO: Use ZEND_HASH_FOREACH_VAL() API? - zend_hash_internal_pointer_reset_ex(key, &pos); - group = zend_hash_get_current_data_ex(key, &pos); - group_str = zval_try_get_string(group); - if (!group_str) { - return NULL; - } - - zend_hash_move_forward_ex(key, &pos); - name = zend_hash_get_current_data_ex(key, &pos); - name_str = zval_try_get_string(name); - if (!name_str) { - zend_string_release_ex(group_str, false); - return NULL; - } - - // TODO: Check ZSTR_LEN(name) != 0 - if (ZSTR_LEN(group_str) == 0) { - zend_string_release_ex(group_str, false); - return name_str; - } - - zend_string *key_str = zend_strpprintf(0, "[%s]%s", ZSTR_VAL(group_str), ZSTR_VAL(name_str)); - zend_string_release_ex(group_str, false); - zend_string_release_ex(name_str, false); - return key_str; + zval *zv; + zend_string *group_str = NULL, *name_str = NULL; + int i = 0; + + if (zend_hash_num_elements(key) != 2) { + zend_argument_error(NULL, 1, "must have exactly two elements: \"key\" and \"name\""); + return NULL; + } + + ZEND_HASH_FOREACH_VAL(key, zv) { + zend_string *tmp = zval_try_get_string(zv); + if (!tmp) { + if (group_str) zend_string_release(group_str); + if (name_str) zend_string_release(name_str); + return NULL; + } + + if (i++ == 0) { + group_str = tmp; + } else { + name_str = tmp; + } + } ZEND_HASH_FOREACH_END(); + + if (ZSTR_LEN(group_str) == 0) { + zend_string_release(group_str); + return name_str; + } + + zend_string *key_str = zend_strpprintf( + 0, "[%s]%s", + ZSTR_VAL(group_str), ZSTR_VAL(name_str) + ); + + zend_string_release(group_str); + zend_string_release(name_str); + + return key_str; } /* }}} */ diff --git a/ext/dba/tests/dba_insert_numeric_keys.phpt b/ext/dba/tests/dba_insert_numeric_keys.phpt new file mode 100644 index 000000000000..298beb85a4c5 --- /dev/null +++ b/ext/dba/tests/dba_insert_numeric_keys.phpt @@ -0,0 +1,52 @@ +--TEST-- +dba_insert should correctly handle numeric array-like keys (php_dba_make_key) +--EXTENSIONS-- +dba +--SKIPIF-- + +--FILE-- + +--CLEAN-- + +--EXPECTF-- +Using handler: "%s" +abc +mixed +value +OK \ No newline at end of file