From 91304b8874916e6cb7600f55ad3bc5aaecb01941 Mon Sep 17 00:00:00 2001 From: Anthony Ferrara Date: Tue, 13 Aug 2013 11:51:53 -0400 Subject: [PATCH 1/3] Add support for constant scalar expressions --- Zend/tests/class_properties_dynamic.phpt | 20 ++++++++++ .../tests/constants/constant-expressions.phpt | 37 +++++++++++++++++++ Zend/tests/function_arguments_003.phpt | 14 +++++++ Zend/tests/static_variable.phpt | 20 ++++++++++ Zend/zend_language_parser.y | 18 +++++++++ 5 files changed, 109 insertions(+) create mode 100644 Zend/tests/class_properties_dynamic.phpt create mode 100644 Zend/tests/constants/constant-expressions.phpt create mode 100644 Zend/tests/function_arguments_003.phpt create mode 100644 Zend/tests/static_variable.phpt diff --git a/Zend/tests/class_properties_dynamic.phpt b/Zend/tests/class_properties_dynamic.phpt new file mode 100644 index 0000000000000..bef82e383388a --- /dev/null +++ b/Zend/tests/class_properties_dynamic.phpt @@ -0,0 +1,20 @@ +--TEST-- +Class Property Expressions +--FILE-- +b1, + $f->b2, + $f->b3 +); +?> +--EXPECT-- +int(2) +int(4) +string(13) "foo bar baz" diff --git a/Zend/tests/constants/constant-expressions.phpt b/Zend/tests/constants/constant-expressions.phpt new file mode 100644 index 0000000000000..596ad054d36e3 --- /dev/null +++ b/Zend/tests/constants/constant-expressions.phpt @@ -0,0 +1,37 @@ +--TEST-- +Constant Expressions +--FILE-- + +--EXPECT-- +int(2) +float(0.5) +float(3) +string(6) "foobar" +float(6) +string(6) "foo234" +int(8) +string(21) "This is a test string" +int(0) diff --git a/Zend/tests/function_arguments_003.phpt b/Zend/tests/function_arguments_003.phpt new file mode 100644 index 0000000000000..9e578c8054460 --- /dev/null +++ b/Zend/tests/function_arguments_003.phpt @@ -0,0 +1,14 @@ +--TEST-- +Function Argument Parsing #003 +--FILE-- + +--EXPECT-- +int(2) +int(4) +string(6) "foobar" diff --git a/Zend/tests/static_variable.phpt b/Zend/tests/static_variable.phpt new file mode 100644 index 0000000000000..fb52603790c69 --- /dev/null +++ b/Zend/tests/static_variable.phpt @@ -0,0 +1,20 @@ +--TEST-- +Static Variable Expressions +--FILE-- + +--EXPECT-- +int(2) +array(2) { + [0]=> + int(2) + [1]=> + int(4) +} diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 6a9a24a87ea72..3d0b7f8bc4d75 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -954,6 +954,24 @@ static_scalar: /* compile-time evaluated scalars */ | '[' static_array_pair_list ']' { $$ = $2; Z_TYPE($$.u.constant) = IS_CONSTANT_ARRAY; } | static_class_constant { $$ = $1; } | T_CLASS_C { $$ = $1; } + | '(' static_scalar ')' { $$ = $2; } + | static_operation { $$ = $1; } +; + +static_operation: + static_scalar '+' static_scalar { add_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); $$ = $1; } + | static_scalar '-' static_scalar { sub_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); $$ = $1; } + | static_scalar '*' static_scalar { mul_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); $$ = $1; } + | static_scalar '/' static_scalar { div_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); $$ = $1; } + | static_scalar '%' static_scalar { mod_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); $$ = $1; } + | '!' static_scalar { boolean_not_function(&$2.u.constant, &$2.u.constant TSRMLS_CC); $$ = $2; } + | '~' static_scalar { bitwise_not_function(&$2.u.constant, &$2.u.constant TSRMLS_CC); $$ = $2; } + | static_scalar '|' static_scalar { bitwise_or_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); $$ = $1; } + | static_scalar '&' static_scalar { bitwise_and_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); $$ = $1; } + | static_scalar '^' static_scalar { bitwise_xor_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); $$ = $1; } + | static_scalar T_SL static_scalar { shift_left_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); $$ = $1; } + | static_scalar T_SR static_scalar { shift_right_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); $$ = $1; } + | static_scalar '.' static_scalar { concat_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); zval_dtor(&$3.u.constant); $$ = $1; } ; static_class_constant: From a42c73f9c09aeb881b60552560a9db889e1ccb50 Mon Sep 17 00:00:00 2001 From: Anthony Ferrara Date: Tue, 13 Aug 2013 12:05:26 -0400 Subject: [PATCH 2/3] Fix memory leaks on cast operations --- .../tests/constants/constant-expressions.phpt | 9 +++++++++ Zend/zend_language_parser.y | 20 +++++++++---------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/Zend/tests/constants/constant-expressions.phpt b/Zend/tests/constants/constant-expressions.phpt index 596ad054d36e3..95c8ab9493648 100644 --- a/Zend/tests/constants/constant-expressions.phpt +++ b/Zend/tests/constants/constant-expressions.phpt @@ -14,6 +14,11 @@ This is a test string ENDOFSTRING; const T_9 = ~-1; +// Test order of operations +const T_10 = 1 + 2 * 3; + +// Test for memory leaks +const T_11 = "1" + 2 + "3"; var_dump(T_1); var_dump(T_2); @@ -24,6 +29,8 @@ var_dump(T_6); var_dump(T_7); var_dump(T_8); var_dump(T_9); +var_dump(T_10); +var_dump(T_11); ?> --EXPECT-- int(2) @@ -35,3 +42,5 @@ string(6) "foo234" int(8) string(21) "This is a test string" int(0) +int(7) +int(6) diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 3d0b7f8bc4d75..516a2ccf0f3dd 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -959,18 +959,18 @@ static_scalar: /* compile-time evaluated scalars */ ; static_operation: - static_scalar '+' static_scalar { add_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); $$ = $1; } - | static_scalar '-' static_scalar { sub_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); $$ = $1; } - | static_scalar '*' static_scalar { mul_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); $$ = $1; } - | static_scalar '/' static_scalar { div_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); $$ = $1; } - | static_scalar '%' static_scalar { mod_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); $$ = $1; } + static_scalar '+' static_scalar { add_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); zval_dtor(&$3.u.constant); $$ = $1; } + | static_scalar '-' static_scalar { sub_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); zval_dtor(&$3.u.constant); $$ = $1; } + | static_scalar '*' static_scalar { mul_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); zval_dtor(&$3.u.constant); $$ = $1; } + | static_scalar '/' static_scalar { div_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); zval_dtor(&$3.u.constant); $$ = $1; } + | static_scalar '%' static_scalar { mod_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); zval_dtor(&$3.u.constant); $$ = $1; } | '!' static_scalar { boolean_not_function(&$2.u.constant, &$2.u.constant TSRMLS_CC); $$ = $2; } | '~' static_scalar { bitwise_not_function(&$2.u.constant, &$2.u.constant TSRMLS_CC); $$ = $2; } - | static_scalar '|' static_scalar { bitwise_or_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); $$ = $1; } - | static_scalar '&' static_scalar { bitwise_and_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); $$ = $1; } - | static_scalar '^' static_scalar { bitwise_xor_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); $$ = $1; } - | static_scalar T_SL static_scalar { shift_left_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); $$ = $1; } - | static_scalar T_SR static_scalar { shift_right_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); $$ = $1; } + | static_scalar '|' static_scalar { bitwise_or_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); zval_dtor(&$3.u.constant); $$ = $1; } + | static_scalar '&' static_scalar { bitwise_and_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); zval_dtor(&$3.u.constant); $$ = $1; } + | static_scalar '^' static_scalar { bitwise_xor_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); zval_dtor(&$3.u.constant); $$ = $1; } + | static_scalar T_SL static_scalar { shift_left_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); zval_dtor(&$3.u.constant); $$ = $1; } + | static_scalar T_SR static_scalar { shift_right_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); zval_dtor(&$3.u.constant); $$ = $1; } | static_scalar '.' static_scalar { concat_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); zval_dtor(&$3.u.constant); $$ = $1; } ; From fc932062cbb3f06dffe1cb2807ee60bc3b95d019 Mon Sep 17 00:00:00 2001 From: Anthony Ferrara Date: Tue, 13 Aug 2013 12:58:44 -0400 Subject: [PATCH 3/3] Fix static expressions to not allow constants --- .../class_properties_dynamic-failure.phpt | 12 ++++++ .../constant-expressions-failure.phpt | 9 +++++ Zend/zend_language_parser.y | 38 ++++++++++--------- 3 files changed, 42 insertions(+), 17 deletions(-) create mode 100644 Zend/tests/class_properties_dynamic-failure.phpt create mode 100644 Zend/tests/constants/constant-expressions-failure.phpt diff --git a/Zend/tests/class_properties_dynamic-failure.phpt b/Zend/tests/class_properties_dynamic-failure.phpt new file mode 100644 index 0000000000000..6280efac1d34a --- /dev/null +++ b/Zend/tests/class_properties_dynamic-failure.phpt @@ -0,0 +1,12 @@ +--TEST-- +Class Property Expressions Failure +--FILE-- + +--EXPECTF-- +Parse error: syntax error, unexpected '|', expecting ',' or ';' in %s/class_properties_dynamic-failure.php on line %d diff --git a/Zend/tests/constants/constant-expressions-failure.phpt b/Zend/tests/constants/constant-expressions-failure.phpt new file mode 100644 index 0000000000000..c9716653d61b0 --- /dev/null +++ b/Zend/tests/constants/constant-expressions-failure.phpt @@ -0,0 +1,9 @@ +--TEST-- +Constant Expressions Failure +--FILE-- + +--EXPECTF-- +Parse error: syntax error, unexpected '|', expecting ',' or ';' in %s/constant-expressions-failure.php on line %d diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 516a2ccf0f3dd..d696d25b42e15 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -943,35 +943,39 @@ common_scalar: static_scalar: /* compile-time evaluated scalars */ - common_scalar { $$ = $1; } + static_scalar_value { $$ = $1; } | static_class_name_scalar { $$ = $1; } | namespace_name { zend_do_fetch_constant(&$$, NULL, &$1, ZEND_CT, 1 TSRMLS_CC); } | T_NAMESPACE T_NS_SEPARATOR namespace_name { $$.op_type = IS_CONST; ZVAL_EMPTY_STRING(&$$.u.constant); zend_do_build_namespace_name(&$$, &$$, &$3 TSRMLS_CC); $3 = $$; zend_do_fetch_constant(&$$, NULL, &$3, ZEND_CT, 0 TSRMLS_CC); } | T_NS_SEPARATOR namespace_name { char *tmp = estrndup(Z_STRVAL($2.u.constant), Z_STRLEN($2.u.constant)+1); memcpy(&(tmp[1]), Z_STRVAL($2.u.constant), Z_STRLEN($2.u.constant)+1); tmp[0] = '\\'; efree(Z_STRVAL($2.u.constant)); Z_STRVAL($2.u.constant) = tmp; ++Z_STRLEN($2.u.constant); zend_do_fetch_constant(&$$, NULL, &$2, ZEND_CT, 0 TSRMLS_CC); } - | '+' static_scalar { ZVAL_LONG(&$1.u.constant, 0); add_function(&$2.u.constant, &$1.u.constant, &$2.u.constant TSRMLS_CC); $$ = $2; } - | '-' static_scalar { ZVAL_LONG(&$1.u.constant, 0); sub_function(&$2.u.constant, &$1.u.constant, &$2.u.constant TSRMLS_CC); $$ = $2; } | T_ARRAY '(' static_array_pair_list ')' { $$ = $3; Z_TYPE($$.u.constant) = IS_CONSTANT_ARRAY; } | '[' static_array_pair_list ']' { $$ = $2; Z_TYPE($$.u.constant) = IS_CONSTANT_ARRAY; } | static_class_constant { $$ = $1; } | T_CLASS_C { $$ = $1; } - | '(' static_scalar ')' { $$ = $2; } +; + +static_scalar_value: + common_scalar { $$ = $1; } + | '+' static_scalar_value { ZVAL_LONG(&$1.u.constant, 0); add_function(&$2.u.constant, &$1.u.constant, &$2.u.constant TSRMLS_CC); $$ = $2; } + | '-' static_scalar_value { ZVAL_LONG(&$1.u.constant, 0); sub_function(&$2.u.constant, &$1.u.constant, &$2.u.constant TSRMLS_CC); $$ = $2; } + | '(' static_scalar_value ')' { $$ = $2; } | static_operation { $$ = $1; } ; static_operation: - static_scalar '+' static_scalar { add_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); zval_dtor(&$3.u.constant); $$ = $1; } - | static_scalar '-' static_scalar { sub_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); zval_dtor(&$3.u.constant); $$ = $1; } - | static_scalar '*' static_scalar { mul_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); zval_dtor(&$3.u.constant); $$ = $1; } - | static_scalar '/' static_scalar { div_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); zval_dtor(&$3.u.constant); $$ = $1; } - | static_scalar '%' static_scalar { mod_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); zval_dtor(&$3.u.constant); $$ = $1; } - | '!' static_scalar { boolean_not_function(&$2.u.constant, &$2.u.constant TSRMLS_CC); $$ = $2; } - | '~' static_scalar { bitwise_not_function(&$2.u.constant, &$2.u.constant TSRMLS_CC); $$ = $2; } - | static_scalar '|' static_scalar { bitwise_or_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); zval_dtor(&$3.u.constant); $$ = $1; } - | static_scalar '&' static_scalar { bitwise_and_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); zval_dtor(&$3.u.constant); $$ = $1; } - | static_scalar '^' static_scalar { bitwise_xor_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); zval_dtor(&$3.u.constant); $$ = $1; } - | static_scalar T_SL static_scalar { shift_left_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); zval_dtor(&$3.u.constant); $$ = $1; } - | static_scalar T_SR static_scalar { shift_right_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); zval_dtor(&$3.u.constant); $$ = $1; } - | static_scalar '.' static_scalar { concat_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); zval_dtor(&$3.u.constant); $$ = $1; } + static_scalar_value '+' static_scalar_value { add_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); zval_dtor(&$3.u.constant); $$ = $1; } + | static_scalar_value '-' static_scalar_value { sub_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); zval_dtor(&$3.u.constant); $$ = $1; } + | static_scalar_value '*' static_scalar_value { mul_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); zval_dtor(&$3.u.constant); $$ = $1; } + | static_scalar_value '/' static_scalar_value { div_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); zval_dtor(&$3.u.constant); $$ = $1; } + | static_scalar_value '%' static_scalar_value { mod_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); zval_dtor(&$3.u.constant); $$ = $1; } + | '!' static_scalar_value { boolean_not_function(&$2.u.constant, &$2.u.constant TSRMLS_CC); $$ = $2; } + | '~' static_scalar_value { bitwise_not_function(&$2.u.constant, &$2.u.constant TSRMLS_CC); $$ = $2; } + | static_scalar_value '|' static_scalar_value { bitwise_or_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); zval_dtor(&$3.u.constant); $$ = $1; } + | static_scalar_value '&' static_scalar_value { bitwise_and_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); zval_dtor(&$3.u.constant); $$ = $1; } + | static_scalar_value '^' static_scalar_value { bitwise_xor_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); zval_dtor(&$3.u.constant); $$ = $1; } + | static_scalar_value T_SL static_scalar_value { shift_left_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); zval_dtor(&$3.u.constant); $$ = $1; } + | static_scalar_value T_SR static_scalar_value { shift_right_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); zval_dtor(&$3.u.constant); $$ = $1; } + | static_scalar_value '.' static_scalar_value { concat_function(&$1.u.constant, &$1.u.constant, &$3.u.constant TSRMLS_CC); zval_dtor(&$3.u.constant); $$ = $1; } ; static_class_constant: