Skip to content

Commit dee5a45

Browse files
committed
Fixed bug #77165
Also add some helper macros for PROTECT/UNPROTECT that check for IMMUTABLE. These checks are needed for nearly any use of PROTECT/UNPROTECT.
1 parent 2a062f3 commit dee5a45

File tree

4 files changed

+27
-4
lines changed

4 files changed

+27
-4
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ PHP NEWS
66
. Fixed bug #77147 (Fixing 60494 ignored ICONV_MIME_DECODE_CONTINUE_ON_ERROR).
77
(cmb)
88

9+
- MBstring:
10+
. Fixed bug #77165 (mb_check_encoding crashes when argument given an empty
11+
array). (Nikita)
12+
913
- SOAP:
1014
. Fixed bug #77141 (Signedness issue in SOAP when precision=-1). (cmb)
1115

Zend/zend_types.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,14 @@ static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) {
570570
GC_DEL_FLAGS(p, GC_PROTECTED); \
571571
} while (0)
572572

573+
#define GC_TRY_PROTECT_RECURSION(p) do { \
574+
if (!(GC_FLAGS(p) & GC_IMMUTABLE)) GC_PROTECT_RECURSION(p); \
575+
} while (0)
576+
577+
#define GC_TRY_UNPROTECT_RECURSION(p) do { \
578+
if (!(GC_FLAGS(p) & GC_IMMUTABLE)) GC_UNPROTECT_RECURSION(p); \
579+
} while (0)
580+
573581
#define Z_IS_RECURSIVE(zval) GC_IS_RECURSIVE(Z_COUNTED(zval))
574582
#define Z_PROTECT_RECURSION(zval) GC_PROTECT_RECURSION(Z_COUNTED(zval))
575583
#define Z_UNPROTECT_RECURSION(zval) GC_UNPROTECT_RECURSION(Z_COUNTED(zval))

ext/mbstring/mbstring.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3125,7 +3125,7 @@ MBSTRING_API HashTable *php_mb_convert_encoding_recursive(HashTable *input, cons
31253125
php_error_docref(NULL, E_WARNING, "Cannot convert recursively referenced values");
31263126
return NULL;
31273127
}
3128-
GC_PROTECT_RECURSION(input);
3128+
GC_TRY_PROTECT_RECURSION(input);
31293129
output = zend_new_array(zend_hash_num_elements(input));
31303130
ZEND_HASH_FOREACH_KEY_VAL(input, idx, key, entry) {
31313131
/* convert key */
@@ -3170,7 +3170,7 @@ MBSTRING_API HashTable *php_mb_convert_encoding_recursive(HashTable *input, cons
31703170
zend_hash_index_add(output, idx, &entry_tmp);
31713171
}
31723172
} ZEND_HASH_FOREACH_END();
3173-
GC_UNPROTECT_RECURSION(input);
3173+
GC_TRY_UNPROTECT_RECURSION(input);
31743174

31753175
return output;
31763176
}
@@ -4738,7 +4738,7 @@ MBSTRING_API int php_mb_check_encoding_recursive(HashTable *vars, const zend_str
47384738
php_error_docref(NULL, E_WARNING, "Cannot not handle circular references");
47394739
return 0;
47404740
}
4741-
GC_PROTECT_RECURSION(vars);
4741+
GC_TRY_PROTECT_RECURSION(vars);
47424742
ZEND_HASH_FOREACH_KEY_VAL(vars, idx, key, entry) {
47434743
ZVAL_DEREF(entry);
47444744
if (key) {
@@ -4772,7 +4772,7 @@ MBSTRING_API int php_mb_check_encoding_recursive(HashTable *vars, const zend_str
47724772
break;
47734773
}
47744774
} ZEND_HASH_FOREACH_END();
4775-
GC_UNPROTECT_RECURSION(vars);
4775+
GC_TRY_UNPROTECT_RECURSION(vars);
47764776
mbfl_buffer_converter_delete(convd);
47774777
return valid;
47784778
}

ext/mbstring/tests/bug77165.phpt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--TEST--
2+
Bug #77165: mb_check_encoding crashes when argument given an empty array
3+
--FILE--
4+
<?php
5+
var_dump(mb_check_encoding(array()));
6+
var_dump(mb_convert_encoding(array(), 'UTF-8'));
7+
?>
8+
--EXPECT--
9+
bool(true)
10+
array(0) {
11+
}

0 commit comments

Comments
 (0)