From 98eee90734c4fabf3f3a3d4168576cb6b25ad9b1 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 26 Oct 2017 16:03:42 +0300 Subject: [PATCH] Fixed indirect modification of magic ArrayAccess method arguments --- Zend/tests/bug75420.10.phpt | 21 +++++++++++++ Zend/tests/bug75420.11.phpt | 20 +++++++++++++ Zend/tests/bug75420.12.phpt | 21 +++++++++++++ Zend/tests/bug75420.13.phpt | 20 +++++++++++++ Zend/tests/bug75420.14.phpt | 20 +++++++++++++ Zend/tests/bug75420.15.phpt | 20 +++++++++++++ Zend/tests/bug75420.16.phpt | 20 +++++++++++++ Zend/tests/bug75420.9.phpt | 20 +++++++++++++ Zend/zend_object_handlers.c | 59 ++++++++++++++++++++++--------------- 9 files changed, 198 insertions(+), 23 deletions(-) create mode 100644 Zend/tests/bug75420.10.phpt create mode 100644 Zend/tests/bug75420.11.phpt create mode 100644 Zend/tests/bug75420.12.phpt create mode 100644 Zend/tests/bug75420.13.phpt create mode 100644 Zend/tests/bug75420.14.phpt create mode 100644 Zend/tests/bug75420.15.phpt create mode 100644 Zend/tests/bug75420.16.phpt create mode 100644 Zend/tests/bug75420.9.phpt diff --git a/Zend/tests/bug75420.10.phpt b/Zend/tests/bug75420.10.phpt new file mode 100644 index 0000000000..c2ae3aa55d --- /dev/null +++ b/Zend/tests/bug75420.10.phpt @@ -0,0 +1,21 @@ +--TEST-- +Bug #75420.10 (Indirect modification of magic method argument) +--FILE-- + +--EXPECT-- +string(6) "foofoo" +int(42) +int(24) diff --git a/Zend/tests/bug75420.11.phpt b/Zend/tests/bug75420.11.phpt new file mode 100644 index 0000000000..1ec623e41c --- /dev/null +++ b/Zend/tests/bug75420.11.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #75420.11 (Indirect modification of magic method argument) +--FILE-- + +--EXPECT-- +string(3) "foo" +bool(false) +int(24) diff --git a/Zend/tests/bug75420.12.phpt b/Zend/tests/bug75420.12.phpt new file mode 100644 index 0000000000..7ed6f1474b --- /dev/null +++ b/Zend/tests/bug75420.12.phpt @@ -0,0 +1,21 @@ +--TEST-- +Bug #75420.12 (Indirect modification of magic method argument) +--FILE-- + +--EXPECT-- +string(6) "foofoo" +bool(false) +int(24) diff --git a/Zend/tests/bug75420.13.phpt b/Zend/tests/bug75420.13.phpt new file mode 100644 index 0000000000..38031badd7 --- /dev/null +++ b/Zend/tests/bug75420.13.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #75420.13 (Indirect modification of magic method argument) +--FILE-- + +--EXPECT-- +string(3) "foo" +int(42) +int(24) diff --git a/Zend/tests/bug75420.14.phpt b/Zend/tests/bug75420.14.phpt new file mode 100644 index 0000000000..07fb2cd984 --- /dev/null +++ b/Zend/tests/bug75420.14.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #75420.14 (Indirect modification of magic method argument) +--FILE-- + +--EXPECT-- +string(3) "foo" +bool(false) +int(24) diff --git a/Zend/tests/bug75420.15.phpt b/Zend/tests/bug75420.15.phpt new file mode 100644 index 0000000000..f747b4c887 --- /dev/null +++ b/Zend/tests/bug75420.15.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #75420.15 (Indirect modification of magic method argument) +--FILE-- + +--EXPECT-- +string(6) "foofoo" +int(24) diff --git a/Zend/tests/bug75420.16.phpt b/Zend/tests/bug75420.16.phpt new file mode 100644 index 0000000000..6c3982eacc --- /dev/null +++ b/Zend/tests/bug75420.16.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #75420.16 (Indirect modification of magic method argument) +--FILE-- + +--EXPECT-- +object(Test)#1 (0) { +} +int(24) diff --git a/Zend/tests/bug75420.9.phpt b/Zend/tests/bug75420.9.phpt new file mode 100644 index 0000000000..d83878e773 --- /dev/null +++ b/Zend/tests/bug75420.9.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #75420.9 (Indirect modification of magic method argument) +--FILE-- + +--EXPECT-- +string(3) "foo" +int(42) +int(24) diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 8028b2ee5b..3b86a1a6eb 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -734,34 +734,38 @@ exit: zval *zend_std_read_dimension(zval *object, zval *offset, int type, zval *rv) /* {{{ */ { zend_class_entry *ce = Z_OBJCE_P(object); - zval tmp; + zval tmp_offset, tmp_object; if (EXPECTED(instanceof_function_ex(ce, zend_ce_arrayaccess, 1) != 0)) { if (offset == NULL) { /* [] construct */ - ZVAL_NULL(&tmp); - offset = &tmp; + ZVAL_NULL(&tmp_offset); } else { - SEPARATE_ARG_IF_REF(offset); + ZVAL_DEREF(offset); + ZVAL_COPY(&tmp_offset, offset); } + ZVAL_COPY(&tmp_object, object); if (type == BP_VAR_IS) { - zend_call_method_with_1_params(object, ce, NULL, "offsetexists", rv, offset); + zend_call_method_with_1_params(&tmp_object, ce, NULL, "offsetexists", rv, &tmp_offset); if (UNEXPECTED(Z_ISUNDEF_P(rv))) { - zval_ptr_dtor(offset); + zval_ptr_dtor(&tmp_object); + zval_ptr_dtor(&tmp_offset); return NULL; } if (!i_zend_is_true(rv)) { - zval_ptr_dtor(offset); + zval_ptr_dtor(&tmp_object); + zval_ptr_dtor(&tmp_offset); zval_ptr_dtor(rv); return &EG(uninitialized_zval); } zval_ptr_dtor(rv); } - zend_call_method_with_1_params(object, ce, NULL, "offsetget", rv, offset); + zend_call_method_with_1_params(&tmp_object, ce, NULL, "offsetget", rv, &tmp_offset); - zval_ptr_dtor(offset); + zval_ptr_dtor(&tmp_object); + zval_ptr_dtor(&tmp_offset); if (UNEXPECTED(Z_TYPE_P(rv) == IS_UNDEF)) { if (UNEXPECTED(!EG(exception))) { @@ -780,17 +784,19 @@ zval *zend_std_read_dimension(zval *object, zval *offset, int type, zval *rv) /* static void zend_std_write_dimension(zval *object, zval *offset, zval *value) /* {{{ */ { zend_class_entry *ce = Z_OBJCE_P(object); - zval tmp; + zval tmp_offset, tmp_object; if (EXPECTED(instanceof_function_ex(ce, zend_ce_arrayaccess, 1) != 0)) { if (!offset) { - ZVAL_NULL(&tmp); - offset = &tmp; + ZVAL_NULL(&tmp_offset); } else { - SEPARATE_ARG_IF_REF(offset); + ZVAL_DEREF(offset); + ZVAL_COPY(&tmp_offset, offset); } - zend_call_method_with_2_params(object, ce, NULL, "offsetset", NULL, offset, value); - zval_ptr_dtor(offset); + ZVAL_COPY(&tmp_object, object); + zend_call_method_with_2_params(&tmp_object, ce, NULL, "offsetset", NULL, &tmp_offset, value); + zval_ptr_dtor(&tmp_object); + zval_ptr_dtor(&tmp_offset); } else { zend_throw_error(NULL, "Cannot use object of type %s as array", ZSTR_VAL(ce->name)); } @@ -800,17 +806,19 @@ static void zend_std_write_dimension(zval *object, zval *offset, zval *value) /* static int zend_std_has_dimension(zval *object, zval *offset, int check_empty) /* {{{ */ { zend_class_entry *ce = Z_OBJCE_P(object); - zval retval; + zval retval, tmp_offset, tmp_object; int result; if (EXPECTED(instanceof_function_ex(ce, zend_ce_arrayaccess, 1) != 0)) { - SEPARATE_ARG_IF_REF(offset); - zend_call_method_with_1_params(object, ce, NULL, "offsetexists", &retval, offset); + ZVAL_DEREF(offset); + ZVAL_COPY(&tmp_offset, offset); + ZVAL_COPY(&tmp_object, object); + zend_call_method_with_1_params(&tmp_object, ce, NULL, "offsetexists", &retval, &tmp_offset); if (EXPECTED(Z_TYPE(retval) != IS_UNDEF)) { result = i_zend_is_true(&retval); zval_ptr_dtor(&retval); if (check_empty && result && EXPECTED(!EG(exception))) { - zend_call_method_with_1_params(object, ce, NULL, "offsetget", &retval, offset); + zend_call_method_with_1_params(&tmp_object, ce, NULL, "offsetget", &retval, &tmp_offset); if (EXPECTED(Z_TYPE(retval) != IS_UNDEF)) { result = i_zend_is_true(&retval); zval_ptr_dtor(&retval); @@ -819,7 +827,8 @@ static int zend_std_has_dimension(zval *object, zval *offset, int check_empty) / } else { result = 0; } - zval_ptr_dtor(offset); + zval_ptr_dtor(&tmp_object); + zval_ptr_dtor(&tmp_offset); } else { zend_throw_error(NULL, "Cannot use object of type %s as array", ZSTR_VAL(ce->name)); return 0; @@ -981,11 +990,15 @@ exit: static void zend_std_unset_dimension(zval *object, zval *offset) /* {{{ */ { zend_class_entry *ce = Z_OBJCE_P(object); + zval tmp_offset, tmp_object; if (instanceof_function_ex(ce, zend_ce_arrayaccess, 1)) { - SEPARATE_ARG_IF_REF(offset); - zend_call_method_with_1_params(object, ce, NULL, "offsetunset", NULL, offset); - zval_ptr_dtor(offset); + ZVAL_DEREF(offset); + ZVAL_COPY(&tmp_offset, offset); + ZVAL_COPY(&tmp_object, object); + zend_call_method_with_1_params(&tmp_object, ce, NULL, "offsetunset", NULL, &tmp_offset); + zval_ptr_dtor(&tmp_object); + zval_ptr_dtor(&tmp_offset); } else { zend_throw_error(NULL, "Cannot use object of type %s as array", ZSTR_VAL(ce->name)); } -- 2.40.0