Skip to content

Commit da26266

Browse files
committed
decoder: Add more checks, call destructor directly
1 parent f3b9497 commit da26266

File tree

2 files changed

+23
-3
lines changed

2 files changed

+23
-3
lines changed

src/simdjson_decoder.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ static zend_always_inline Bucket *simdjson_hash_str_find_bucket(const HashTable
213213
while (idx != HT_INVALID_IDX) {
214214
ZEND_ASSERT(idx < HT_IDX_TO_HASH(ht->nTableSize));
215215
p = HT_HASH_TO_BUCKET_EX(arData, idx);
216+
ZEND_ASSERT(p->key != NULL);
216217
if (p->h == h && zend_string_equals_cstr(p->key, str, len)) {
217218
return p;
218219
}
@@ -226,6 +227,7 @@ static zend_always_inline void simdjson_dedup_key_strings_release(HashTable *ht)
226227
Bucket *p = ht->arData;
227228
Bucket *end = p + ht->nNumUsed;
228229
do {
230+
ZEND_ASSERT(!ZSTR_IS_INTERNED(p->key));
229231
if (GC_DELREF(p->key) == 0) {
230232
ZEND_ASSERT(!(GC_FLAGS(p->key) & IS_STR_PERSISTENT));
231233
efree(p->key);
@@ -264,6 +266,7 @@ static zend_always_inline zend_string* simdjson_dedup_key(HashTable *ht, const c
264266
Bucket *p;
265267
zend_string *key;
266268

269+
// Maximum string length that we deduplicate is 64 bytes
267270
if (UNEXPECTED(len > SIMDJSON_MAX_DEDUP_LENGTH)) {
268271
goto init_new_string;
269272
}
@@ -309,10 +312,11 @@ static zend_always_inline void simdjson_hash_str_add_or_update(HashTable *ht, co
309312
zend_ulong h;
310313

311314
// Check if array is initialized with proper flags and size
312-
// This checks are removed in production code
315+
// These checks are removed in production code
313316
ZEND_ASSERT(!(HT_FLAGS(ht) & HASH_FLAG_UNINITIALIZED)); // make sure that hashtable was initialized
314317
ZEND_ASSERT(!(HT_FLAGS(ht) & HASH_FLAG_PACKED)); // make sure that hashtable is not packed
315318
ZEND_ASSERT(ht->nNumUsed < ht->nTableSize); // make sure that we still have space for new elements
319+
ZEND_ASSERT(ht->pDestructor == ZVAL_PTR_DTOR); // make sure that destructor is defined and set to zval_ptr_dtor
316320

317321
// Compute key hash
318322
h = zend_inline_hash_func(str, len);
@@ -322,7 +326,7 @@ static zend_always_inline void simdjson_hash_str_add_or_update(HashTable *ht, co
322326
zval *data;
323327
ZEND_ASSERT(&p->val != pData);
324328
data = &p->val;
325-
ht->pDestructor(data); // destructor is always defined for this array
329+
zval_ptr_dtor(data); // directly call zval_ptr_dtor method
326330
ZVAL_COPY_VALUE(data, pData);
327331
} else {
328332
idx = ht->nNumUsed++;
@@ -488,7 +492,7 @@ static simdjson_php_error_code simdjson_create_object(simdjson::dom::element ele
488492
return simdjson::SUCCESS;
489493
}
490494

491-
zend_array *arr = simdjson_init_packed_array(return_value, json_array.size());
495+
HashTable *arr = simdjson_init_packed_array(return_value, json_array.size());
492496

493497
for (simdjson::dom::element child : json_array) {
494498
zval value;

tests/decode_duplicate_key.phpt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
simdjson_decode keys with the same name
3+
--FILE--
4+
<?php
5+
var_dump(\simdjson_decode('{"ahoj":"svete","ahoj":"kamo"}', false));
6+
var_dump(\simdjson_decode('{"ahoj":"svete","ahoj":"kamo"}', true));
7+
?>
8+
--EXPECTF--
9+
object(stdClass)#1 (1) {
10+
["ahoj"]=>
11+
string(4) "kamo"
12+
}
13+
array(1) {
14+
["ahoj"]=>
15+
string(4) "kamo"
16+
}

0 commit comments

Comments
 (0)