@@ -12367,6 +12367,56 @@ static int zend_jit_fetch_dim_read(zend_jit_ctx *jit,
12367
12367
}
12368
12368
12369
12369
#ifdef HAVE_FFI
12370
+ static int zend_jit_ffi_abc(zend_jit_ctx *jit,
12371
+ const zend_op *opline,
12372
+ zend_ffi_type *ffi_type,
12373
+ uint32_t op2_info,
12374
+ zend_jit_addr op2_addr,
12375
+ zend_ssa_range *op2_range)
12376
+ {
12377
+ int32_t exit_point;
12378
+ const void *exit_addr;
12379
+
12380
+ ZEND_ASSERT(op2_info == MAY_BE_LONG);
12381
+ if (ffi_type->kind == ZEND_FFI_TYPE_ARRAY
12382
+ && !(ffi_type->attr & (ZEND_FFI_ATTR_VLA|ZEND_FFI_ATTR_INCOMPLETE_ARRAY))) {
12383
+ if (Z_MODE(op2_addr) == IS_CONST_ZVAL) {
12384
+ zval *zv = Z_ZV(op2_addr);
12385
+ ZEND_ASSERT(Z_TYPE_P(zv) == IS_LONG);
12386
+ if (Z_LVAL_P(zv) < 0 || Z_LVAL_P(zv) >= ffi_type->array.length) {
12387
+ /* Always out of range */
12388
+ exit_point = zend_jit_trace_get_exit_point(opline, 0);
12389
+ exit_addr = zend_jit_trace_get_exit_addr(exit_point);
12390
+ if (!exit_addr) {
12391
+ return 0;
12392
+ }
12393
+ jit_SIDE_EXIT(jit, ir_CONST_ADDR(exit_addr));
12394
+ }
12395
+ } else if (!op2_range || op2_range->min < 0 || op2_range->max >= ffi_type->array.length) {
12396
+ if (op2_range->max < 0 || op2_range->min >= ffi_type->array.length) {
12397
+ /* Always out of range */
12398
+ exit_point = zend_jit_trace_get_exit_point(opline, 0);
12399
+ exit_addr = zend_jit_trace_get_exit_addr(exit_point);
12400
+ if (!exit_addr) {
12401
+ return 0;
12402
+ }
12403
+ jit_SIDE_EXIT(jit, ir_CONST_ADDR(exit_addr));
12404
+ } else {
12405
+ /* Array Bounds Check */
12406
+ exit_point = zend_jit_trace_get_exit_point(opline, 0);
12407
+ exit_addr = zend_jit_trace_get_exit_addr(exit_point);
12408
+ if (!exit_addr) {
12409
+ return 0;
12410
+ }
12411
+ ir_GUARD(ir_ULT(jit_Z_LVAL(jit, op2_addr), ir_CONST_LONG(ffi_type->array.length)),
12412
+ ir_CONST_ADDR(exit_addr));
12413
+ }
12414
+ }
12415
+ }
12416
+
12417
+ return 1;
12418
+ }
12419
+
12370
12420
static int zend_jit_ffi_fetch_dim_read(zend_jit_ctx *jit,
12371
12421
const zend_op *opline,
12372
12422
zend_ssa *ssa,
@@ -12386,9 +12436,11 @@ static int zend_jit_ffi_fetch_dim_read(zend_jit_ctx *jit,
12386
12436
12387
12437
// TODO: ce guard ???
12388
12438
// TODO: ffi type guard ???
12389
- if (op1_ffi_type->kind == ZEND_FFI_TYPE_ARRAY) {
12390
- // TODO: array bounds check ???
12439
+
12440
+ if (!zend_jit_ffi_abc(jit, opline, op1_ffi_type, op2_info, op2_addr, op2_range)) {
12441
+ return 0;
12391
12442
}
12443
+
12392
12444
ir_ref obj_ref = jit_Z_PTR(jit, op1_addr);
12393
12445
ir_ref cdata_ref = ir_LOAD_A(ir_ADD_OFFSET(obj_ref, offsetof(zend_ffi_cdata, ptr)));
12394
12446
ir_ref ptr = ir_ADD_A(cdata_ref, ir_MUL_L(jit_Z_LVAL(jit, op2_addr), ir_CONST_LONG(el_type->size)));
@@ -13122,9 +13174,11 @@ static int zend_jit_ffi_assign_dim(zend_jit_ctx *jit,
13122
13174
13123
13175
// TODO: ce guard ???
13124
13176
// TODO: ffi type guard ???
13125
- if (op1_ffi_type->kind == ZEND_FFI_TYPE_ARRAY) {
13126
- // TODO: array bounds check ???
13177
+
13178
+ if (!zend_jit_ffi_abc(jit, opline, op1_ffi_type, op2_info, op2_addr, op2_range)) {
13179
+ return 0;
13127
13180
}
13181
+
13128
13182
ir_ref obj_ref = jit_Z_PTR(jit, op1_addr);
13129
13183
ir_ref cdata_ref = ir_LOAD_A(ir_ADD_OFFSET(obj_ref, offsetof(zend_ffi_cdata, ptr)));
13130
13184
ir_ref ptr = ir_ADD_A(cdata_ref, ir_MUL_L(jit_Z_LVAL(jit, op2_addr), ir_CONST_LONG(el_type->size)));
@@ -13437,9 +13491,11 @@ static int zend_jit_ffi_assign_dim_op(zend_jit_ctx *jit,
13437
13491
13438
13492
// TODO: ce guard ???
13439
13493
// TODO: ffi type guard ???
13440
- if (op1_ffi_type->kind == ZEND_FFI_TYPE_ARRAY) {
13441
- // TODO: array bounds check ???
13494
+
13495
+ if (!zend_jit_ffi_abc(jit, opline, op1_ffi_type, op2_info, op2_addr, op2_range)) {
13496
+ return 0;
13442
13497
}
13498
+
13443
13499
ir_ref obj_ref = jit_Z_PTR(jit, op1_addr);
13444
13500
ir_ref cdata_ref = ir_LOAD_A(ir_ADD_OFFSET(obj_ref, offsetof(zend_ffi_cdata, ptr)));
13445
13501
ir_ref ptr = ir_ADD_A(cdata_ref, ir_MUL_L(jit_Z_LVAL(jit, op2_addr), ir_CONST_LONG(el_type->size)));
0 commit comments