Skip to content

Commit b7fd773

Browse files
cmb69TimWolla
andauthored
Refactor zlib dictionary processing (GH-16407)
Co-authored-by: Tim Düsterhus <[email protected]>
1 parent 6d9f040 commit b7fd773

File tree

1 file changed

+34
-33
lines changed

1 file changed

+34
-33
lines changed

ext/zlib/zlib.c

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -796,61 +796,62 @@ static bool zlib_create_dictionary_string(HashTable *options, char **dict, size_
796796
*dict = emalloc(ZSTR_LEN(str));
797797
memcpy(*dict, ZSTR_VAL(str), ZSTR_LEN(str));
798798
*dictlen = ZSTR_LEN(str);
799-
} break;
799+
800+
return 1;
801+
}
800802

801803
case IS_ARRAY: {
802804
HashTable *dictionary = Z_ARR_P(option_buffer);
805+
bool result = 1;
803806

804807
if (zend_hash_num_elements(dictionary) > 0) {
805-
char *dictptr;
806-
zval *cur;
807808
zend_string **strings = safe_emalloc(zend_hash_num_elements(dictionary), sizeof(zend_string *), 0);
808-
zend_string **end, **ptr = strings - 1;
809+
size_t total = 0;
809810

811+
zval *cur;
810812
ZEND_HASH_FOREACH_VAL(dictionary, cur) {
811-
*++ptr = zval_get_string(cur);
812-
ZEND_ASSERT(*ptr);
813-
if (ZSTR_LEN(*ptr) == 0 || EG(exception)) {
814-
do {
815-
zend_string_release(*ptr);
816-
} while (--ptr >= strings);
817-
efree(strings);
818-
if (!EG(exception)) {
819-
zend_argument_value_error(2, "must not contain empty strings");
820-
}
821-
return 0;
813+
zend_string *string = zval_try_get_string(cur);
814+
if (string == NULL) {
815+
result = 0;
816+
break;
817+
}
818+
*dictlen += ZSTR_LEN(string) + 1;
819+
strings[total++] = string;
820+
if (ZSTR_LEN(string) == 0) {
821+
result = 0;
822+
zend_argument_value_error(2, "must not contain empty strings");
823+
break;
822824
}
823-
if (zend_str_has_nul_byte(*ptr)) {
824-
do {
825-
zend_string_release(*ptr);
826-
} while (--ptr >= strings);
827-
efree(strings);
825+
if (zend_str_has_nul_byte(string)) {
826+
result = 0;
828827
zend_argument_value_error(2, "must not contain strings with null bytes");
829-
return 0;
828+
break;
830829
}
831-
832-
*dictlen += ZSTR_LEN(*ptr) + 1;
833830
} ZEND_HASH_FOREACH_END();
834831

835-
dictptr = *dict = emalloc(*dictlen);
836-
ptr = strings;
837-
end = strings + zend_hash_num_elements(dictionary);
838-
do {
839-
memcpy(dictptr, ZSTR_VAL(*ptr), ZSTR_LEN(*ptr));
840-
dictptr += ZSTR_LEN(*ptr);
832+
char *dictptr = emalloc(*dictlen);
833+
*dict = dictptr;
834+
for (size_t i = 0; i < total; i++) {
835+
zend_string *string = strings[i];
836+
dictptr = zend_mempcpy(dictptr, ZSTR_VAL(string), ZSTR_LEN(string));
841837
*dictptr++ = 0;
842-
zend_string_release_ex(*ptr, 0);
843-
} while (++ptr != end);
838+
zend_string_release(string);
839+
}
844840
efree(strings);
841+
if (!result) {
842+
efree(*dict);
843+
*dict = NULL;
844+
}
845845
}
846-
} break;
846+
847+
return result;
848+
}
847849

848850
default:
849851
zend_argument_type_error(2, "must be of type zero-terminated string or array, %s given", zend_zval_value_name(option_buffer));
850852
return 0;
851853
}
852854
}
853-
854855
return 1;
855856
}
856857

0 commit comments

Comments
 (0)