From 15846ff115722b2f95d699abf07141d774b0e2cd Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 17 Jun 2020 12:34:04 +0200 Subject: [PATCH 1/8] Add ZVAL_OBJ_COPY macro For the common ZVAL_OBJ + GC_ADDREF pattern. This mirrors the existing ZVAL_STR_COPY API. --- Zend/zend_API.h | 2 + Zend/zend_builtin_functions.c | 3 +- Zend/zend_closures.c | 6 +-- Zend/zend_generators.c | 3 +- Zend/zend_inheritance.c | 3 +- Zend/zend_interfaces.c | 3 +- Zend/zend_types.h | 8 ++++ Zend/zend_weakrefs.c | 12 ++---- ext/date/php_date.c | 43 ++++++++----------- ext/dom/dom_iterators.c | 3 +- ext/dom/php_dom.c | 6 +-- .../breakiterator/breakiterator_iterators.cpp | 3 +- ext/pdo/pdo_dbh.c | 6 +-- ext/phar/phar_object.c | 8 ++-- ext/reflection/php_reflection.c | 33 +++++--------- ext/simplexml/simplexml.c | 9 ++-- ext/soap/soap.c | 6 +-- ext/spl/php_spl.c | 6 +-- ext/spl/spl_array.c | 15 +++---- ext/spl/spl_directory.c | 18 +++----- ext/spl/spl_dllist.c | 3 +- ext/spl/spl_fixedarray.c | 3 +- ext/spl/spl_iterators.c | 3 +- ext/sqlite3/sqlite3.c | 12 ++---- ext/standard/array.c | 3 +- ext/standard/var.c | 6 +-- ext/xml/xml.c | 3 +- 27 files changed, 89 insertions(+), 140 deletions(-) diff --git a/Zend/zend_API.h b/Zend/zend_API.h index 8ed0e20871c7f..bdcdfaea318f4 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -716,6 +716,7 @@ END_EXTERN_C() #define RETVAL_ARR(r) ZVAL_ARR(return_value, r) #define RETVAL_EMPTY_ARRAY() ZVAL_EMPTY_ARRAY(return_value) #define RETVAL_OBJ(r) ZVAL_OBJ(return_value, r) +#define RETVAL_OBJ_COPY(r) ZVAL_OBJ_COPY(return_value, r) #define RETVAL_COPY(zv) ZVAL_COPY(return_value, zv) #define RETVAL_COPY_VALUE(zv) ZVAL_COPY_VALUE(return_value, zv) #define RETVAL_ZVAL(zv, copy, dtor) ZVAL_ZVAL(return_value, zv, copy, dtor) @@ -740,6 +741,7 @@ END_EXTERN_C() #define RETURN_ARR(r) do { RETVAL_ARR(r); return; } while (0) #define RETURN_EMPTY_ARRAY() do { RETVAL_EMPTY_ARRAY(); return; } while (0) #define RETURN_OBJ(r) do { RETVAL_OBJ(r); return; } while (0) +#define RETURN_OBJ_COPY(r) do { RETVAL_OBJ_COPY(r); return; } while (0) #define RETURN_COPY(zv) do { RETVAL_COPY(zv); return; } while (0) #define RETURN_COPY_VALUE(zv) do { RETVAL_COPY_VALUE(zv); return; } while (0) #define RETURN_ZVAL(zv, copy, dtor) do { RETVAL_ZVAL(zv, copy, dtor); return; } while (0) diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 775bab1504a3f..521c2c32de199 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -2069,9 +2069,8 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int } zend_hash_add_new(Z_ARRVAL(stack_frame), ZSTR_KNOWN(ZEND_STR_CLASS), &tmp); if ((options & DEBUG_BACKTRACE_PROVIDE_OBJECT) != 0) { - ZVAL_OBJ(&tmp, object); + ZVAL_OBJ_COPY(&tmp, object); zend_hash_add_new(Z_ARRVAL(stack_frame), ZSTR_KNOWN(ZEND_STR_OBJECT), &tmp); - Z_ADDREF(tmp); } ZVAL_INTERNED_STR(&tmp, ZSTR_KNOWN(ZEND_STR_OBJECT_OPERATOR)); diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index af008c3628fa5..40ebaae0ab74d 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -283,8 +283,7 @@ static int zend_create_closure_from_callable(zval *return_value, zval *callable, /* For Closure::fromCallable([$closure, "__invoke"]) return $closure. */ if (fcc.object && fcc.object->ce == zend_ce_closure && zend_string_equals_literal(mptr->common.function_name, "__invoke")) { - ZVAL_OBJ(return_value, fcc.object); - GC_ADDREF(fcc.object); + RETVAL_OBJ_COPY(fcc.object); zend_free_trampoline(mptr); return SUCCESS; } @@ -725,8 +724,7 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent if (scope) { closure->func.common.fn_flags |= ZEND_ACC_PUBLIC; if (this_ptr && Z_TYPE_P(this_ptr) == IS_OBJECT && (closure->func.common.fn_flags & ZEND_ACC_STATIC) == 0) { - Z_ADDREF_P(this_ptr); - ZVAL_OBJ(&closure->this_ptr, Z_OBJ_P(this_ptr)); + ZVAL_OBJ_COPY(&closure->this_ptr, Z_OBJ_P(this_ptr)); } } } diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index a74ae530b1bbc..803627f9a1d19 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -1120,8 +1120,7 @@ zend_object_iterator *zend_generator_get_iterator(zend_class_entry *ce, zval *ob zend_iterator_init(iterator); iterator->funcs = &zend_generator_iterator_functions; - Z_ADDREF_P(object); - ZVAL_OBJ(&iterator->data, Z_OBJ_P(object)); + ZVAL_OBJ_COPY(&iterator->data, Z_OBJ_P(object)); return iterator; } diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index b6a3a891b23ca..7cee42085bf58 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -2416,8 +2416,7 @@ static void check_unrecoverable_load_failure(zend_class_entry *ce) { zend_string *exception_str; zval exception_zv; ZEND_ASSERT(EG(exception) && "Exception must have been thrown"); - ZVAL_OBJ(&exception_zv, EG(exception)); - Z_ADDREF(exception_zv); + ZVAL_OBJ_COPY(&exception_zv, EG(exception)); zend_clear_exception(); exception_str = zval_get_string(&exception_zv); zend_error_noreturn(E_ERROR, diff --git a/Zend/zend_interfaces.c b/Zend/zend_interfaces.c index 52d3a8ee19e37..6ac2721f453d5 100644 --- a/Zend/zend_interfaces.c +++ b/Zend/zend_interfaces.c @@ -211,8 +211,7 @@ static zend_object_iterator *zend_user_it_get_iterator(zend_class_entry *ce, zva zend_iterator_init((zend_object_iterator*)iterator); - Z_ADDREF_P(object); - ZVAL_OBJ(&iterator->it.data, Z_OBJ_P(object)); + ZVAL_OBJ_COPY(&iterator->it.data, Z_OBJ_P(object)); iterator->it.funcs = &zend_interface_iterator_funcs_iterator; iterator->ce = Z_OBJCE_P(object); ZVAL_UNDEF(&iterator->value); diff --git a/Zend/zend_types.h b/Zend/zend_types.h index 10a751d1b4f2c..7796979ed842f 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -968,6 +968,14 @@ static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) { Z_TYPE_INFO_P(__z) = IS_OBJECT_EX; \ } while (0) +#define ZVAL_OBJ_COPY(z, o) do { \ + zval *__z = (z); \ + zend_object *__o = (o); \ + GC_ADDREF(__o); \ + Z_OBJ_P(__z) = __o; \ + Z_TYPE_INFO_P(__z) = IS_OBJECT_EX; \ + } while (0) + #define ZVAL_RES(z, r) do { \ zval *__z = (z); \ Z_RES_P(__z) = (r); \ diff --git a/Zend/zend_weakrefs.c b/Zend/zend_weakrefs.c index db5ffde2fdcf1..b633a57e9fd5e 100644 --- a/Zend/zend_weakrefs.c +++ b/Zend/zend_weakrefs.c @@ -189,8 +189,7 @@ static zend_always_inline zend_bool zend_weakref_find(zval *referent, zval *retu zend_weakref *wr; found_weakref: wr = ptr; - GC_ADDREF(&wr->std); - ZVAL_OBJ(return_value, &wr->std); + RETVAL_OBJ_COPY(&wr->std); return 1; } @@ -221,8 +220,7 @@ static zend_always_inline void zend_weakref_get(zval *weakref, zval *return_valu zend_weakref *wr = zend_weakref_fetch(weakref); if (wr->referent) { - ZVAL_OBJ(return_value, wr->referent); - Z_ADDREF_P(return_value); + RETVAL_OBJ_COPY(wr->referent); } } @@ -433,8 +431,7 @@ static HashTable *zend_weakmap_get_properties_for(zend_object *object, zend_prop zval obj_zv; array_init(&pair); - ZVAL_OBJ(&obj_zv, (zend_object *) obj_addr); - Z_ADDREF(obj_zv); + ZVAL_OBJ_COPY(&obj_zv, (zend_object *) obj_addr); add_assoc_zval(&pair, "key", &obj_zv); Z_TRY_ADDREF_P(val); add_assoc_zval(&pair, "value", val); @@ -511,8 +508,7 @@ static void zend_weakmap_iterator_get_current_key(zend_object_iterator *obj_iter ZEND_ASSERT(0 && "Must have integer key"); } - ZVAL_OBJ(key, (zend_object *) num_key); - Z_ADDREF_P(key); + ZVAL_OBJ_COPY(key, (zend_object *) num_key); } static void zend_weakmap_iterator_move_forward(zend_object_iterator *obj_iter) diff --git a/ext/date/php_date.c b/ext/date/php_date.c index a908fed2c7a22..94e8ab50c7124 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -1542,8 +1542,7 @@ zend_object_iterator *date_object_period_get_iterator(zend_class_entry *ce, zval zend_iterator_init((zend_object_iterator*)iterator); - Z_ADDREF_P(object); - ZVAL_OBJ(&iterator->intern.data, Z_OBJ_P(object)); + ZVAL_OBJ_COPY(&iterator->intern.data, Z_OBJ_P(object)); iterator->intern.funcs = &date_period_it_funcs; iterator->object = Z_PHPPERIOD_P(object); ZVAL_UNDEF(&iterator->current); @@ -2891,8 +2890,7 @@ PHP_FUNCTION(date_modify) RETURN_FALSE; } - Z_ADDREF_P(object); - ZVAL_OBJ(return_value, Z_OBJ_P(object)); + RETURN_OBJ_COPY(Z_OBJ_P(object)); } /* }}} */ @@ -2915,7 +2913,7 @@ PHP_METHOD(DateTimeImmutable, modify) RETURN_FALSE; } - ZVAL_OBJ(return_value, Z_OBJ(new_object)); + RETURN_OBJ(Z_OBJ(new_object)); } /* }}} */ @@ -2948,8 +2946,7 @@ PHP_FUNCTION(date_add) php_date_add(object, interval, return_value); - Z_ADDREF_P(object); - ZVAL_OBJ(return_value, Z_OBJ_P(object)); + RETURN_OBJ_COPY(Z_OBJ_P(object)); } /* }}} */ @@ -2967,7 +2964,7 @@ PHP_METHOD(DateTimeImmutable, add) date_clone_immutable(object, &new_object); php_date_add(&new_object, interval, return_value); - ZVAL_OBJ(return_value, Z_OBJ(new_object)); + RETURN_OBJ(Z_OBJ(new_object)); } /* }}} */ @@ -3005,8 +3002,7 @@ PHP_FUNCTION(date_sub) php_date_sub(object, interval, return_value); - Z_ADDREF_P(object); - ZVAL_OBJ(return_value, Z_OBJ_P(object)); + RETURN_OBJ_COPY(Z_OBJ_P(object)); } /* }}} */ @@ -3024,7 +3020,7 @@ PHP_METHOD(DateTimeImmutable, sub) date_clone_immutable(object, &new_object); php_date_sub(&new_object, interval, return_value); - ZVAL_OBJ(return_value, Z_OBJ(new_object)); + RETURN_OBJ(Z_OBJ(new_object)); } /* }}} */ @@ -3109,8 +3105,7 @@ PHP_FUNCTION(date_timezone_set) php_date_timezone_set(object, timezone_object, return_value); - Z_ADDREF_P(object); - ZVAL_OBJ(return_value, Z_OBJ_P(object)); + RETURN_OBJ_COPY(Z_OBJ_P(object)); } /* }}} */ @@ -3129,7 +3124,7 @@ PHP_METHOD(DateTimeImmutable, setTimezone) date_clone_immutable(object, &new_object); php_date_timezone_set(&new_object, timezone_object, return_value); - ZVAL_OBJ(return_value, Z_OBJ(new_object)); + RETURN_OBJ(Z_OBJ(new_object)); } /* }}} */ @@ -3196,8 +3191,7 @@ PHP_FUNCTION(date_time_set) php_date_time_set(object, h, i, s, ms, return_value); - Z_ADDREF_P(object); - ZVAL_OBJ(return_value, Z_OBJ_P(object)); + RETURN_OBJ_COPY(Z_OBJ_P(object)); } /* }}} */ @@ -3216,7 +3210,7 @@ PHP_METHOD(DateTimeImmutable, setTime) date_clone_immutable(object, &new_object); php_date_time_set(&new_object, h, i, s, ms, return_value); - ZVAL_OBJ(return_value, Z_OBJ(new_object)); + RETURN_OBJ(Z_OBJ(new_object)); } /* }}} */ @@ -3246,8 +3240,7 @@ PHP_FUNCTION(date_date_set) php_date_date_set(object, y, m, d, return_value); - Z_ADDREF_P(object); - ZVAL_OBJ(return_value, Z_OBJ_P(object)); + RETURN_OBJ_COPY(Z_OBJ_P(object)); } /* }}} */ @@ -3266,7 +3259,7 @@ PHP_METHOD(DateTimeImmutable, setDate) date_clone_immutable(object, &new_object); php_date_date_set(&new_object, y, m, d, return_value); - ZVAL_OBJ(return_value, Z_OBJ(new_object)); + RETURN_OBJ(Z_OBJ(new_object)); } /* }}} */ @@ -3300,8 +3293,7 @@ PHP_FUNCTION(date_isodate_set) php_date_isodate_set(object, y, w, d, return_value); - Z_ADDREF_P(object); - ZVAL_OBJ(return_value, Z_OBJ_P(object)); + RETURN_OBJ_COPY(Z_OBJ_P(object)); } /* }}} */ @@ -3320,7 +3312,7 @@ PHP_METHOD(DateTimeImmutable, setISODate) date_clone_immutable(object, &new_object); php_date_isodate_set(&new_object, y, w, d, return_value); - ZVAL_OBJ(return_value, Z_OBJ(new_object)); + RETURN_OBJ(Z_OBJ(new_object)); } /* }}} */ @@ -3349,8 +3341,7 @@ PHP_FUNCTION(date_timestamp_set) php_date_timestamp_set(object, timestamp, return_value); - Z_ADDREF_P(object); - ZVAL_OBJ(return_value, Z_OBJ_P(object)); + RETURN_OBJ_COPY(Z_OBJ_P(object)); } /* }}} */ @@ -3369,7 +3360,7 @@ PHP_METHOD(DateTimeImmutable, setTimestamp) date_clone_immutable(object, &new_object); php_date_timestamp_set(&new_object, timestamp, return_value); - ZVAL_OBJ(return_value, Z_OBJ(new_object)); + RETURN_OBJ(Z_OBJ(new_object)); } /* }}} */ diff --git a/ext/dom/dom_iterators.c b/ext/dom/dom_iterators.c index bd83114bd9f06..c21cc92154bbb 100644 --- a/ext/dom/dom_iterators.c +++ b/ext/dom/dom_iterators.c @@ -270,8 +270,7 @@ zend_object_iterator *php_dom_get_iterator(zend_class_entry *ce, zval *object, i iterator = emalloc(sizeof(php_dom_iterator)); zend_iterator_init(&iterator->intern); - Z_ADDREF_P(object); - ZVAL_OBJ(&iterator->intern.data, Z_OBJ_P(object)); + ZVAL_OBJ_COPY(&iterator->intern.data, Z_OBJ_P(object)); iterator->intern.funcs = &php_dom_iterator_funcs; ZVAL_UNDEF(&iterator->curobj); diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index 9dc50ac28773d..c90475df1af2d 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -997,8 +997,7 @@ void dom_namednode_iter(dom_object *basenode, int ntype, dom_object *intern, xml ZEND_ASSERT(basenode != NULL); - ZVAL_OBJ(&mapptr->baseobj_zv, &basenode->std); - Z_ADDREF(mapptr->baseobj_zv); + ZVAL_OBJ_COPY(&mapptr->baseobj_zv, &basenode->std); mapptr->baseobj = basenode; mapptr->nodetype = ntype; @@ -1136,8 +1135,7 @@ PHP_DOM_EXPORT zend_bool php_dom_create_object(xmlNodePtr obj, zval *return_valu } if ((intern = (dom_object *) php_dom_object_get_data((void *) obj))) { - GC_ADDREF(&intern->std); - ZVAL_OBJ(return_value, &intern->std); + ZVAL_OBJ_COPY(return_value, &intern->std); return 1; } diff --git a/ext/intl/breakiterator/breakiterator_iterators.cpp b/ext/intl/breakiterator/breakiterator_iterators.cpp index c55d9a2d94b16..7c955a5ecb232 100644 --- a/ext/intl/breakiterator/breakiterator_iterators.cpp +++ b/ext/intl/breakiterator/breakiterator_iterators.cpp @@ -110,8 +110,7 @@ U_CFUNC zend_object_iterator *_breakiterator_get_iterator( zoi_with_current *zoi_iter = static_cast(emalloc(sizeof *zoi_iter)); zend_iterator_init(&zoi_iter->zoi); - Z_ADDREF_P(object); - ZVAL_OBJ(&zoi_iter->zoi.data, Z_OBJ_P(object)); + ZVAL_OBJ_COPY(&zoi_iter->zoi.data, Z_OBJ_P(object)); zoi_iter->zoi.funcs = &breakiterator_iterator_funcs; zoi_iter->zoi.index = 0; zoi_iter->destroy_it = _breakiterator_destroy_it; diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index 769fe25f9d832..e1d8c5b92ca33 100644 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -535,8 +535,7 @@ PHP_METHOD(PDO, prepare) stmt->default_fetch_type = dbh->default_fetch_type; stmt->dbh = dbh; /* give it a reference to me */ - ZVAL_OBJ(&stmt->database_object_handle, &dbh_obj->std); - Z_ADDREF(stmt->database_object_handle); + ZVAL_OBJ_COPY(&stmt->database_object_handle, &dbh_obj->std); /* we haven't created a lazy object yet */ ZVAL_UNDEF(&stmt->lazy_object_ref); @@ -1073,8 +1072,7 @@ PHP_METHOD(PDO, query) stmt->active_query_stringlen = statement_len; stmt->dbh = dbh; /* give it a reference to me */ - ZVAL_OBJ(&stmt->database_object_handle, &dbh_obj->std); - Z_ADDREF(stmt->database_object_handle); + ZVAL_OBJ_COPY(&stmt->database_object_handle, &dbh_obj->std); /* we haven't created a lazy object yet */ ZVAL_UNDEF(&stmt->lazy_object_ref); diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index d273e1d519c22..881ce96cf63be 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -2473,7 +2473,7 @@ PHP_METHOD(Phar, convertToExecutable) phar_obj->archive->is_data = is_data; if (ret) { - ZVAL_OBJ(return_value, ret); + RETURN_OBJ(ret); } else { RETURN_NULL(); } @@ -2576,7 +2576,7 @@ PHP_METHOD(Phar, convertToData) phar_obj->archive->is_data = is_data; if (ret) { - ZVAL_OBJ(return_value, ret); + RETURN_OBJ(ret); } else { RETURN_NULL(); } @@ -3279,7 +3279,7 @@ PHP_METHOD(Phar, compress) } if (ret) { - ZVAL_OBJ(return_value, ret); + RETURN_OBJ(ret); } else { RETURN_NULL(); } @@ -3319,7 +3319,7 @@ PHP_METHOD(Phar, decompress) } if (ret) { - ZVAL_OBJ(return_value, ret); + RETURN_OBJ(ret); } else { RETURN_NULL(); } diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 1f29ff59e4892..0a116a012797b 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -1275,8 +1275,7 @@ static void reflection_parameter_factory(zend_function *fptr, zval *closure_obje intern->ref_type = REF_TYPE_PARAMETER; intern->ce = fptr->common.scope; if (closure_object) { - Z_ADDREF_P(closure_object); - ZVAL_OBJ(&intern->obj, Z_OBJ_P(closure_object)); + ZVAL_OBJ_COPY(&intern->obj, Z_OBJ_P(closure_object)); } prop_name = reflection_prop_name(object); @@ -1343,8 +1342,7 @@ static void reflection_function_factory(zend_function *function, zval *closure_o intern->ref_type = REF_TYPE_FUNCTION; intern->ce = NULL; if (closure_object) { - Z_ADDREF_P(closure_object); - ZVAL_OBJ(&intern->obj, Z_OBJ_P(closure_object)); + ZVAL_OBJ_COPY(&intern->obj, Z_OBJ_P(closure_object)); } ZVAL_STR_COPY(reflection_prop_name(object), function->common.function_name); } @@ -1361,8 +1359,7 @@ static void reflection_method_factory(zend_class_entry *ce, zend_function *metho intern->ref_type = REF_TYPE_FUNCTION; intern->ce = ce; if (closure_object) { - Z_ADDREF_P(closure_object); - ZVAL_OBJ(&intern->obj, Z_OBJ_P(closure_object)); + ZVAL_OBJ_COPY(&intern->obj, Z_OBJ_P(closure_object)); } ZVAL_STR_COPY(reflection_prop_name(object), method->common.function_name); @@ -1490,7 +1487,6 @@ ZEND_METHOD(ReflectionFunction, __construct) if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "O", &closure, zend_ce_closure) == SUCCESS) { fptr = (zend_function*)zend_get_closure_method_def(closure); - Z_ADDREF_P(closure); } else { ALLOCA_FLAG(use_heap) @@ -1521,7 +1517,7 @@ ZEND_METHOD(ReflectionFunction, __construct) intern->ptr = fptr; intern->ref_type = REF_TYPE_FUNCTION; if (closure) { - ZVAL_OBJ(&intern->obj, Z_OBJ_P(closure)); + ZVAL_OBJ_COPY(&intern->obj, Z_OBJ_P(closure)); } else { ZVAL_UNDEF(&intern->obj); } @@ -1591,8 +1587,7 @@ ZEND_METHOD(ReflectionFunctionAbstract, getClosureThis) if (!Z_ISUNDEF(intern->obj)) { closure_this = zend_get_closure_this_ptr(&intern->obj); if (!Z_ISUNDEF_P(closure_this)) { - Z_ADDREF_P(closure_this); - ZVAL_OBJ(return_value, Z_OBJ_P(closure_this)); + RETURN_OBJ_COPY(Z_OBJ_P(closure_this)); } } } @@ -1632,8 +1627,7 @@ ZEND_METHOD(ReflectionFunction, getClosure) if (!Z_ISUNDEF(intern->obj)) { /* Closures are immutable objects */ - Z_ADDREF(intern->obj); - ZVAL_OBJ(return_value, Z_OBJ(intern->obj)); + RETURN_OBJ_COPY(Z_OBJ(intern->obj)); } else { zend_create_fake_closure(return_value, fptr, NULL, NULL, NULL); } @@ -2100,8 +2094,7 @@ ZEND_METHOD(ReflectionGenerator, __construct) } intern->ref_type = REF_TYPE_GENERATOR; - Z_ADDREF_P(generator); - ZVAL_OBJ(&intern->obj, Z_OBJ_P(generator)); + ZVAL_OBJ_COPY(&intern->obj, Z_OBJ_P(generator)); intern->ce = zend_ce_generator; } /* }}} */ @@ -2217,10 +2210,9 @@ ZEND_METHOD(ReflectionGenerator, getThis) REFLECTION_CHECK_VALID_GENERATOR(ex) if (Z_TYPE(ex->This) == IS_OBJECT) { - Z_ADDREF(ex->This); - ZVAL_OBJ(return_value, Z_OBJ(ex->This)); + RETURN_OBJ_COPY(Z_OBJ(ex->This)); } else { - ZVAL_NULL(return_value); + RETURN_NULL(); } } /* }}} */ @@ -2239,9 +2231,7 @@ ZEND_METHOD(ReflectionGenerator, getExecutingGenerator) REFLECTION_CHECK_VALID_GENERATOR(ex) current = zend_generator_get_current(generator); - GC_ADDREF(¤t->std); - - ZVAL_OBJ(return_value, (zend_object *) current); + RETURN_OBJ_COPY(¤t->std); } /* }}} */ @@ -3166,8 +3156,7 @@ ZEND_METHOD(ReflectionMethod, getClosure) if (Z_OBJCE_P(obj) == zend_ce_closure && (mptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) { - Z_ADDREF_P(obj); - ZVAL_OBJ(return_value, Z_OBJ_P(obj)); + RETURN_OBJ_COPY(Z_OBJ_P(obj)); } else { zend_create_fake_closure(return_value, mptr, mptr->common.scope, Z_OBJCE_P(obj), obj); } diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index 85372cb53deea..20e20e3a2b81c 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -2216,7 +2216,7 @@ PHP_FUNCTION(simplexml_load_file) php_libxml_increment_doc_ref((php_libxml_node_object *)sxe, docp); php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, xmlDocGetRootElement(docp), NULL); - ZVAL_OBJ(return_value, &sxe->zo); + RETURN_OBJ(&sxe->zo); } /* }}} */ @@ -2270,7 +2270,7 @@ PHP_FUNCTION(simplexml_load_string) php_libxml_increment_doc_ref((php_libxml_node_object *)sxe, docp); php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, xmlDocGetRootElement(docp), NULL); - ZVAL_OBJ(return_value, &sxe->zo); + RETURN_OBJ(&sxe->zo); } /* }}} */ @@ -2419,8 +2419,7 @@ zend_object_iterator *php_sxe_get_iterator(zend_class_entry *ce, zval *object, i iterator = emalloc(sizeof(php_sxe_iterator)); zend_iterator_init(&iterator->intern); - Z_ADDREF_P(object); - ZVAL_OBJ(&iterator->intern.data, Z_OBJ_P(object)); + ZVAL_OBJ_COPY(&iterator->intern.data, Z_OBJ_P(object)); iterator->intern.funcs = &php_sxe_iterator_funcs; iterator->sxe = Z_SXEOBJ_P(object); @@ -2568,7 +2567,7 @@ PHP_FUNCTION(simplexml_import_dom) php_libxml_increment_doc_ref((php_libxml_node_object *)sxe, nodep->doc); php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, nodep, NULL); - ZVAL_OBJ(return_value, &sxe->zo); + RETURN_OBJ(&sxe->zo); } else { php_error_docref(NULL, E_WARNING, "Invalid Nodetype to import"); RETVAL_NULL(); diff --git a/ext/soap/soap.c b/ext/soap/soap.c index d2ac5ea662701..6356ac73790c1 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -1049,8 +1049,7 @@ PHP_METHOD(SoapServer, setObject) service->type = SOAP_OBJECT; - Z_ADDREF_P(obj); - ZVAL_OBJ(&service->soap_object, Z_OBJ_P(obj)); + ZVAL_OBJ_COPY(&service->soap_object, Z_OBJ_P(obj)); SOAP_SERVER_END_CODE(); } @@ -1760,8 +1759,7 @@ PHP_METHOD(SoapServer, addSoapHeader) *p = emalloc(sizeof(soapHeader)); memset(*p, 0, sizeof(soapHeader)); ZVAL_NULL(&(*p)->function_name); - Z_ADDREF_P(fault); - ZVAL_OBJ(&(*p)->retval, Z_OBJ_P(fault)); + ZVAL_OBJ_COPY(&(*p)->retval, Z_OBJ_P(fault)); SOAP_SERVER_END_CODE(); } diff --git a/ext/spl/php_spl.c b/ext/spl/php_spl.c index ced58ab20d599..e2b361fb5b04e 100644 --- a/ext/spl/php_spl.c +++ b/ext/spl/php_spl.c @@ -609,8 +609,7 @@ PHP_FUNCTION(spl_autoload_functions) ZEND_HASH_FOREACH_PTR(SPL_G(autoload_functions), alfi) { if (alfi->closure) { zval obj_zv; - ZVAL_OBJ(&obj_zv, alfi->closure); - Z_ADDREF(obj_zv); + ZVAL_OBJ_COPY(&obj_zv, alfi->closure); add_next_index_zval(return_value, &obj_zv); } else if (alfi->func_ptr->common.scope) { zval tmp; @@ -618,8 +617,7 @@ PHP_FUNCTION(spl_autoload_functions) array_init(&tmp); if (alfi->obj) { zval obj_zv; - ZVAL_OBJ(&obj_zv, alfi->obj); - Z_ADDREF(obj_zv); + ZVAL_OBJ_COPY(&obj_zv, alfi->obj); add_next_index_zval(&tmp, &obj_zv); } else { add_next_index_str(&tmp, zend_string_copy(alfi->ce->name)); diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index ab263b6195f6c..86a1ad501c288 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -189,13 +189,11 @@ static zend_object *spl_array_object_new_ex(zend_class_entry *class_type, zend_o zend_array_dup(spl_array_get_hash_table(other))); } else { ZEND_ASSERT(orig->handlers == &spl_handler_ArrayIterator); - GC_ADDREF(orig); - ZVAL_OBJ(&intern->array, orig); + ZVAL_OBJ_COPY(&intern->array, orig); intern->ar_flags |= SPL_ARRAY_USE_OTHER; } } else { - GC_ADDREF(orig); - ZVAL_OBJ(&intern->array, orig); + ZVAL_OBJ_COPY(&intern->array, orig); intern->ar_flags |= SPL_ARRAY_USE_OTHER; } } else { @@ -1173,8 +1171,7 @@ zend_object_iterator *spl_array_get_iterator(zend_class_entry *ce, zval *object, zend_iterator_init(&iterator->it); - Z_ADDREF_P(object); - ZVAL_OBJ(&iterator->it.data, Z_OBJ_P(object)); + ZVAL_OBJ_COPY(&iterator->it.data, Z_OBJ_P(object)); iterator->it.funcs = &spl_array_it_funcs; iterator->ce = ce; ZVAL_UNDEF(&iterator->value); @@ -1333,7 +1330,7 @@ PHP_METHOD(ArrayObject, getIterator) RETURN_THROWS(); } - ZVAL_OBJ(return_value, spl_array_object_new_ex(intern->ce_get_iterator, Z_OBJ_P(object), 0)); + RETURN_OBJ(spl_array_object_new_ex(intern->ce_get_iterator, Z_OBJ_P(object), 0)); } /* }}} */ @@ -1652,9 +1649,7 @@ PHP_METHOD(RecursiveArrayIterator, getChildren) return; } if (instanceof_function(Z_OBJCE_P(entry), Z_OBJCE_P(ZEND_THIS))) { - ZVAL_OBJ(return_value, Z_OBJ_P(entry)); - Z_ADDREF_P(return_value); - return; + RETURN_OBJ_COPY(Z_OBJ_P(entry)); } } diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index df33ae6548d8b..f30d7fcf7f78f 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -457,7 +457,7 @@ static spl_filesystem_object *spl_filesystem_object_create_info(spl_filesystem_o zend_update_class_constants(ce); intern = spl_filesystem_from_obj(spl_filesystem_object_new_ex(ce)); - ZVAL_OBJ(return_value, &intern->std); + RETVAL_OBJ(&intern->std); if (ce->constructor->common.scope != spl_ce_SplFileInfo) { ZVAL_STRINGL(&arg1, file_path, file_path_len); @@ -501,7 +501,7 @@ static spl_filesystem_object *spl_filesystem_object_create_type(int num_args, sp } intern = spl_filesystem_from_obj(spl_filesystem_object_new_ex(ce)); - ZVAL_OBJ(return_value, &intern->std); + RETVAL_OBJ(&intern->std); spl_filesystem_object_get_file_name(source); if (ce->constructor->common.scope != spl_ce_SplFileInfo) { @@ -536,7 +536,7 @@ static spl_filesystem_object *spl_filesystem_object_create_type(int num_args, sp intern = spl_filesystem_from_obj(spl_filesystem_object_new_ex(ce)); - ZVAL_OBJ(return_value, &intern->std); + RETVAL_OBJ(&intern->std); spl_filesystem_object_get_file_name(source); @@ -802,8 +802,7 @@ PHP_METHOD(DirectoryIterator, current) if (zend_parse_parameters_none() == FAILURE) { RETURN_THROWS(); } - ZVAL_OBJ(return_value, Z_OBJ_P(ZEND_THIS)); - Z_ADDREF_P(return_value); + RETURN_OBJ_COPY(Z_OBJ_P(ZEND_THIS)); } /* }}} */ @@ -1099,8 +1098,7 @@ PHP_METHOD(FilesystemIterator, current) spl_filesystem_object_get_file_name(intern); spl_filesystem_object_create_type(0, intern, SPL_FS_INFO, NULL, return_value); } else { - ZVAL_OBJ(return_value, Z_OBJ_P(ZEND_THIS)); - Z_ADDREF_P(return_value); + RETURN_OBJ_COPY(Z_OBJ_P(ZEND_THIS)); } } /* }}} */ @@ -1645,8 +1643,7 @@ zend_object_iterator *spl_filesystem_dir_get_iterator(zend_class_entry *ce, zval } dir_object = Z_SPLFILESYSTEM_P(object); iterator = spl_filesystem_object_to_iterator(dir_object); - Z_ADDREF_P(object); - ZVAL_OBJ(&iterator->intern.data, Z_OBJ_P(object)); + ZVAL_OBJ_COPY(&iterator->intern.data, Z_OBJ_P(object)); iterator->intern.funcs = &spl_filesystem_dir_it_funcs; /* ->current must be initialized; rewind doesn't set it and valid * doesn't check whether it's set */ @@ -1847,8 +1844,7 @@ zend_object_iterator *spl_filesystem_tree_get_iterator(zend_class_entry *ce, zva dir_object = Z_SPLFILESYSTEM_P(object); iterator = spl_filesystem_object_to_iterator(dir_object); - Z_ADDREF_P(object); - ZVAL_OBJ(&iterator->intern.data, Z_OBJ_P(object)); + ZVAL_OBJ_COPY(&iterator->intern.data, Z_OBJ_P(object)); iterator->intern.funcs = &spl_filesystem_tree_it_funcs; return &iterator->intern; diff --git a/ext/spl/spl_dllist.c b/ext/spl/spl_dllist.c index 0462c46aa47cf..adf3d354cccd8 100644 --- a/ext/spl/spl_dllist.c +++ b/ext/spl/spl_dllist.c @@ -1351,8 +1351,7 @@ zend_object_iterator *spl_dllist_get_iterator(zend_class_entry *ce, zval *object zend_iterator_init((zend_object_iterator*)iterator); - Z_ADDREF_P(object); - ZVAL_OBJ(&iterator->intern.it.data, Z_OBJ_P(object)); + ZVAL_OBJ_COPY(&iterator->intern.it.data, Z_OBJ_P(object)); iterator->intern.it.funcs = &spl_dllist_it_funcs; iterator->intern.ce = ce; iterator->traverse_position = dllist_object->traverse_position; diff --git a/ext/spl/spl_fixedarray.c b/ext/spl/spl_fixedarray.c index 2b86a85d5155d..63a3ef78fa286 100644 --- a/ext/spl/spl_fixedarray.c +++ b/ext/spl/spl_fixedarray.c @@ -980,8 +980,7 @@ zend_object_iterator *spl_fixedarray_get_iterator(zend_class_entry *ce, zval *ob zend_iterator_init((zend_object_iterator*)iterator); - Z_ADDREF_P(object); - ZVAL_OBJ(&iterator->intern.it.data, Z_OBJ_P(object)); + ZVAL_OBJ_COPY(&iterator->intern.it.data, Z_OBJ_P(object)); iterator->intern.it.funcs = &spl_fixedarray_it_funcs; iterator->intern.ce = ce; ZVAL_UNDEF(&iterator->intern.value); diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index a6ccc855c0ef9..8ddd413cf3d90 100644 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -459,8 +459,7 @@ static zend_object_iterator *spl_recursive_it_get_iterator(zend_class_entry *ce, zend_iterator_init((zend_object_iterator*)iterator); - Z_ADDREF_P(zobject); - ZVAL_OBJ(&iterator->intern.data, Z_OBJ_P(zobject)); + ZVAL_OBJ_COPY(&iterator->intern.data, Z_OBJ_P(zobject)); iterator->intern.funcs = &spl_recursive_it_iterator_funcs; return (zend_object_iterator*)iterator; } diff --git a/ext/sqlite3/sqlite3.c b/ext/sqlite3/sqlite3.c index c309d5d545e05..3102592238da9 100644 --- a/ext/sqlite3/sqlite3.c +++ b/ext/sqlite3/sqlite3.c @@ -534,8 +534,7 @@ PHP_METHOD(SQLite3, prepare) object_init_ex(return_value, php_sqlite3_stmt_entry); stmt_obj = Z_SQLITE3_STMT_P(return_value); stmt_obj->db_obj = db_obj; - Z_ADDREF_P(object); - ZVAL_OBJ(&stmt_obj->db_obj_zval, Z_OBJ_P(object)); + ZVAL_OBJ_COPY(&stmt_obj->db_obj_zval, Z_OBJ_P(object)); errcode = sqlite3_prepare_v2(db_obj->db, ZSTR_VAL(sql), ZSTR_LEN(sql), &(stmt_obj->stmt), NULL); if (errcode != SQLITE_OK) { @@ -590,8 +589,7 @@ PHP_METHOD(SQLite3, query) object_init_ex(&stmt, php_sqlite3_stmt_entry); stmt_obj = Z_SQLITE3_STMT_P(&stmt); stmt_obj->db_obj = db_obj; - Z_ADDREF_P(object); - ZVAL_OBJ(&stmt_obj->db_obj_zval, Z_OBJ_P(object)); + ZVAL_OBJ_COPY(&stmt_obj->db_obj_zval, Z_OBJ_P(object)); return_code = sqlite3_prepare_v2(db_obj->db, ZSTR_VAL(sql), ZSTR_LEN(sql), &(stmt_obj->stmt), NULL); if (return_code != SQLITE_OK) { @@ -1879,8 +1877,7 @@ PHP_METHOD(SQLite3Stmt, execute) result->is_prepared_statement = 1; result->db_obj = stmt_obj->db_obj; result->stmt_obj = stmt_obj; - Z_ADDREF_P(object); - ZVAL_OBJ(&result->stmt_obj_zval, Z_OBJ_P(object)); + ZVAL_OBJ_COPY(&result->stmt_obj_zval, Z_OBJ_P(object)); break; } @@ -1929,8 +1926,7 @@ PHP_METHOD(SQLite3Stmt, __construct) } stmt_obj->db_obj = db_obj; - Z_ADDREF_P(db_zval); - ZVAL_OBJ(&stmt_obj->db_obj_zval, Z_OBJ_P(db_zval)); + ZVAL_OBJ_COPY(&stmt_obj->db_obj_zval, Z_OBJ_P(db_zval)); errcode = sqlite3_prepare_v2(db_obj->db, ZSTR_VAL(sql), ZSTR_LEN(sql), &(stmt_obj->stmt), NULL); if (errcode != SQLITE_OK) { diff --git a/ext/standard/array.c b/ext/standard/array.c index d942cfc184ce4..0a8484f99965c 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -2479,8 +2479,7 @@ static void php_compact_var(HashTable *eg_active_symbol_table, zval *return_valu } else if (zend_string_equals_literal(Z_STR_P(entry), "this")) { zend_object *object = zend_get_this_object(EG(current_execute_data)); if (object) { - GC_ADDREF(object); - ZVAL_OBJ(&data, object); + ZVAL_OBJ_COPY(&data, object); zend_hash_update(Z_ARRVAL_P(return_value), Z_STR_P(entry), &data); } } else { diff --git a/ext/standard/var.c b/ext/standard/var.c index 5b4fd8fe54fd7..4d47e67e2c7d1 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -1001,8 +1001,7 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_ zval *data; zend_ulong index; - Z_ADDREF_P(struc); - ZVAL_OBJ(&obj, Z_OBJ_P(struc)); + ZVAL_OBJ_COPY(&obj, Z_OBJ_P(struc)); if (php_var_serialize_call_magic_serialize(&retval, &obj) == FAILURE) { if (!EG(exception)) { smart_str_appendl(buf, "N;", 2); @@ -1065,8 +1064,7 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_ if (ce != PHP_IC_ENTRY && zend_hash_str_exists(&ce->function_table, "__sleep", sizeof("__sleep")-1)) { zval retval, tmp; - Z_ADDREF_P(struc); - ZVAL_OBJ(&tmp, Z_OBJ_P(struc)); + ZVAL_OBJ_COPY(&tmp, Z_OBJ_P(struc)); if (php_var_serialize_call_sleep(&retval, &tmp) == FAILURE) { if (!EG(exception)) { diff --git a/ext/xml/xml.c b/ext/xml/xml.c index 19d7238c46d61..f626dd1636781 100644 --- a/ext/xml/xml.c +++ b/ext/xml/xml.c @@ -1085,8 +1085,7 @@ PHP_FUNCTION(xml_set_object) parser = Z_XMLPARSER_P(pind); zval_ptr_dtor(&parser->object); - Z_ADDREF_P(mythis); - ZVAL_OBJ(&parser->object, Z_OBJ_P(mythis)); + ZVAL_OBJ_COPY(&parser->object, Z_OBJ_P(mythis)); RETVAL_TRUE; } From 408961987fe585557d759d39bea32d6a02ce0a97 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Wed, 17 Jun 2020 16:45:12 +0200 Subject: [PATCH 2/8] Fix typos --- ext/standard/basic_functions.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 0a429963bd59d..3c2c18db96802 100755 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -757,7 +757,7 @@ PHP_FUNCTION(getenv) /* SAPI method returns an emalloc()'d string */ ptr = sapi_getenv(str, str_len); if (ptr) { - // TODO: avoid realocation ??? + // TODO: avoid reallocation ??? RETVAL_STRING(ptr); efree(ptr); return; @@ -775,7 +775,7 @@ PHP_FUNCTION(getenv) } SetLastError(0); - /*If the given bugger is not large enough to hold the data, the return value is + /*If the given buffer is not large enough to hold the data, the return value is the buffer size, in characters, required to hold the string and its terminating null character. We use this return value to alloc the final buffer. */ size = GetEnvironmentVariableW(keyw, &dummybuf, 0); From 45d1c38dab58bb78ce8ef789716f01bd3057fe5c Mon Sep 17 00:00:00 2001 From: moliata Date: Wed, 17 Jun 2020 17:04:52 +0300 Subject: [PATCH 3/8] Use zend_is_constructor() --- Zend/zend_compile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 062ed8b025916..a34b1d8bea99b 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -5906,7 +5906,7 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32_t fall zend_op_array *op_array = CG(active_op_array); zend_class_entry *scope = op_array->scope; zend_bool is_ctor = - scope && zend_string_equals_literal_ci(op_array->function_name, "__construct"); + scope && zend_is_constructor(op_array->function_name); if (!is_ctor) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare promoted property outside a constructor"); From 3a0bdb720a9e54b91c812665f36b936e6cf44ef3 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Thu, 23 Apr 2020 16:16:58 +0200 Subject: [PATCH 4/8] Fix #63575: Root elements are not properly cloned Cloning of root elements has to preserve that property, so they require some special treatment. --- NEWS | 1 + ext/simplexml/simplexml.c | 22 +++++++++++++++++----- ext/simplexml/tests/bug39662.phpt | 6 ++++-- ext/simplexml/tests/bug63575.phpt | 24 ++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 7 deletions(-) create mode 100644 ext/simplexml/tests/bug63575.phpt diff --git a/NEWS b/NEWS index db10e1be45470..3732e9946db84 100644 --- a/NEWS +++ b/NEWS @@ -154,6 +154,7 @@ PHP NEWS - SimpleXML: . Fixed bug #75245 (Don't set content of elements with only whitespaces). (eriklundin) + . Fixed bug #63575 (Root elements are not properly cloned). (cmb) - sodium: . Fixed bug #77646 (sign_detached() strings not terminated). (Frank) diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index 20e20e3a2b81c..8d8a47f73ebba 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -2035,12 +2035,20 @@ sxe_object_clone(zend_object *object) php_sxe_object *clone; xmlNodePtr nodep = NULL; xmlDocPtr docp = NULL; + zend_bool is_root_element = sxe->node && sxe->node->node && sxe->node->node->parent + && (sxe->node->node->parent->type == XML_DOCUMENT_NODE || sxe->node->node->parent->type == XML_HTML_DOCUMENT_NODE); clone = php_sxe_object_new(sxe->zo.ce, sxe->fptr_count); - clone->document = sxe->document; - if (clone->document) { - clone->document->refcount++; - docp = clone->document->ptr; + + if (is_root_element) { + docp = xmlCopyDoc(sxe->document->ptr, 1); + php_libxml_increment_doc_ref((php_libxml_node_object *)clone, docp); + } else { + clone->document = sxe->document; + if (clone->document) { + clone->document->refcount++; + docp = clone->document->ptr; + } } clone->iter.isprefix = sxe->iter.isprefix; @@ -2053,7 +2061,11 @@ sxe_object_clone(zend_object *object) clone->iter.type = sxe->iter.type; if (sxe->node) { - nodep = xmlDocCopyNode(sxe->node->node, docp, 1); + if (is_root_element) { + nodep = xmlDocGetRootElement(docp); + } else { + nodep = xmlDocCopyNode(sxe->node->node, docp, 1); + } } php_libxml_increment_node_ptr((php_libxml_node_object *)clone, nodep, NULL); diff --git a/ext/simplexml/tests/bug39662.phpt b/ext/simplexml/tests/bug39662.phpt index 5dc2b99a92481..343aeef7036fd 100644 --- a/ext/simplexml/tests/bug39662.phpt +++ b/ext/simplexml/tests/bug39662.phpt @@ -23,7 +23,9 @@ object(SimpleXMLElement)#%d (0) { } object(SimpleXMLElement)#%d (0) { } -string(15) " +string(%d) " + -" + +" Done diff --git a/ext/simplexml/tests/bug63575.phpt b/ext/simplexml/tests/bug63575.phpt new file mode 100644 index 0000000000000..0947ea677de03 --- /dev/null +++ b/ext/simplexml/tests/bug63575.phpt @@ -0,0 +1,24 @@ +--TEST-- +Bug #63575 (Root elements are not properly cloned) +--SKIPIF-- + +--FILE-- +'; + +$o1 = new SimpleXMlElement($xml); +$o2 = clone $o1; + +$r = current($o2->xpath('/a')); +$r->addChild('c', new SimpleXMlElement('')); + +echo $o1->asXML(), PHP_EOL, $o2->asXML(); +?> +--EXPECT-- + + + + + From 1efaed7cf7f112fa9c5920626084e8a36b6af781 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Wed, 17 Jun 2020 16:40:46 +0200 Subject: [PATCH 5/8] Improve error messages of ext/zlib --- ext/zlib/tests/deflate_add_error.phpt | 4 ++-- ext/zlib/tests/deflate_init_error.phpt | 10 +++++----- ext/zlib/tests/dictionary_usage.phpt | 1 - ext/zlib/tests/inflate_add_error.phpt | 4 ++-- ext/zlib/zlib.c | 17 ++++++++--------- 5 files changed, 17 insertions(+), 19 deletions(-) diff --git a/ext/zlib/tests/deflate_add_error.phpt b/ext/zlib/tests/deflate_add_error.phpt index b2b7d7917c0f0..4a467d39bfe98 100644 --- a/ext/zlib/tests/deflate_add_error.phpt +++ b/ext/zlib/tests/deflate_add_error.phpt @@ -27,5 +27,5 @@ try { ?> --EXPECT-- -deflate_add(): supplied resource is not a valid zlib deflate resource -Flush mode must be ZLIB_NO_FLUSH, ZLIB_PARTIAL_FLUSH, ZLIB_SYNC_FLUSH, ZLIB_FULL_FLUSH, ZLIB_BLOCK or ZLIB_FINISH +deflate_add(): Argument #1 ($context) must be of type DeflateContext, resource given +deflate_add(): Argument #3 ($flush_behavior) must be one of ZLIB_NO_FLUSH, ZLIB_PARTIAL_FLUSH, ZLIB_SYNC_FLUSH, ZLIB_FULL_FLUSH, ZLIB_BLOCK, or ZLIB_FINISH diff --git a/ext/zlib/tests/deflate_init_error.phpt b/ext/zlib/tests/deflate_init_error.phpt index be3f0974d6526..b31a16be9accf 100644 --- a/ext/zlib/tests/deflate_init_error.phpt +++ b/ext/zlib/tests/deflate_init_error.phpt @@ -41,8 +41,8 @@ try { ?> --EXPECT-- -Encoding mode must be ZLIB_ENCODING_RAW, ZLIB_ENCODING_GZIP or ZLIB_ENCODING_DEFLATE -Compression level (42) must be within -1..9 -Compression level (-2) must be within -1..9 -Compression memory level (0) must be within 1..9 -Compression memory level (10) must be within 1..9 +deflate_init(): Argument #1 ($encoding) must be either ZLIB_ENCODING_RAW, ZLIB_ENCODING_GZIP, or ZLIB_ENCODING_DEFLATE +deflate_init(): "level" option must be between -1 and 9 +deflate_init(): "level" option must be between -1 and 9 +deflate_init(): "memory" option must be between 1 and 9 +deflate_init(): "memory" option must be between 1 and 9 diff --git a/ext/zlib/tests/dictionary_usage.phpt b/ext/zlib/tests/dictionary_usage.phpt index 195e9b216d5ac..359cfd3550eb4 100644 --- a/ext/zlib/tests/dictionary_usage.phpt +++ b/ext/zlib/tests/dictionary_usage.phpt @@ -18,7 +18,6 @@ var_dump($dictStr_a === $a); $r = inflate_init(ZLIB_ENCODING_DEFLATE, ["dictionary" => $dict]); var_dump(inflate_add($r, $a, ZLIB_FINISH)); - $r = inflate_init(ZLIB_ENCODING_DEFLATE, ["dictionary" => ["8"] + range("a", "z")]); var_dump(inflate_add($r, $a, ZLIB_FINISH)); diff --git a/ext/zlib/tests/inflate_add_error.phpt b/ext/zlib/tests/inflate_add_error.phpt index 9622e5a4c40b8..33792197523cd 100644 --- a/ext/zlib/tests/inflate_add_error.phpt +++ b/ext/zlib/tests/inflate_add_error.phpt @@ -26,5 +26,5 @@ try { ?> --EXPECT-- -inflate_add(): supplied resource is not a valid zlib inflate resource -Flush mode must be ZLIB_NO_FLUSH, ZLIB_PARTIAL_FLUSH, ZLIB_SYNC_FLUSH, ZLIB_FULL_FLUSH, ZLIB_BLOCK or ZLIB_FINISH +inflate_add(): Argument #1 ($context) must be of type InflateContext, resource given +inflate_add(): Argument #3 ($flush_mode) must be one of ZLIB_NO_FLUSH, ZLIB_PARTIAL_FLUSH, ZLIB_SYNC_FLUSH, ZLIB_FULL_FLUSH, ZLIB_BLOCK, or ZLIB_FINISH diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c index ae65ba439624b..11753b0f83965 100644 --- a/ext/zlib/zlib.c +++ b/ext/zlib/zlib.c @@ -786,7 +786,7 @@ static zend_bool zlib_create_dictionary_string(HashTable *options, char **dict, } efree(strings); if (!EG(exception)) { - zend_value_error("Dictionary entries must be non-empty strings"); + zend_argument_value_error(2, "must not contain empty strings"); } return 0; } @@ -796,7 +796,7 @@ static zend_bool zlib_create_dictionary_string(HashTable *options, char **dict, efree(ptr); } while (--ptr >= strings); efree(strings); - zend_value_error("Dictionary entries must not contain a NULL-byte"); + zend_argument_value_error(2, "must not contain strings with null bytes"); return 0; } } @@ -1077,7 +1077,7 @@ PHP_FUNCTION(deflate_init) level = zval_get_long(option_buffer); } if (level < -1 || level > 9) { - zend_value_error("Compression level (" ZEND_LONG_FMT ") must be within -1..9", level); + zend_value_error("deflate_init(): \"level\" option must be between -1 and 9"); RETURN_THROWS(); } @@ -1085,7 +1085,7 @@ PHP_FUNCTION(deflate_init) memory = zval_get_long(option_buffer); } if (memory < 1 || memory > 9) { - zend_value_error("Compression memory level (" ZEND_LONG_FMT ") must be within 1..9", memory); + zend_value_error("deflate_init(): \"memory\" option must be between 1 and 9"); RETURN_THROWS(); } @@ -1093,7 +1093,7 @@ PHP_FUNCTION(deflate_init) window = zval_get_long(option_buffer); } if (window < 8 || window > 15) { - zend_value_error("zlib window size (logarithm) (" ZEND_LONG_FMT ") must be within 8..15", window); + zend_value_error("deflate_init(): \"window\" option must be between 8 and 15"); RETURN_THROWS(); } @@ -1108,7 +1108,7 @@ PHP_FUNCTION(deflate_init) case Z_DEFAULT_STRATEGY: break; default: - zend_value_error("Strategy must be one of ZLIB_FILTERED, ZLIB_HUFFMAN_ONLY, ZLIB_RLE, ZLIB_FIXED or ZLIB_DEFAULT_STRATEGY"); + zend_value_error("deflate_init(): \"strategy\" option must be one of ZLIB_FILTERED, ZLIB_HUFFMAN_ONLY, ZLIB_RLE, ZLIB_FIXED or ZLIB_DEFAULT_STRATEGY"); RETURN_THROWS(); } @@ -1122,7 +1122,7 @@ PHP_FUNCTION(deflate_init) case PHP_ZLIB_ENCODING_DEFLATE: break; default: - zend_value_error("Encoding mode must be ZLIB_ENCODING_RAW, ZLIB_ENCODING_GZIP or ZLIB_ENCODING_DEFLATE"); + zend_argument_value_error(1, "must be either ZLIB_ENCODING_RAW, ZLIB_ENCODING_GZIP, or ZLIB_ENCODING_DEFLATE"); RETURN_THROWS(); } @@ -1186,8 +1186,7 @@ PHP_FUNCTION(deflate_add) break; default: - zend_value_error( - "Flush mode must be ZLIB_NO_FLUSH, ZLIB_PARTIAL_FLUSH, ZLIB_SYNC_FLUSH, ZLIB_FULL_FLUSH, ZLIB_BLOCK or ZLIB_FINISH"); + zend_argument_value_error(3, "must be one of ZLIB_NO_FLUSH, ZLIB_PARTIAL_FLUSH, ZLIB_SYNC_FLUSH, ZLIB_FULL_FLUSH, ZLIB_BLOCK, or ZLIB_FINISH"); RETURN_THROWS(); } From 314eedbc35116d61e97978f5fc822dfecd14053d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Wed, 17 Jun 2020 16:45:57 +0200 Subject: [PATCH 6/8] Convert resources to objects in ext/zlib Closes GH-5680 --- UPGRADING | 8 +- ext/zlib/php_zlib.h | 1 + ext/zlib/zlib.c | 340 ++++++++++++++++++++++++---------------- ext/zlib/zlib.stub.php | 26 +-- ext/zlib/zlib_arginfo.h | 23 ++- 5 files changed, 241 insertions(+), 157 deletions(-) diff --git a/UPGRADING b/UPGRADING index 794b91f9432f0..b7670f813be97 100644 --- a/UPGRADING +++ b/UPGRADING @@ -440,7 +440,7 @@ PHP 8.0 UPGRADE NOTES - Sysvmsg: . msg_get_queue() will now return an SysvMessageQueue object rather than a - resource. Return value checks using is_resource() should be replaced with + resource. Return value checks using is_resource() should be replaced with checks for `false`. - Sysvsem: @@ -474,6 +474,12 @@ PHP 8.0 UPGRADE NOTES - Zlib: . gzgetss() has been removed. + . inflate_init() will now return an InflateContext object rather than a + resource. Return value checks using is_resource() should be replaced with + checks for `false`. + . deflate_init() will now return a DeflateContext object rather than a + resource. Return value checks using is_resource() should be replaced with + checks for `false`. ======================================== 2. New Features diff --git a/ext/zlib/php_zlib.h b/ext/zlib/php_zlib.h index b8f25015aecf5..6c43625217bc8 100644 --- a/ext/zlib/php_zlib.h +++ b/ext/zlib/php_zlib.h @@ -47,6 +47,7 @@ typedef struct _php_zlib_context { int status; size_t inflateDictlen; php_zlib_buffer buffer; + zend_object std; } php_zlib_context; ZEND_BEGIN_MODULE_GLOBALS(zlib) diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c index 11753b0f83965..aa3be3a513926 100644 --- a/ext/zlib/zlib.c +++ b/ext/zlib/zlib.c @@ -29,12 +29,13 @@ #include "ext/standard/php_string.h" #include "php_zlib.h" #include "zlib_arginfo.h" +#include "Zend/zend_interfaces.h" /* * zlib include files can define the following preprocessor defines which rename * the corresponding PHP functions to gzopen64, gzseek64 and gztell64 and thereby * breaking some software, most notably PEAR's Archive_Tar, which halts execution - * without error message on gzip compressed archivesa. + * without error message on gzip compressed archives. * * This only seems to happen on 32bit systems with large file support. */ @@ -42,45 +43,94 @@ #undef gzseek #undef gztell -int le_deflate; -#define le_deflate_name "zlib deflate" -int le_inflate; -#define le_inflate_name "zlib inflate" - ZEND_DECLARE_MODULE_GLOBALS(zlib) -/* {{{ Memory management wrappers */ +/* InflateContext class */ -static voidpf php_zlib_alloc(voidpf opaque, uInt items, uInt size) -{ - return (voidpf)safe_emalloc(items, size, 0); +zend_class_entry *inflate_context_ce; +static zend_object_handlers inflate_context_object_handlers; + +static inline php_zlib_context *inflate_context_from_obj(zend_object *obj) { + return (php_zlib_context *)((char *)(obj) - XtOffsetOf(php_zlib_context, std)); } -static void php_zlib_free(voidpf opaque, voidpf address) +#define Z_INFLATE_CONTEXT_P(zv) inflate_context_from_obj(Z_OBJ_P(zv)) + +static zend_object *inflate_context_create_object(zend_class_entry *class_type) { + php_zlib_context *intern = zend_object_alloc(sizeof(php_zlib_context), class_type); + + zend_object_std_init(&intern->std, class_type); + object_properties_init(&intern->std, class_type); + intern->std.handlers = &inflate_context_object_handlers; + + return &intern->std; +} + +static zend_function *inflate_context_get_constructor(zend_object *object) { + zend_throw_error(NULL, "Cannot directly construct InflateContext, use inflate_init() instead"); + return NULL; +} + +static void inflate_context_free_obj(zend_object *object) { - efree((void*)address); + php_zlib_context *intern = inflate_context_from_obj(object); + + if (intern->inflateDict) { + efree(intern->inflateDict); + } + inflateEnd(&intern->Z); + + zend_object_std_dtor(&intern->std); } /* }}} */ -/* {{{ Incremental deflate/inflate resource destructors */ +/* DeflateContext class */ + +zend_class_entry *deflate_context_ce; +static zend_object_handlers deflate_context_object_handlers; + +static inline php_zlib_context *deflate_context_from_obj(zend_object *obj) { + return (php_zlib_context *)((char *)(obj) - XtOffsetOf(php_zlib_context, std)); +} + +#define Z_DEFLATE_CONTEXT_P(zv) deflate_context_from_obj(Z_OBJ_P(zv)) + +static zend_object *deflate_context_create_object(zend_class_entry *class_type) { + php_zlib_context *intern = zend_object_alloc(sizeof(php_zlib_context), class_type); + + zend_object_std_init(&intern->std, class_type); + object_properties_init(&intern->std, class_type); + intern->std.handlers = &deflate_context_object_handlers; + + return &intern->std; +} -void deflate_rsrc_dtor(zend_resource *res) +static zend_function *deflate_context_get_constructor(zend_object *object) { + zend_throw_error(NULL, "Cannot directly construct DeflateContext, use deflate_init() instead"); + return NULL; +} + +static void deflate_context_free_obj(zend_object *object) { - z_stream *ctx = zend_fetch_resource(res, le_deflate_name, le_deflate); - deflateEnd(ctx); - efree(ctx); + php_zlib_context *intern = deflate_context_from_obj(object); + + deflateEnd(&intern->Z); + + zend_object_std_dtor(&intern->std); } +/* }}} */ + +/* {{{ Memory management wrappers */ -void inflate_rsrc_dtor(zend_resource *res) +static voidpf php_zlib_alloc(voidpf opaque, uInt items, uInt size) { - z_stream *ctx = zend_fetch_resource(res, le_inflate_name, le_inflate); - if (((php_zlib_context *) ctx)->inflateDict) { - efree(((php_zlib_context *) ctx)->inflateDict); - } - inflateEnd(ctx); - efree(ctx); + return (voidpf)safe_emalloc(items, size, 0); } +static void php_zlib_free(voidpf opaque, voidpf address) +{ + efree((void*)address); +} /* }}} */ /* {{{ php_zlib_output_conflict_check() */ @@ -826,11 +876,11 @@ static zend_bool zlib_create_dictionary_string(HashTable *options, char **dict, return 1; } -/* {{{ proto resource inflate_init(int encoding) +/* {{{ proto InflateContext inflate_init(int encoding) Initialize an incremental inflate context with the specified encoding */ PHP_FUNCTION(inflate_init) { - z_stream *ctx; + php_zlib_context *ctx; zend_long encoding, window = 15; char *dict = NULL; size_t dictlen = 0; @@ -850,7 +900,7 @@ PHP_FUNCTION(inflate_init) } if (!zlib_create_dictionary_string(options, &dict, &dictlen)) { - RETURN_FALSE; + RETURN_THROWS(); } switch (encoding) { @@ -863,12 +913,14 @@ PHP_FUNCTION(inflate_init) RETURN_THROWS(); } - ctx = ecalloc(1, sizeof(php_zlib_context)); - ctx->zalloc = php_zlib_alloc; - ctx->zfree = php_zlib_free; - ((php_zlib_context *) ctx)->inflateDict = dict; - ((php_zlib_context *) ctx)->inflateDictlen = dictlen; - ((php_zlib_context *) ctx)->status = Z_OK; + object_init_ex(return_value, inflate_context_ce); + ctx = Z_INFLATE_CONTEXT_P(return_value); + + ctx->Z.zalloc = php_zlib_alloc; + ctx->Z.zfree = php_zlib_free; + ctx->inflateDict = dict; + ctx->inflateDictlen = dictlen; + ctx->status = Z_OK; if (encoding < 0) { encoding += 15 - window; @@ -876,31 +928,29 @@ PHP_FUNCTION(inflate_init) encoding -= 15 - window; } - if (Z_OK == inflateInit2(ctx, encoding)) { - if (encoding == PHP_ZLIB_ENCODING_RAW && dictlen > 0) { - php_zlib_context *php_ctx = (php_zlib_context *) ctx; - switch (inflateSetDictionary(ctx, (Bytef *) php_ctx->inflateDict, php_ctx->inflateDictlen)) { - case Z_OK: - efree(php_ctx->inflateDict); - php_ctx->inflateDict = NULL; - break; - case Z_DATA_ERROR: - php_error_docref(NULL, E_WARNING, "Dictionary does not match expected dictionary (incorrect adler32 hash)"); - efree(php_ctx->inflateDict); - php_ctx->inflateDict = NULL; - EMPTY_SWITCH_DEFAULT_CASE() - } - } - RETURN_RES(zend_register_resource(ctx, le_inflate)); - } else { - efree(ctx); + if (inflateInit2(&ctx->Z, encoding) != Z_OK) { + zval_ptr_dtor(return_value); php_error_docref(NULL, E_WARNING, "Failed allocating zlib.inflate context"); RETURN_FALSE; } + + if (encoding == PHP_ZLIB_ENCODING_RAW && dictlen > 0) { + switch (inflateSetDictionary(&ctx->Z, (Bytef *) ctx->inflateDict, ctx->inflateDictlen)) { + case Z_OK: + efree(ctx->inflateDict); + ctx->inflateDict = NULL; + break; + case Z_DATA_ERROR: + php_error_docref(NULL, E_WARNING, "Dictionary does not match expected dictionary (incorrect adler32 hash)"); + efree(ctx->inflateDict); + ctx->inflateDict = NULL; + EMPTY_SWITCH_DEFAULT_CASE() + } + } } /* }}} */ -/* {{{ proto string inflate_add(resource context, string encoded_data[, int flush_mode = ZLIB_SYNC_FLUSH]) +/* {{{ proto string inflate_add(InflateContext context, string encoded_data[, int flush_mode = ZLIB_SYNC_FLUSH]) Incrementally inflate encoded data in the specified context */ PHP_FUNCTION(inflate_add) { @@ -908,17 +958,15 @@ PHP_FUNCTION(inflate_add) char *in_buf; size_t in_len, buffer_used = 0, CHUNK_SIZE = 8192; zval *res; - z_stream *ctx; + php_zlib_context *ctx; zend_long flush_type = Z_SYNC_FLUSH; int status; - if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "rs|l", &res, &in_buf, &in_len, &flush_type)) { + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "Os|l", &res, inflate_context_ce, &in_buf, &in_len, &flush_type)) { RETURN_THROWS(); } - if ((ctx = zend_fetch_resource(Z_RES_P(res), le_inflate_name, le_inflate)) == NULL) { - RETURN_THROWS(); - } + ctx = Z_INFLATE_CONTEXT_P(res); switch (flush_type) { case Z_NO_FLUSH: @@ -930,16 +978,15 @@ PHP_FUNCTION(inflate_add) break; default: - zend_value_error( - "Flush mode must be ZLIB_NO_FLUSH, ZLIB_PARTIAL_FLUSH, ZLIB_SYNC_FLUSH, ZLIB_FULL_FLUSH, ZLIB_BLOCK or ZLIB_FINISH"); + zend_argument_value_error(3, "must be one of ZLIB_NO_FLUSH, ZLIB_PARTIAL_FLUSH, ZLIB_SYNC_FLUSH, ZLIB_FULL_FLUSH, ZLIB_BLOCK, or ZLIB_FINISH"); RETURN_THROWS(); } /* Lazy-resetting the zlib stream so ctx->total_in remains available until the next inflate_add() call. */ - if (((php_zlib_context *) ctx)->status == Z_STREAM_END) + if (ctx->status == Z_STREAM_END) { - ((php_zlib_context *) ctx)->status = Z_OK; - inflateReset(ctx); + ctx->status = Z_OK; + inflateReset(&ctx->Z); } if (in_len <= 0 && flush_type != Z_FINISH) { @@ -947,24 +994,24 @@ PHP_FUNCTION(inflate_add) } out = zend_string_alloc((in_len > CHUNK_SIZE) ? in_len : CHUNK_SIZE, 0); - ctx->next_in = (Bytef *) in_buf; - ctx->next_out = (Bytef *) ZSTR_VAL(out); - ctx->avail_in = in_len; - ctx->avail_out = ZSTR_LEN(out); + ctx->Z.next_in = (Bytef *) in_buf; + ctx->Z.next_out = (Bytef *) ZSTR_VAL(out); + ctx->Z.avail_in = in_len; + ctx->Z.avail_out = ZSTR_LEN(out); do { - status = inflate(ctx, flush_type); - buffer_used = ZSTR_LEN(out) - ctx->avail_out; + status = inflate(&ctx->Z, flush_type); + buffer_used = ZSTR_LEN(out) - ctx->Z.avail_out; - ((php_zlib_context *) ctx)->status = status; /* Save status for exposing to userspace */ + ctx->status = status; /* Save status for exposing to userspace */ switch (status) { case Z_OK: - if (ctx->avail_out == 0) { + if (ctx->Z.avail_out == 0) { /* more output buffer space needed; realloc and try again */ out = zend_string_realloc(out, ZSTR_LEN(out) + CHUNK_SIZE, 0); - ctx->avail_out = CHUNK_SIZE; - ctx->next_out = (Bytef *) ZSTR_VAL(out) + buffer_used; + ctx->Z.avail_out = CHUNK_SIZE; + ctx->Z.next_out = (Bytef *) ZSTR_VAL(out) + buffer_used; break; } else { goto complete; @@ -972,29 +1019,28 @@ PHP_FUNCTION(inflate_add) case Z_STREAM_END: goto complete; case Z_BUF_ERROR: - if (flush_type == Z_FINISH && ctx->avail_out == 0) { + if (flush_type == Z_FINISH && ctx->Z.avail_out == 0) { /* more output buffer space needed; realloc and try again */ out = zend_string_realloc(out, ZSTR_LEN(out) + CHUNK_SIZE, 0); - ctx->avail_out = CHUNK_SIZE; - ctx->next_out = (Bytef *) ZSTR_VAL(out) + buffer_used; + ctx->Z.avail_out = CHUNK_SIZE; + ctx->Z.next_out = (Bytef *) ZSTR_VAL(out) + buffer_used; break; } else { /* No more input data; we're finished */ goto complete; } case Z_NEED_DICT: - if (((php_zlib_context *) ctx)->inflateDict) { - php_zlib_context *php_ctx = (php_zlib_context *) ctx; - switch (inflateSetDictionary(ctx, (Bytef *) php_ctx->inflateDict, php_ctx->inflateDictlen)) { + if (ctx->inflateDict) { + switch (inflateSetDictionary(&ctx->Z, (Bytef *) ctx->inflateDict, ctx->inflateDictlen)) { case Z_OK: - efree(php_ctx->inflateDict); - php_ctx->inflateDict = NULL; + efree(ctx->inflateDict); + ctx->inflateDict = NULL; break; case Z_DATA_ERROR: - php_error_docref(NULL, E_WARNING, "Dictionary does not match expected dictionary (incorrect adler32 hash)"); - efree(php_ctx->inflateDict); + efree(ctx->inflateDict); + ctx->inflateDict = NULL; zend_string_release_ex(out, 0); - php_ctx->inflateDict = NULL; + php_error_docref(NULL, E_WARNING, "Dictionary does not match expected dictionary (incorrect adler32 hash)"); RETURN_FALSE; EMPTY_SWITCH_DEFAULT_CASE() } @@ -1010,11 +1056,10 @@ PHP_FUNCTION(inflate_add) } } while (1); - complete: { - out = zend_string_realloc(out, buffer_used, 0); - ZSTR_VAL(out)[buffer_used] = 0; - RETURN_STR(out); - } +complete: + out = zend_string_realloc(out, buffer_used, 0); + ZSTR_VAL(out)[buffer_used] = 0; + RETURN_STR(out); } /* }}} */ @@ -1023,18 +1068,15 @@ PHP_FUNCTION(inflate_add) PHP_FUNCTION(inflate_get_status) { zval *res; - z_stream *ctx; + php_zlib_context *ctx; - if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "r", &res)) - { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &res, inflate_context_ce) != SUCCESS) { RETURN_THROWS(); } - if ((ctx = zend_fetch_resource(Z_RES_P(res), le_inflate_name, le_inflate)) == NULL) { - RETURN_THROWS(); - } + ctx = Z_INFLATE_CONTEXT_P(res); - RETURN_LONG(((php_zlib_context *) ctx)->status); + RETURN_LONG(ctx->status); } /* }}} */ @@ -1043,26 +1085,23 @@ PHP_FUNCTION(inflate_get_status) PHP_FUNCTION(inflate_get_read_len) { zval *res; - z_stream *ctx; + php_zlib_context *ctx; - if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "r", &res)) - { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &res, inflate_context_ce) != SUCCESS) { RETURN_THROWS(); } - if ((ctx = zend_fetch_resource(Z_RES_P(res), le_inflate_name, le_inflate)) == NULL) { - RETURN_THROWS(); - } + ctx = Z_INFLATE_CONTEXT_P(res); - RETURN_LONG(ctx->total_in); + RETURN_LONG(ctx->Z.total_in); } /* }}} */ -/* {{{ proto resource deflate_init(int encoding[, array options]) +/* {{{ proto DeflateContext deflate_init(int encoding[, array options]) Initialize an incremental deflate context using the specified encoding */ PHP_FUNCTION(deflate_init) { - z_stream *ctx; + php_zlib_context *ctx; zend_long encoding, level = -1, memory = 8, window = 15, strategy = Z_DEFAULT_STRATEGY; char *dict = NULL; size_t dictlen = 0; @@ -1113,7 +1152,7 @@ PHP_FUNCTION(deflate_init) } if (!zlib_create_dictionary_string(options, &dict, &dictlen)) { - RETURN_FALSE; + RETURN_THROWS(); } switch (encoding) { @@ -1126,9 +1165,11 @@ PHP_FUNCTION(deflate_init) RETURN_THROWS(); } - ctx = ecalloc(1, sizeof(php_zlib_context)); - ctx->zalloc = php_zlib_alloc; - ctx->zfree = php_zlib_free; + object_init_ex(return_value, deflate_context_ce); + ctx = Z_DEFLATE_CONTEXT_P(return_value); + + ctx->Z.zalloc = php_zlib_alloc; + ctx->Z.zfree = php_zlib_free; if (encoding < 0) { encoding += 15 - window; @@ -1136,23 +1177,21 @@ PHP_FUNCTION(deflate_init) encoding -= 15 - window; } - if (Z_OK == deflateInit2(ctx, level, Z_DEFLATED, encoding, memory, strategy)) { - if (dict) { - int success = deflateSetDictionary(ctx, (Bytef *) dict, dictlen); - ZEND_ASSERT(success == Z_OK); - efree(dict); - } - - RETURN_RES(zend_register_resource(ctx, le_deflate)); - } else { - efree(ctx); + if (deflateInit2(&ctx->Z, level, Z_DEFLATED, encoding, memory, strategy) != Z_OK) { + zval_ptr_dtor(return_value); php_error_docref(NULL, E_WARNING, "Failed allocating zlib.deflate context"); RETURN_FALSE; } + + if (dict) { + int success = deflateSetDictionary(&ctx->Z, (Bytef *) dict, dictlen); + ZEND_ASSERT(success == Z_OK); + efree(dict); + } } /* }}} */ -/* {{{ proto string deflate_add(resource context, string data[, int flush_mode = ZLIB_SYNC_FLUSH]) +/* {{{ proto string deflate_add(DeflateContext context, string data[, int flush_mode = ZLIB_SYNC_FLUSH]) Incrementally deflate data in the specified context */ PHP_FUNCTION(deflate_add) { @@ -1160,17 +1199,15 @@ PHP_FUNCTION(deflate_add) char *in_buf; size_t in_len, out_size, buffer_used; zval *res; - z_stream *ctx; + php_zlib_context *ctx; zend_long flush_type = Z_SYNC_FLUSH; int status; - if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "rs|l", &res, &in_buf, &in_len, &flush_type)) { + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "Os|l", &res, deflate_context_ce, &in_buf, &in_len, &flush_type)) { RETURN_THROWS(); } - if ((ctx = zend_fetch_resource(Z_RES_P(res), le_deflate_name, le_deflate)) == NULL) { - RETURN_THROWS(); - } + ctx = Z_DEFLATE_CONTEXT_P(res); switch (flush_type) { case Z_BLOCK: @@ -1198,35 +1235,35 @@ PHP_FUNCTION(deflate_add) out_size = (out_size < 64) ? 64 : out_size; out = zend_string_alloc(out_size, 0); - ctx->next_in = (Bytef *) in_buf; - ctx->next_out = (Bytef *) ZSTR_VAL(out); - ctx->avail_in = in_len; - ctx->avail_out = ZSTR_LEN(out); + ctx->Z.next_in = (Bytef *) in_buf; + ctx->Z.next_out = (Bytef *) ZSTR_VAL(out); + ctx->Z.avail_in = in_len; + ctx->Z.avail_out = ZSTR_LEN(out); buffer_used = 0; do { - if (ctx->avail_out == 0) { + if (ctx->Z.avail_out == 0) { /* more output buffer space needed; realloc and try again */ /* adding 64 more bytes solved every issue I have seen */ out = zend_string_realloc(out, ZSTR_LEN(out) + 64, 0); - ctx->avail_out = 64; - ctx->next_out = (Bytef *) ZSTR_VAL(out) + buffer_used; + ctx->Z.avail_out = 64; + ctx->Z.next_out = (Bytef *) ZSTR_VAL(out) + buffer_used; } - status = deflate(ctx, flush_type); - buffer_used = ZSTR_LEN(out) - ctx->avail_out; - } while (status == Z_OK && ctx->avail_out == 0); + status = deflate(&ctx->Z, flush_type); + buffer_used = ZSTR_LEN(out) - ctx->Z.avail_out; + } while (status == Z_OK && ctx->Z.avail_out == 0); switch (status) { case Z_OK: - ZSTR_LEN(out) = (char *) ctx->next_out - ZSTR_VAL(out); + ZSTR_LEN(out) = (char *) ctx->Z.next_out - ZSTR_VAL(out); ZSTR_VAL(out)[ZSTR_LEN(out)] = 0; RETURN_STR(out); break; case Z_STREAM_END: - ZSTR_LEN(out) = (char *) ctx->next_out - ZSTR_VAL(out); + ZSTR_LEN(out) = (char *) ctx->Z.next_out - ZSTR_VAL(out); ZSTR_VAL(out)[ZSTR_LEN(out)] = 0; - deflateReset(ctx); + deflateReset(&ctx->Z); RETURN_STR(out); break; default: @@ -1319,8 +1356,33 @@ static PHP_MINIT_FUNCTION(zlib) php_output_handler_conflict_register(ZEND_STRL("ob_gzhandler"), php_zlib_output_conflict_check); php_output_handler_conflict_register(ZEND_STRL(PHP_ZLIB_OUTPUT_HANDLER_NAME), php_zlib_output_conflict_check); - le_deflate = zend_register_list_destructors_ex(deflate_rsrc_dtor, NULL, "zlib.deflate", module_number); - le_inflate = zend_register_list_destructors_ex(inflate_rsrc_dtor, NULL, "zlib.inflate", module_number); + zend_class_entry inflate_ce; + INIT_CLASS_ENTRY(inflate_ce, "InflateContext", class_InflateContext_methods); + inflate_context_ce = zend_register_internal_class(&inflate_ce); + inflate_context_ce->ce_flags |= ZEND_ACC_FINAL; + inflate_context_ce->create_object = inflate_context_create_object; + inflate_context_ce->serialize = zend_class_serialize_deny; + inflate_context_ce->unserialize = zend_class_unserialize_deny; + + memcpy(&inflate_context_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); + inflate_context_object_handlers.offset = XtOffsetOf(php_zlib_context, std); + inflate_context_object_handlers.free_obj = inflate_context_free_obj; + inflate_context_object_handlers.get_constructor = inflate_context_get_constructor; + inflate_context_object_handlers.clone_obj = NULL; + + zend_class_entry deflate_ce; + INIT_CLASS_ENTRY(deflate_ce, "DeflateContext", class_DeflateContext_methods); + deflate_context_ce = zend_register_internal_class(&deflate_ce); + deflate_context_ce->ce_flags |= ZEND_ACC_FINAL; + deflate_context_ce->create_object = deflate_context_create_object; + deflate_context_ce->serialize = zend_class_serialize_deny; + deflate_context_ce->unserialize = zend_class_unserialize_deny; + + memcpy(&deflate_context_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); + deflate_context_object_handlers.offset = XtOffsetOf(php_zlib_context, std); + deflate_context_object_handlers.free_obj = deflate_context_free_obj; + deflate_context_object_handlers.get_constructor = deflate_context_get_constructor; + deflate_context_object_handlers.clone_obj = NULL; REGISTER_LONG_CONSTANT("FORCE_GZIP", PHP_ZLIB_ENCODING_GZIP, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("FORCE_DEFLATE", PHP_ZLIB_ENCODING_DEFLATE, CONST_CS|CONST_PERSISTENT); diff --git a/ext/zlib/zlib.stub.php b/ext/zlib/zlib.stub.php index c3f87e5ccc35e..8f4ba12c7964c 100644 --- a/ext/zlib/zlib.stub.php +++ b/ext/zlib/zlib.stub.php @@ -2,6 +2,14 @@ /** @generate-function-entries */ +final class InflateContext +{ +} + +final class DeflateContext +{ +} + function ob_gzhandler(string $data, int $flags): string|false {} function zlib_get_coding_type(): string|false {} @@ -95,20 +103,14 @@ function gzread($fp, int $length): string|false {} */ function gzgets($fp, int $length = 1024): string|false {} -/** @return resource|false */ -function deflate_init(int $encoding, array $options = []) {} +function deflate_init(int $encoding, array $options = []): DeflateContext|false {} -/** @param resource $resource */ -function deflate_add($resource, string $add, int $flush_behavior = ZLIB_SYNC_FLUSH): string|false {} +function deflate_add(DeflateContext $context, string $add, int $flush_behavior = ZLIB_SYNC_FLUSH): string|false {} -/** @return resource|false */ -function inflate_init(int $encoding, array $options = []) {} +function inflate_init(int $encoding, array $options = []): InflateContext|false {} -/** @param resource $context */ -function inflate_add($context, string $encoded_data, int $flush_mode = ZLIB_SYNC_FLUSH): string|false {} +function inflate_add(InflateContext $context, string $encoded_data, int $flush_mode = ZLIB_SYNC_FLUSH): string|false {} -/** @param resource $resource */ -function inflate_get_status($resource): int {} +function inflate_get_status(InflateContext $context): int {} -/** @param resource $resource */ -function inflate_get_read_len($resource): int {} +function inflate_get_read_len(InflateContext $context): int {} diff --git a/ext/zlib/zlib_arginfo.h b/ext/zlib/zlib_arginfo.h index b86926c906207..2a5112391ed87 100644 --- a/ext/zlib/zlib_arginfo.h +++ b/ext/zlib/zlib_arginfo.h @@ -103,27 +103,30 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_gzgets, 0, 1, MAY_BE_STRING|MAY_ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, length, IS_LONG, 0, "1024") ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_deflate_init, 0, 0, 1) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_deflate_init, 0, 1, DeflateContext, MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, encoding, IS_LONG, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 0, "[]") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_deflate_add, 0, 2, MAY_BE_STRING|MAY_BE_FALSE) - ZEND_ARG_INFO(0, resource) + ZEND_ARG_OBJ_INFO(0, context, DeflateContext, 0) ZEND_ARG_TYPE_INFO(0, add, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flush_behavior, IS_LONG, 0, "ZLIB_SYNC_FLUSH") ZEND_END_ARG_INFO() -#define arginfo_inflate_init arginfo_deflate_init +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_inflate_init, 0, 1, InflateContext, MAY_BE_FALSE) + ZEND_ARG_TYPE_INFO(0, encoding, IS_LONG, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 0, "[]") +ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_inflate_add, 0, 2, MAY_BE_STRING|MAY_BE_FALSE) - ZEND_ARG_INFO(0, context) + ZEND_ARG_OBJ_INFO(0, context, InflateContext, 0) ZEND_ARG_TYPE_INFO(0, encoded_data, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flush_mode, IS_LONG, 0, "ZLIB_SYNC_FLUSH") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_inflate_get_status, 0, 1, IS_LONG, 0) - ZEND_ARG_INFO(0, resource) + ZEND_ARG_OBJ_INFO(0, context, InflateContext, 0) ZEND_END_ARG_INFO() #define arginfo_inflate_get_read_len arginfo_inflate_get_status @@ -193,3 +196,13 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(inflate_get_read_len, arginfo_inflate_get_read_len) ZEND_FE_END }; + + +static const zend_function_entry class_InflateContext_methods[] = { + ZEND_FE_END +}; + + +static const zend_function_entry class_DeflateContext_methods[] = { + ZEND_FE_END +}; From 9b3e57921f1a56ed4b3b389e4cea0b98c4b19498 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 17 Jun 2020 17:13:01 +0200 Subject: [PATCH 7/8] Suppress zend signals check in two readline tests Installing a callback handler may cause libedit to register new signals during the request. --- Zend/zend.c | 2 +- Zend/zend_signal.c | 1 - ext/readline/tests/libedit_callback_handler_install_001.phpt | 2 ++ ext/readline/tests/libedit_callback_handler_remove_001.phpt | 2 ++ 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Zend/zend.c b/Zend/zend.c index b61658ef53e28..2191ca815092f 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -173,7 +173,7 @@ ZEND_INI_BEGIN() ZEND_INI_ENTRY("zend.script_encoding", NULL, ZEND_INI_ALL, OnUpdateScriptEncoding) STD_ZEND_INI_BOOLEAN("zend.detect_unicode", "1", ZEND_INI_ALL, OnUpdateBool, detect_unicode, zend_compiler_globals, compiler_globals) #ifdef ZEND_SIGNALS - STD_ZEND_INI_BOOLEAN("zend.signal_check", "0", ZEND_INI_SYSTEM, OnUpdateBool, check, zend_signal_globals_t, zend_signal_globals) + STD_ZEND_INI_BOOLEAN("zend.signal_check", ZEND_DEBUG ? "1" : "0", ZEND_INI_SYSTEM, OnUpdateBool, check, zend_signal_globals_t, zend_signal_globals) #endif STD_ZEND_INI_BOOLEAN("zend.exception_ignore_args", "0", ZEND_INI_ALL, OnUpdateBool, exception_ignore_args, zend_executor_globals, executor_globals) ZEND_INI_END() diff --git a/Zend/zend_signal.c b/Zend/zend_signal.c index 96870f8d5cc49..e69914752aca1 100644 --- a/Zend/zend_signal.c +++ b/Zend/zend_signal.c @@ -328,7 +328,6 @@ void zend_signal_activate(void) SIGG(active) = 1; SIGG(depth) = 0; - SIGG(check) = ZEND_DEBUG; } /* }}} */ /* {{{ zend_signal_deactivate diff --git a/ext/readline/tests/libedit_callback_handler_install_001.phpt b/ext/readline/tests/libedit_callback_handler_install_001.phpt index b5d921e279621..4fdd4acadd711 100644 --- a/ext/readline/tests/libedit_callback_handler_install_001.phpt +++ b/ext/readline/tests/libedit_callback_handler_install_001.phpt @@ -4,6 +4,8 @@ readline_callback_handler_install(): Basic test +--INI-- +zend.signal_check=0 --FILE-- +--INI-- +zend.signal_check=0 --FILE-- Date: Wed, 27 May 2020 08:12:45 +0200 Subject: [PATCH 8/8] Remove unneeded --disable-inline-optimization build parameter In 1999, inline optimization was turned off by default. The commit log indicates this was done because GCC was running out of memory on some hosts when building the Zend executor. In 2003, inline optimization was re-enabled by default, but a build option was added to turn it off if one runs out of memory when building. Computing hardware has come a long way since 2003 and I doubt that anyone is running out of memory when building PHP now. Interestingly, this code set an unused variable called `INLINE_CFLAGS`. It actually disabled inline optimization by adding -O0 to the build command, not using `INLINE_CFLAGS`. Just to see how much memory GCC/Make are using when building PHP, I tried building with successively higher values of `ulimit -v` until it succeeded. Interestingly, while most of the codebase can be built with about 400MB of memory, ext/fileinfo/libmagic/apprentice.c requires 1.2GB, doubtless because it includes ext/fileinfo/data_file.c, which is more than 350,000 lines long. That is with GCC 7.5.0. Most users get PHP as a binary package anyways, so the question is, are *packagers* of PHP trying to build on machines with just 1GB RAM? And would they want to package a PHP interpreter built with *no optimizations*? I can't imagine either being true. --- Zend/Zend.m4 | 19 ------------------- configure.ac | 14 +------------- 2 files changed, 1 insertion(+), 32 deletions(-) diff --git a/Zend/Zend.m4 b/Zend/Zend.m4 index 7c715e853bf5b..b0f913aac3e09 100644 --- a/Zend/Zend.m4 +++ b/Zend/Zend.m4 @@ -196,18 +196,9 @@ AC_ARG_ENABLE([zts], [ZEND_ZTS=$enableval], [ZEND_ZTS=no]) -AC_ARG_ENABLE([inline-optimization], - [AS_HELP_STRING([--disable-inline-optimization], - [If building zend_execute.lo fails, try this switch])], - [ZEND_INLINE_OPTIMIZATION=$enableval], - [ZEND_INLINE_OPTIMIZATION=yes]) - AC_MSG_CHECKING(whether to enable thread-safety) AC_MSG_RESULT($ZEND_ZTS) -AC_MSG_CHECKING(whether to enable inline optimization for GCC) -AC_MSG_RESULT($ZEND_INLINE_OPTIMIZATION) - AC_MSG_CHECKING(whether to enable Zend debugging) AC_MSG_RESULT($ZEND_DEBUG) @@ -232,18 +223,8 @@ if test "$ZEND_ZTS" = "yes"; then CFLAGS="$CFLAGS -DZTS" fi -changequote({,}) -if test -n "$GCC" && test "$ZEND_INLINE_OPTIMIZATION" != "yes"; then - INLINE_CFLAGS=`echo $ac_n "$CFLAGS $ac_c" | sed s/-O[0-9s]*//` -else - INLINE_CFLAGS="$CFLAGS" -fi -changequote([,]) - AC_C_INLINE -AC_SUBST(INLINE_CFLAGS) - AC_MSG_CHECKING(target system is Darwin) if echo "$target" | grep "darwin" > /dev/null; then AC_DEFINE([DARWIN], 1, [Define if the target system is darwin]) diff --git a/configure.ac b/configure.ac index 4f291b45d6282..ded516b01f095 100644 --- a/configure.ac +++ b/configure.ac @@ -1371,7 +1371,6 @@ old_CC=$CC if test "$PHP_THREAD_SAFETY" = "yes" && test -n "$ac_cv_pthreads_cflags"; then CXXFLAGS="$CXXFLAGS $ac_cv_pthreads_cflags" - INLINE_CFLAGS="$INLINE_CFLAGS $ac_cv_pthreads_cflags" CPPFLAGS="$CPPFLAGS $ac_cv_pthreads_cflags" fi @@ -1425,7 +1424,6 @@ PHP_CONFIGURE_PART(Generating files) CXXFLAGS_CLEAN=$CXXFLAGS CFLAGS_CLEAN="$CFLAGS \$(PROF_FLAGS)" CFLAGS="\$(CFLAGS_CLEAN) $standard_libtool_flag" -INLINE_CFLAGS="$INLINE_CFLAGS $standard_libtool_flag" CXXFLAGS="$CXXFLAGS $standard_libtool_flag \$(PROF_FLAGS)" if test "$PHP_PHAR" != "no" && test "$PHP_CLI" != "no"; then @@ -1470,7 +1468,7 @@ PHP_ADD_SOURCES(Zend, \ zend_execute_API.c zend_highlight.c zend_llist.c \ zend_vm_opcodes.c zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \ zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \ - zend_list.c zend_builtin_functions.c zend_attributes.c \ + zend_list.c zend_builtin_functions.c zend_attributes.c zend_execute.c \ zend_ini.c zend_sort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \ zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_gc.c \ zend_closures.c zend_weakrefs.c zend_float.c zend_string.c zend_signal.c zend_generators.c \ @@ -1478,16 +1476,6 @@ PHP_ADD_SOURCES(Zend, \ zend_default_classes.c zend_inheritance.c zend_smart_str.c zend_cpuinfo.c zend_gdb.c, \ -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) -dnl Selectively disable optimization due to high RAM usage during compiling the -dnl executor. -if test -n "$GCC" && test "$ZEND_INLINE_OPTIMIZATION" != "yes"; then - flag=-O0 -else - flag= -fi - -PHP_ADD_SOURCES_X(Zend, zend_execute.c, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1,PHP_GLOBAL_OBJS,,$flag) - PHP_ADD_BUILD_DIR(main main/streams) PHP_ADD_BUILD_DIR(TSRM) PHP_ADD_BUILD_DIR(Zend)