Skip to content

Commit 59c8d6a

Browse files
committed
Merge branch 'PHP-7.3' into PHP-7.4
* PHP-7.3: Fix literal compaction collision between string and double
2 parents c065a58 + 14b770d commit 59c8d6a

File tree

2 files changed

+8
-3
lines changed

2 files changed

+8
-3
lines changed

ext/opcache/Optimizer/compact_literals.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
126126
int l_false = -1;
127127
int l_true = -1;
128128
int l_empty_arr = -1;
129-
HashTable hash;
129+
HashTable hash, double_hash;
130130
zend_string *key = NULL;
131131
void *checkpoint = zend_arena_checkpoint(ctx->arena);
132132
int *const_slot, *class_slot, *func_slot, *bind_var_slot, *property_slot, *method_slot;
@@ -309,6 +309,8 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
309309
/* Merge equal constants */
310310
j = 0;
311311
zend_hash_init(&hash, op_array->last_literal, NULL, NULL, 0);
312+
/* Use separate hashtable for doubles stored as string keys, to avoid collisions. */
313+
zend_hash_init(&double_hash, 0, NULL, NULL, 0);
312314
map = (int*)zend_arena_alloc(&ctx->arena, op_array->last_literal * sizeof(int));
313315
memset(map, 0, op_array->last_literal * sizeof(int));
314316
for (i = 0; i < op_array->last_literal; i++) {
@@ -391,12 +393,12 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
391393
}
392394
break;
393395
case IS_DOUBLE:
394-
if ((pos = zend_hash_str_find(&hash, (char*)&Z_DVAL(op_array->literals[i]), sizeof(double))) != NULL) {
396+
if ((pos = zend_hash_str_find(&double_hash, (char*)&Z_DVAL(op_array->literals[i]), sizeof(double))) != NULL) {
395397
map[i] = Z_LVAL_P(pos);
396398
} else {
397399
map[i] = j;
398400
ZVAL_LONG(&zv, j);
399-
zend_hash_str_add(&hash, (char*)&Z_DVAL(op_array->literals[i]), sizeof(double), &zv);
401+
zend_hash_str_add_new(&double_hash, (char*)&Z_DVAL(op_array->literals[i]), sizeof(double), &zv);
400402
if (i != j) {
401403
op_array->literals[j] = op_array->literals[i];
402404
info[j] = info[i];
@@ -479,7 +481,10 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
479481
break;
480482
}
481483
}
484+
485+
/* Only clean "hash", as it will be reused in the loop below. */
482486
zend_hash_clean(&hash);
487+
zend_hash_destroy(&double_hash);
483488
op_array->last_literal = j;
484489

485490
const_slot = zend_arena_alloc(&ctx->arena, j * 6 * sizeof(int));
252 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)