Skip to content

Commit 2d8f9f3

Browse files
committed
Merge branch 'PHP-7.4'
* PHP-7.4: Fix literal compaction collision between string and double
2 parents cdaf350 + 59c8d6a commit 2d8f9f3

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
@@ -132,7 +132,7 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
132132
int l_false = -1;
133133
int l_true = -1;
134134
int l_empty_arr = -1;
135-
HashTable hash;
135+
HashTable hash, double_hash;
136136
zend_string *key = NULL;
137137
void *checkpoint = zend_arena_checkpoint(ctx->arena);
138138
int *const_slot, *class_slot, *func_slot, *bind_var_slot, *property_slot, *method_slot;
@@ -315,6 +315,8 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
315315
/* Merge equal constants */
316316
j = 0;
317317
zend_hash_init(&hash, op_array->last_literal, NULL, NULL, 0);
318+
/* Use separate hashtable for doubles stored as string keys, to avoid collisions. */
319+
zend_hash_init(&double_hash, 0, NULL, NULL, 0);
318320
map = (int*)zend_arena_alloc(&ctx->arena, op_array->last_literal * sizeof(int));
319321
memset(map, 0, op_array->last_literal * sizeof(int));
320322
for (i = 0; i < op_array->last_literal; i++) {
@@ -397,12 +399,12 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
397399
}
398400
break;
399401
case IS_DOUBLE:
400-
if ((pos = zend_hash_str_find(&hash, (char*)&Z_DVAL(op_array->literals[i]), sizeof(double))) != NULL) {
402+
if ((pos = zend_hash_str_find(&double_hash, (char*)&Z_DVAL(op_array->literals[i]), sizeof(double))) != NULL) {
401403
map[i] = Z_LVAL_P(pos);
402404
} else {
403405
map[i] = j;
404406
ZVAL_LONG(&zv, j);
405-
zend_hash_str_add(&hash, (char*)&Z_DVAL(op_array->literals[i]), sizeof(double), &zv);
407+
zend_hash_str_add_new(&double_hash, (char*)&Z_DVAL(op_array->literals[i]), sizeof(double), &zv);
406408
if (i != j) {
407409
op_array->literals[j] = op_array->literals[i];
408410
info[j] = info[i];
@@ -485,7 +487,10 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
485487
break;
486488
}
487489
}
490+
491+
/* Only clean "hash", as it will be reused in the loop below. */
488492
zend_hash_clean(&hash);
493+
zend_hash_destroy(&double_hash);
489494
op_array->last_literal = j;
490495

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

0 commit comments

Comments
 (0)