@@ -2577,13 +2577,13 @@ static void zend_separate_if_call_and_write(znode *node, zend_ast *ast, uint32_t
25772577
25782578void zend_delayed_compile_var (znode * result , zend_ast * ast , uint32_t type );
25792579void zend_compile_assign (znode * result , zend_ast * ast );
2580- static void zend_compile_list_assign (znode * result , zend_ast * ast , znode * expr_node );
2580+ static void zend_compile_list_assign (znode * result , zend_ast * ast , znode * expr_node , zend_bool old_style );
25812581
25822582static inline void zend_emit_assign_znode (zend_ast * var_ast , znode * value_node ) /* {{{ */
25832583{
25842584 znode dummy_node ;
2585- if (var_ast -> kind == ZEND_AST_LIST ) {
2586- zend_compile_list_assign (& dummy_node , var_ast , value_node );
2585+ if (var_ast -> kind == ZEND_AST_ARRAY ) {
2586+ zend_compile_list_assign (& dummy_node , var_ast , value_node , var_ast -> attr );
25872587 } else {
25882588 zend_ast * assign_ast = zend_ast_create (ZEND_AST_ASSIGN , var_ast ,
25892589 zend_ast_create_znode (value_node ));
@@ -2727,18 +2727,35 @@ void zend_compile_static_prop(znode *result, zend_ast *ast, uint32_t type, int d
27272727}
27282728/* }}} */
27292729
2730- static void zend_compile_unkeyed_list_assign (zend_ast_list * list , znode * expr_node ) /* {{{ */
2730+ static void zend_verify_list_assign_target (zend_ast * var_ast , zend_bool old_style ) /* {{{ */ {
2731+ if (var_ast -> kind == ZEND_AST_ARRAY ) {
2732+ if (old_style != var_ast -> attr ) {
2733+ zend_error (E_COMPILE_ERROR , "Cannot mix [] and list()" );
2734+ }
2735+ } else if (!zend_can_write_to_variable (var_ast )) {
2736+ zend_error (E_COMPILE_ERROR , "Assignments can only happen to writable values" );
2737+ }
2738+ }
2739+ /* }}} */
2740+
2741+ static void zend_compile_unkeyed_list_assign (zend_ast_list * list , znode * expr_node , zend_bool old_style ) /* {{{ */
27312742{
27322743 uint32_t i ;
27332744 zend_bool has_elems = 0 ;
27342745
27352746 for (i = 0 ; i < list -> children ; ++ i ) {
2736- zend_ast * var_ast = list -> child [i ];
2747+ zend_ast * elem_ast = list -> child [i ];
2748+ zend_ast * var_ast ;
27372749 znode fetch_result , dim_node ;
27382750
2739- if (var_ast == NULL ) {
2751+ if (elem_ast == NULL ) {
27402752 continue ;
27412753 }
2754+ if (elem_ast -> attr ) {
2755+ zend_error (E_COMPILE_ERROR , "[] and list() assignments cannot be by reference" );
2756+ }
2757+
2758+ var_ast = elem_ast -> child [0 ];
27422759 has_elems = 1 ;
27432760
27442761 dim_node .op_type = IS_CONST ;
@@ -2748,6 +2765,12 @@ static void zend_compile_unkeyed_list_assign(zend_ast_list *list, znode *expr_no
27482765 Z_TRY_ADDREF (expr_node -> u .constant );
27492766 }
27502767
2768+ if (elem_ast -> child [1 ] != NULL ) {
2769+ zend_error (E_COMPILE_ERROR , "Cannot mix keyed and unkeyed array entries in assignments" );
2770+ }
2771+
2772+ zend_verify_list_assign_target (var_ast , old_style );
2773+
27512774 zend_emit_op (& fetch_result , ZEND_FETCH_LIST , expr_node , & dim_node );
27522775 zend_emit_assign_znode (var_ast , & fetch_result );
27532776 }
@@ -2758,7 +2781,7 @@ static void zend_compile_unkeyed_list_assign(zend_ast_list *list, znode *expr_no
27582781}
27592782/* }}} */
27602783
2761- static void zend_compile_keyed_list_assign (zend_ast_list * list , znode * expr_node ) /* {{{ */
2784+ static void zend_compile_keyed_list_assign (zend_ast_list * list , znode * expr_node , zend_bool old_style ) /* {{{ */
27622785{
27632786 uint32_t i ;
27642787
@@ -2768,26 +2791,40 @@ static void zend_compile_keyed_list_assign(zend_ast_list *list, znode *expr_node
27682791 zend_ast * key_ast = pair_ast -> child [1 ];
27692792 znode fetch_result , dim_node ;
27702793
2794+ if (pair_ast -> attr ) {
2795+ zend_error (E_COMPILE_ERROR , "[] and list() assignments cannot be by reference" );
2796+ }
2797+
27712798 zend_compile_expr (& dim_node , key_ast );
27722799
27732800 if (expr_node -> op_type == IS_CONST ) {
27742801 Z_TRY_ADDREF (expr_node -> u .constant );
27752802 }
27762803
2804+ if (var_ast == NULL ) {
2805+ zend_error (E_COMPILE_ERROR , "Cannot use empty array entries in keyed array" );
2806+ }
2807+
2808+ if (key_ast == NULL ) {
2809+ zend_error (E_COMPILE_ERROR , "Cannot mix keyed and unkeyed array entries in assignments" );
2810+ }
2811+
2812+ zend_verify_list_assign_target (var_ast , old_style );
2813+
27772814 zend_emit_op (& fetch_result , ZEND_FETCH_LIST , expr_node , & dim_node );
27782815 zend_emit_assign_znode (var_ast , & fetch_result );
27792816 }
27802817}
27812818/* }}} */
27822819
2783- static void zend_compile_list_assign (znode * result , zend_ast * ast , znode * expr_node ) /* {{{ */
2820+ static void zend_compile_list_assign (znode * result , zend_ast * ast , znode * expr_node , zend_bool old_style ) /* {{{ */
27842821{
27852822 zend_ast_list * list = zend_ast_get_list (ast );
27862823
2787- if (list -> children > 0 && list -> child [0 ] != NULL && list -> child [0 ]-> kind == ZEND_AST_ARRAY_ELEM ) {
2788- zend_compile_keyed_list_assign (list , expr_node );
2824+ if (list -> children > 0 && list -> child [0 ] != NULL && list -> child [0 ]-> child [ 1 ] != NULL /* has key */ ) {
2825+ zend_compile_keyed_list_assign (list , expr_node , old_style );
27892826 } else {
2790- zend_compile_unkeyed_list_assign (list , expr_node );
2827+ zend_compile_unkeyed_list_assign (list , expr_node , old_style );
27912828 }
27922829
27932830 * result = * expr_node ;
@@ -2837,13 +2874,16 @@ zend_bool zend_list_has_assign_to(zend_ast *list_ast, zend_string *name) /* {{{
28372874 zend_ast_list * list = zend_ast_get_list (list_ast );
28382875 uint32_t i ;
28392876 for (i = 0 ; i < list -> children ; i ++ ) {
2840- zend_ast * var_ast = list -> child [i ];
2841- if (!var_ast ) {
2877+ zend_ast * elem_ast = list -> child [i ];
2878+ zend_ast * var_ast ;
2879+
2880+ if (!elem_ast ) {
28422881 continue ;
28432882 }
2883+ var_ast = elem_ast -> child [0 ];
28442884
28452885 /* Recursively check nested list()s */
2846- if (var_ast -> kind == ZEND_AST_LIST && zend_list_has_assign_to (var_ast , name )) {
2886+ if (var_ast -> kind == ZEND_AST_ARRAY && zend_list_has_assign_to (var_ast , name )) {
28472887 return 1 ;
28482888 }
28492889
@@ -2925,15 +2965,15 @@ void zend_compile_assign(znode *result, zend_ast *ast) /* {{{ */
29252965
29262966 zend_emit_op_data (& expr_node );
29272967 return ;
2928- case ZEND_AST_LIST :
2968+ case ZEND_AST_ARRAY :
29292969 if (zend_list_has_assign_to_self (var_ast , expr_ast )) {
29302970 /* list($a, $b) = $a should evaluate the right $a first */
29312971 zend_compile_simple_var_no_cv (& expr_node , expr_ast , BP_VAR_R , 0 );
29322972 } else {
29332973 zend_compile_expr (& expr_node , expr_ast );
29342974 }
29352975
2936- zend_compile_list_assign (result , var_ast , & expr_node );
2976+ zend_compile_list_assign (result , var_ast , & expr_node , var_ast -> attr );
29372977 return ;
29382978 EMPTY_SWITCH_DEFAULT_CASE ();
29392979 }
@@ -4340,7 +4380,7 @@ void zend_compile_foreach(zend_ast *ast) /* {{{ */
43404380 if (key_ast -> kind == ZEND_AST_REF ) {
43414381 zend_error_noreturn (E_COMPILE_ERROR , "Key element cannot be a reference" );
43424382 }
4343- if (key_ast -> kind == ZEND_AST_LIST ) {
4383+ if (key_ast -> kind == ZEND_AST_ARRAY ) {
43444384 zend_error_noreturn (E_COMPILE_ERROR , "Cannot use list as key element" );
43454385 }
43464386 }
@@ -6357,14 +6397,22 @@ static zend_bool zend_try_ct_eval_array(zval *result, zend_ast *ast) /* {{{ */
63576397 uint32_t i ;
63586398 zend_bool is_constant = 1 ;
63596399
6400+ if (ast -> attr ) {
6401+ zend_error (E_COMPILE_ERROR , "Cannot use list() as standalone expression" );
6402+ }
6403+
63606404 /* First ensure that *all* child nodes are constant and by-val */
63616405 for (i = 0 ; i < list -> children ; ++ i ) {
63626406 zend_ast * elem_ast = list -> child [i ];
6363- zend_bool by_ref = elem_ast -> attr ;
6407+
6408+ if (elem_ast == NULL ) {
6409+ zend_error (E_COMPILE_ERROR , "Cannot use empty array elements in arrays" );
6410+ }
6411+
63646412 zend_eval_const_expr (& elem_ast -> child [0 ]);
63656413 zend_eval_const_expr (& elem_ast -> child [1 ]);
63666414
6367- if (by_ref || elem_ast -> child [0 ]-> kind != ZEND_AST_ZVAL
6415+ if (elem_ast -> attr /* by_ref */ || elem_ast -> child [0 ]-> kind != ZEND_AST_ZVAL
63686416 || (elem_ast -> child [1 ] && elem_ast -> child [1 ]-> kind != ZEND_AST_ZVAL )
63696417 ) {
63706418 is_constant = 0 ;
@@ -6982,9 +7030,16 @@ void zend_compile_array(znode *result, zend_ast *ast) /* {{{ */
69827030
69837031 for (i = 0 ; i < list -> children ; ++ i ) {
69847032 zend_ast * elem_ast = list -> child [i ];
6985- zend_ast * value_ast = elem_ast -> child [0 ];
6986- zend_ast * key_ast = elem_ast -> child [1 ];
6987- zend_bool by_ref = elem_ast -> attr ;
7033+ zend_ast * value_ast , * key_ast ;
7034+ zend_bool by_ref ;
7035+
7036+ if (elem_ast == NULL ) {
7037+ zend_error (E_COMPILE_ERROR , "Cannot use empty array elements in arrays" );
7038+ }
7039+
7040+ value_ast = elem_ast -> child [0 ];
7041+ key_ast = elem_ast -> child [1 ];
7042+ by_ref = elem_ast -> attr ;
69887043
69897044 znode value_node , key_node , * key_node_ptr = NULL ;
69907045
0 commit comments