Skip to content

Commit 37ac707

Browse files
committed
Add missing zend_string_release_ex(tmp, 0) and cleanup
- use GC_DELREF() instead of zend_string_release_ex() - add expectations for exceptional cases - replace IS_ARRAY_IMMUTABLE by IS_STR_INTERNED
1 parent df16da3 commit 37ac707

File tree

2 files changed

+18
-12
lines changed

2 files changed

+18
-12
lines changed

Zend/zend_execute.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1540,7 +1540,7 @@ static zend_never_inline void zend_assign_to_string_offset(zval *str, zval *dim,
15401540
s = zend_string_init(Z_STRVAL_P(str), Z_STRLEN_P(str), 0);
15411541
ZSTR_H(s) = ZSTR_H(Z_STR_P(str));
15421542
if (Z_REFCOUNTED_P(str)) {
1543-
zend_string_release_ex(Z_STR_P(str), 0);
1543+
GC_DELREF(Z_STR_P(str));
15441544
}
15451545
ZVAL_NEW_STR(str, s);
15461546
}
@@ -1552,7 +1552,7 @@ static zend_never_inline void zend_assign_to_string_offset(zval *str, zval *dim,
15521552
* Temporarily increase the refcount to detect this situation. */
15531553
GC_ADDREF(s);
15541554
offset = zend_check_string_offset(dim, BP_VAR_W EXECUTE_DATA_CC);
1555-
if (GC_DELREF(s) == 0) {
1555+
if (UNEXPECTED(GC_DELREF(s) == 0)) {
15561556
zend_string_efree(s);
15571557
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
15581558
ZVAL_NULL(EX_VAR(opline->result.var));
@@ -1592,8 +1592,11 @@ static zend_never_inline void zend_assign_to_string_offset(zval *str, zval *dim,
15921592
}
15931593
/* Convert to string, just the time to pick the 1st byte */
15941594
tmp = zval_try_get_string_func(value);
1595-
if (GC_DELREF(s) == 0) {
1595+
if (UNEXPECTED(GC_DELREF(s) == 0)) {
15961596
zend_string_efree(s);
1597+
if (tmp) {
1598+
zend_string_release_ex(tmp, 0);
1599+
}
15971600
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
15981601
ZVAL_NULL(EX_VAR(opline->result.var));
15991602
}
@@ -1628,7 +1631,7 @@ static zend_never_inline void zend_assign_to_string_offset(zval *str, zval *dim,
16281631
* Temporarily increase the refcount to detect this situation. */
16291632
GC_ADDREF(s);
16301633
zend_error(E_WARNING, "Only the first byte will be assigned to the string offset");
1631-
if (GC_DELREF(s) == 0) {
1634+
if (UNEXPECTED(GC_DELREF(s) == 0)) {
16321635
zend_string_efree(s);
16331636
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
16341637
ZVAL_NULL(EX_VAR(opline->result.var));
@@ -2439,11 +2442,11 @@ static zend_always_inline void zend_fetch_dimension_address_read(zval *result, z
24392442
case IS_UNDEF:
24402443
/* The string may be destroyed while throwing the notice.
24412444
* Temporarily increase the refcount to detect this situation. */
2442-
if (!(GC_FLAGS(str) & IS_ARRAY_IMMUTABLE)) {
2445+
if (!(GC_FLAGS(str) & IS_STR_INTERNED)) {
24432446
GC_ADDREF(str);
24442447
}
24452448
ZVAL_UNDEFINED_OP2();
2446-
if (!(GC_FLAGS(str) & IS_ARRAY_IMMUTABLE) && GC_DELREF(str) == 0) {
2449+
if (!(GC_FLAGS(str) & IS_STR_INTERNED) && UNEXPECTED(GC_DELREF(str) == 0)) {
24472450
zend_string_efree(str);
24482451
ZVAL_NULL(result);
24492452
return;
@@ -2455,11 +2458,11 @@ static zend_always_inline void zend_fetch_dimension_address_read(zval *result, z
24552458
if (type != BP_VAR_IS) {
24562459
/* The string may be destroyed while throwing the notice.
24572460
* Temporarily increase the refcount to detect this situation. */
2458-
if (!(GC_FLAGS(str) & IS_ARRAY_IMMUTABLE)) {
2461+
if (!(GC_FLAGS(str) & IS_STR_INTERNED)) {
24592462
GC_ADDREF(str);
24602463
}
24612464
zend_error(E_WARNING, "String offset cast occurred");
2462-
if (!(GC_FLAGS(str) & IS_ARRAY_IMMUTABLE) && GC_DELREF(str) == 0) {
2465+
if (!(GC_FLAGS(str) & IS_STR_INTERNED) && UNEXPECTED(GC_DELREF(str) == 0)) {
24632466
zend_string_efree(str);
24642467
ZVAL_NULL(result);
24652468
return;

ext/opcache/jit/zend_jit_helpers.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1137,7 +1137,7 @@ static zend_never_inline void zend_assign_to_string_offset(zval *str, zval *dim,
11371137
s = zend_string_init(Z_STRVAL_P(str), Z_STRLEN_P(str), 0);
11381138
ZSTR_H(s) = ZSTR_H(Z_STR_P(str));
11391139
if (Z_REFCOUNTED_P(str)) {
1140-
zend_string_release_ex(Z_STR_P(str), 0);
1140+
GC_DELREF(Z_STR_P(str));
11411141
}
11421142
ZVAL_NEW_STR(str, s);
11431143
}
@@ -1147,7 +1147,7 @@ static zend_never_inline void zend_assign_to_string_offset(zval *str, zval *dim,
11471147
* Temporarily increase the refcount to detect this situation. */
11481148
GC_ADDREF(s);
11491149
offset = zend_check_string_offset(dim/*, BP_VAR_W*/);
1150-
if (GC_DELREF(s) == 0) {
1150+
if (UNEXPECTED(GC_DELREF(s) == 0)) {
11511151
zend_string_efree(s);
11521152
if (result) {
11531153
ZVAL_NULL(result);
@@ -1189,8 +1189,11 @@ static zend_never_inline void zend_assign_to_string_offset(zval *str, zval *dim,
11891189
/* Convert to string, just the time to pick the 1st byte */
11901190
tmp = zval_try_get_string_func(value);
11911191

1192-
if (GC_DELREF(s) == 0) {
1192+
if (UNEXPECTED(GC_DELREF(s) == 0)) {
11931193
zend_string_efree(s);
1194+
if (tmp) {
1195+
zend_string_release_ex(tmp, 0);
1196+
}
11941197
if (result) {
11951198
ZVAL_NULL(result);
11961199
}
@@ -1233,7 +1236,7 @@ static zend_never_inline void zend_assign_to_string_offset(zval *str, zval *dim,
12331236
* Temporarily increase the refcount to detect this situation. */
12341237
GC_ADDREF(s);
12351238
zend_error(E_WARNING, "Only the first byte will be assigned to the string offset");
1236-
if (GC_DELREF(s) == 0) {
1239+
if (UNEXPECTED(GC_DELREF(s) == 0)) {
12371240
zend_string_efree(s);
12381241
if (result) {
12391242
ZVAL_NULL(result);

0 commit comments

Comments
 (0)