Skip to content

Commit 5584811

Browse files
committed
Simplify zlib dictionary processing
The patch has been contributed by @TimWolla.
1 parent 150599e commit 5584811

File tree

1 file changed

+36
-33
lines changed

1 file changed

+36
-33
lines changed

ext/zlib/zlib.c

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -796,62 +796,65 @@ 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_get_string(cur);
814+
ZEND_ASSERT(string);
815+
if (EG(exception)) {
816+
result = 0;
817+
break;
818+
}
819+
if (ZSTR_LEN(string) == 0) {
820+
result = 0;
821+
zend_argument_value_error(2, "must not contain empty strings");
822+
break;
822823
}
823-
if (zend_str_has_nul_byte(*ptr)) {
824-
do {
825-
zend_string_release(*ptr);
826-
} while (--ptr >= strings);
827-
efree(strings);
824+
if (zend_str_has_nul_byte(string)) {
825+
result = 0;
828826
zend_argument_value_error(2, "must not contain strings with null bytes");
829-
return 0;
827+
break;
830828
}
831829

832-
*dictlen += ZSTR_LEN(*ptr) + 1;
830+
*dictlen += ZSTR_LEN(string) + 1;
831+
strings[total] = string;
832+
total++;
833833
} ZEND_HASH_FOREACH_END();
834834

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);
835+
char *dictptr = emalloc(*dictlen);
836+
*dict = dictptr;
837+
for (size_t i = 0; i < total; i++) {
838+
zend_string *string = strings[i];
839+
dictptr = zend_mempcpy(dictptr, ZSTR_VAL(string), ZSTR_LEN(string));
841840
*dictptr++ = 0;
842-
zend_string_release_ex(*ptr, 0);
843-
} while (++ptr != end);
841+
zend_string_release(string);
842+
}
844843
efree(strings);
844+
if (!result) {
845+
efree(*dict);
846+
*dict = NULL;
847+
}
845848
}
846-
} break;
849+
850+
return result;
851+
}
847852

848853
default:
849854
zend_argument_type_error(2, "must be of type zero-terminated string or array, %s given", zend_zval_value_name(option_buffer));
850855
return 0;
851856
}
852857
}
853-
854-
return 1;
855858
}
856859

857860
/* {{{ Initialize an incremental inflate context with the specified encoding */

0 commit comments

Comments
 (0)