Skip to content

Commit e794d79

Browse files
committed
JSON string must be always valid UTF-8 string
1 parent 9a27456 commit e794d79

File tree

1 file changed

+13
-5
lines changed

1 file changed

+13
-5
lines changed

src/simdjson_bindings.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@ get_key_with_optional_prefix(simdjson::dom::element &doc, std::string_view json_
5454
return doc.at_pointer(std_pointer);
5555
}
5656

57+
static zend_always_inline zend_string* simdjson_string_init(const char* buf, const size_t len) {
58+
zend_string *str = zend_string_init(buf, len, 0);
59+
#ifdef IS_STR_VALID_UTF8
60+
GC_ADD_FLAGS(str, IS_STR_VALID_UTF8); // JSON string must be always valid UTF-8 string
61+
#endif
62+
return str;
63+
}
64+
5765
static simdjson::error_code
5866
build_parsed_json_cust(simdjson_php_parser* parser, simdjson::dom::element &doc, const char *buf, size_t len, bool realloc_if_needed,
5967
size_t depth = simdjson::DEFAULT_MAX_DEPTH) {
@@ -93,7 +101,7 @@ build_parsed_json_cust(simdjson_php_parser* parser, simdjson::dom::element &doc,
93101
static zend_always_inline void simdjson_set_zval_to_string(zval *v, const char *buf, size_t len) {
94102
/* In php 7.1, the ZSTR_CHAR macro doesn't exist, and CG(one_char_string)[chr] may or may not be null */
95103
#if PHP_VERSION_ID >= 70200
96-
if (len <= 1) {
104+
if (UNEXPECTED(len <= 1)) {
97105
/*
98106
A note on performance benefits of the use of interned strings here and elsewhere:
99107
@@ -111,7 +119,8 @@ static zend_always_inline void simdjson_set_zval_to_string(zval *v, const char *
111119
return;
112120
}
113121
#endif
114-
ZVAL_STRINGL(v, buf, len);
122+
zend_string *str = simdjson_string_init(buf, len);
123+
ZVAL_NEW_STR(v, str);
115124
}
116125

117126
static zend_always_inline void simdjson_add_key_to_symtable(HashTable *ht, const char *buf, size_t len, zval *value) {
@@ -125,7 +134,7 @@ static zend_always_inline void simdjson_add_key_to_symtable(HashTable *ht, const
125134
return;
126135
}
127136
#endif
128-
zend_string *key = zend_string_init(buf, len, 0);
137+
zend_string *key = simdjson_string_init(buf, len);
129138
zend_symtable_update(ht, key, value);
130139
/* Release the reference counted key */
131140
zend_string_release_ex(key, 0);
@@ -208,7 +217,6 @@ static simdjson_php_error_code create_array(simdjson::dom::element element, zval
208217
ZVAL_NULL(return_value);
209218
return error;
210219
}
211-
/* TODO consider using zend_string_init_existing_interned in php 8.1+ to save memory and time freeing strings. */
212220
simdjson_add_key_to_symtable(arr, field.key.data(), field.key.size(), &array_element);
213221
}
214222
break;
@@ -297,7 +305,7 @@ static simdjson_php_error_code create_object(simdjson::dom::element element, zva
297305
if (size <= 1) {
298306
key = size == 1 ? ZSTR_CHAR((unsigned char)data[0]) : ZSTR_EMPTY_ALLOC();
299307
} else {
300-
key = zend_string_init(data, size, 0);
308+
key = simdjson_string_init(data, size);
301309
}
302310
zend_std_write_property(obj, key, &value, NULL);
303311
zend_string_release_ex(key, 0);

0 commit comments

Comments
 (0)