@@ -690,7 +690,8 @@ static zend_never_inline zend_long zend_check_string_offset(zval *dim/*, int typ
690
690
/* For BC reasons we allow errors so that we can warn on leading numeric string */
691
691
if (IS_LONG == is_numeric_string_ex (Z_STRVAL_P (dim ), Z_STRLEN_P (dim ), & offset , NULL ,
692
692
/* allow errors */ true, NULL , & trailing_data )) {
693
- if (UNEXPECTED (trailing_data ) /*&& type != BP_VAR_UNSET*/ ) {
693
+ if (UNEXPECTED (trailing_data )
694
+ && EG (current_execute_data )-> opline -> opcode != ZEND_FETCH_DIM_UNSET ) {
694
695
zend_error (E_WARNING , "Illegal string offset \"%s\"" , Z_STRVAL_P (dim ));
695
696
}
696
697
return offset ;
@@ -850,6 +851,7 @@ static zend_never_inline ZEND_COLD void zend_wrong_string_offset(void)
850
851
case ZEND_FETCH_DIM_RW :
851
852
case ZEND_FETCH_DIM_FUNC_ARG :
852
853
case ZEND_FETCH_DIM_UNSET :
854
+ case ZEND_FETCH_LIST_W :
853
855
/* TODO: Encode the "reason" into opline->extended_value??? */
854
856
var = opline -> result .var ;
855
857
opline ++ ;
@@ -858,9 +860,21 @@ static zend_never_inline ZEND_COLD void zend_wrong_string_offset(void)
858
860
while (opline < end ) {
859
861
if (opline -> op1_type == IS_VAR && opline -> op1 .var == var ) {
860
862
switch (opline -> opcode ) {
863
+ case ZEND_FETCH_OBJ_W :
864
+ case ZEND_FETCH_OBJ_RW :
865
+ case ZEND_FETCH_OBJ_FUNC_ARG :
866
+ case ZEND_FETCH_OBJ_UNSET :
867
+ case ZEND_ASSIGN_OBJ :
861
868
case ZEND_ASSIGN_OBJ_OP :
869
+ case ZEND_ASSIGN_OBJ_REF :
862
870
msg = "Cannot use string offset as an object" ;
863
871
break ;
872
+ case ZEND_FETCH_DIM_W :
873
+ case ZEND_FETCH_DIM_RW :
874
+ case ZEND_FETCH_DIM_FUNC_ARG :
875
+ case ZEND_FETCH_DIM_UNSET :
876
+ case ZEND_FETCH_LIST_W :
877
+ case ZEND_ASSIGN_DIM :
864
878
case ZEND_ASSIGN_DIM_OP :
865
879
msg = "Cannot use string offset as an array" ;
866
880
break ;
@@ -878,20 +892,6 @@ static zend_never_inline ZEND_COLD void zend_wrong_string_offset(void)
878
892
case ZEND_POST_DEC :
879
893
msg = "Cannot increment/decrement string offsets" ;
880
894
break ;
881
- case ZEND_FETCH_DIM_W :
882
- case ZEND_FETCH_DIM_RW :
883
- case ZEND_FETCH_DIM_FUNC_ARG :
884
- case ZEND_FETCH_DIM_UNSET :
885
- case ZEND_ASSIGN_DIM :
886
- msg = "Cannot use string offset as an array" ;
887
- break ;
888
- case ZEND_FETCH_OBJ_W :
889
- case ZEND_FETCH_OBJ_RW :
890
- case ZEND_FETCH_OBJ_FUNC_ARG :
891
- case ZEND_FETCH_OBJ_UNSET :
892
- case ZEND_ASSIGN_OBJ :
893
- msg = "Cannot use string offset as an object" ;
894
- break ;
895
895
case ZEND_ASSIGN_REF :
896
896
case ZEND_ADD_ARRAY_ELEMENT :
897
897
case ZEND_INIT_ARRAY :
@@ -914,6 +914,9 @@ static zend_never_inline ZEND_COLD void zend_wrong_string_offset(void)
914
914
case ZEND_SEND_FUNC_ARG :
915
915
msg = "Only variables can be passed by reference" ;
916
916
break ;
917
+ case ZEND_FE_RESET_RW :
918
+ msg = "Cannot iterate on string offsets by reference" ;
919
+ break ;
917
920
EMPTY_SWITCH_DEFAULT_CASE ();
918
921
}
919
922
break ;
@@ -1014,6 +1017,75 @@ static zend_never_inline void zend_assign_to_string_offset(zval *str, zval *dim,
1014
1017
}
1015
1018
}
1016
1019
1020
+ static zend_always_inline void ZEND_FASTCALL zend_jit_fetch_dim_obj_helper (zval * object_ptr , zval * dim , zval * result , int type )
1021
+ {
1022
+ zval * retval ;
1023
+
1024
+ if (EXPECTED (Z_TYPE_P (object_ptr ) == IS_OBJECT )) {
1025
+ retval = Z_OBJ_HT_P (object_ptr )-> read_dimension (Z_OBJ_P (object_ptr ), dim , type , result );
1026
+ if (UNEXPECTED (retval == & EG (uninitialized_zval ))) {
1027
+ zend_class_entry * ce = Z_OBJCE_P (object_ptr );
1028
+
1029
+ ZVAL_NULL (result );
1030
+ zend_error (E_NOTICE , "Indirect modification of overloaded element of %s has no effect" , ZSTR_VAL (ce -> name ));
1031
+ } else if (EXPECTED (retval && Z_TYPE_P (retval ) != IS_UNDEF )) {
1032
+ if (!Z_ISREF_P (retval )) {
1033
+ if (result != retval ) {
1034
+ ZVAL_COPY (result , retval );
1035
+ retval = result ;
1036
+ }
1037
+ if (Z_TYPE_P (retval ) != IS_OBJECT ) {
1038
+ zend_class_entry * ce = Z_OBJCE_P (object_ptr );
1039
+ zend_error (E_NOTICE , "Indirect modification of overloaded element of %s has no effect" , ZSTR_VAL (ce -> name ));
1040
+ }
1041
+ } else if (UNEXPECTED (Z_REFCOUNT_P (retval ) == 1 )) {
1042
+ ZVAL_UNREF (retval );
1043
+ }
1044
+ if (result != retval ) {
1045
+ ZVAL_INDIRECT (result , retval );
1046
+ }
1047
+ } else {
1048
+ ZEND_ASSERT (EG (exception ) && "read_dimension() returned NULL without exception" );
1049
+ ZVAL_UNDEF (result );
1050
+ }
1051
+ } else if (EXPECTED (Z_TYPE_P (object_ptr ) == IS_STRING )) {
1052
+ if (!dim ) {
1053
+ zend_throw_error (NULL , "[] operator not supported for strings" );
1054
+ } else {
1055
+ if (UNEXPECTED (Z_TYPE_P (dim ) != IS_LONG )) {
1056
+ zend_check_string_offset (dim /*, BP_VAR_RW*/ );
1057
+ }
1058
+ if (!EG (exception )) {
1059
+ zend_wrong_string_offset ();
1060
+ }
1061
+ }
1062
+ ZVAL_UNDEF (result );
1063
+ } else {
1064
+ if (type == BP_VAR_UNSET ) {
1065
+ zend_throw_error (NULL , "Cannot unset offset in a non-array variable" );
1066
+ ZVAL_UNDEF (result );
1067
+ } else {
1068
+ zend_throw_error (NULL , "Cannot use a scalar value as an array" );
1069
+ ZVAL_UNDEF (result );
1070
+ }
1071
+ }
1072
+ }
1073
+
1074
+ static void ZEND_FASTCALL zend_jit_fetch_dim_obj_w_helper (zval * object_ptr , zval * dim , zval * result )
1075
+ {
1076
+ zend_jit_fetch_dim_obj_helper (object_ptr , dim , result , BP_VAR_W );
1077
+ }
1078
+
1079
+ static void ZEND_FASTCALL zend_jit_fetch_dim_obj_rw_helper (zval * object_ptr , zval * dim , zval * result )
1080
+ {
1081
+ zend_jit_fetch_dim_obj_helper (object_ptr , dim , result , BP_VAR_RW );
1082
+ }
1083
+
1084
+ //static void ZEND_FASTCALL zend_jit_fetch_dim_obj_unset_helper(zval *object_ptr, zval *dim, zval *result)
1085
+ //{
1086
+ // zend_jit_fetch_dim_obj_helper(object_ptr, dim, result, BP_VAR_UNSET);
1087
+ //}
1088
+
1017
1089
static void ZEND_FASTCALL zend_jit_assign_dim_helper (zval * object_ptr , zval * dim , zval * value , zval * result )
1018
1090
{
1019
1091
if (EXPECTED (Z_TYPE_P (object_ptr ) == IS_OBJECT )) {
0 commit comments