Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@ and this project adheres to [Semantic Versioning](https://semver.org).
- Added PHP compatible string offsets, so reading, writing, `isset()`, `empty()` and `unset()` on a string behave as they do in PHP, including negative offsets, out of range warnings, dynamically typed sources and `for c in s` [#760](https://github.com/zephir-lang/zephir/issues/760)

### Fixed
- Fixed the `zephir_array_*_long()` helpers truncating a negative or large index to 32 bits on Windows, where `unsigned long` is narrower than `zend_long`, so `s[-1]` read index 4294967295 and a write tried to grow the string to 4 GB [#2666](https://github.com/zephir-lang/zephir/issues/2666)
- Fixed Zephir `long`/`ulong` mapping to a C `long`, 32-bit on Windows, so a 64-bit value truncated and `Z_PARAM_LONG()` stored 8 bytes into a 4-byte local [#2666](https://github.com/zephir-lang/zephir/issues/2666)
- Fixed the kernel signatures that carry a PHP integer (`zephir_get_intval_ex()`, the comparison, division and modulo helpers, `zephir_substr()`, `zephir_fast_explode()`, `zephir_preg_match()` and the multi-dimensional array key) using a C `long` [#2666](https://github.com/zephir-lang/zephir/issues/2666)
- Fixed a multi-dimensional array index reaching `zephir_array_update_multi()` as a C `int` where the callee reads a `zend_long`, so `a[0][1]` produced keys such as 140733193388033 on Windows [#2666](https://github.com/zephir-lang/zephir/issues/2666)
- Fixed a `uint`/`ulong` multi-dimensional array index being passed by address, so the pointer value became the array key [#2666](https://github.com/zephir-lang/zephir/issues/2666)
- Fixed six `zephir_safe_mod_*()` helpers being declared and emitted but never defined, so any `%` with a float operand died at load with `undefined symbol` [#2666](https://github.com/zephir-lang/zephir/issues/2666)
- Fixed `%` yielding a float instead of an `int`, which lost every result above 2^53 [#2666](https://github.com/zephir-lang/zephir/issues/2666)
- Fixed `/ 0` and `% 0` raising an `E_WARNING` and returning 0 instead of throwing `DivisionByZeroError` as PHP 8 does [#2666](https://github.com/zephir-lang/zephir/issues/2666)
- Fixed `PHP_INT_MIN % -1` crashing the process with SIGFPE [#2666](https://github.com/zephir-lang/zephir/issues/2666)
- Fixed a float divisor being silently truncated to an integer by `/` and `%` [#2666](https://github.com/zephir-lang/zephir/issues/2666)
- Fixed a `-Wformat` warning in `zephir_fclose()` by casting the resource handle to `zend_long` and formatting it with the portable `ZEND_LONG_FMT` macro instead of `%d`, preserving compatibility with PHP 8.0's `int` handle.
- A variable whose only consumer is a closure's `use (...)` clause now counts as used: it is no longer reported as `unused-variable`, and it is declared in the generated C. A declared-but-unassigned capture was skipped by both, so the generated code referenced an undeclared identifier and the extension failed to build. Capturing a variable that was never declared now fails with `Cannot capture variable 'x' because it wasn't declared` instead of a PHP fatal error [#2029](https://github.com/zephir-lang/zephir/issues/2029)
- Fixed array defaults on a class (typed `array` property defaults, trait array property defaults and array class constants), which were one shared table that every instance mutated in place instead of being copy-on-write [#2651](https://github.com/zephir-lang/zephir/issues/2651)
Expand Down
1 change: 1 addition & 0 deletions ext/config.m4
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ if test "$PHP_STUB" = "yes"; then
stub/issue2635/caller.zep.c
stub/issue2635/impl.zep.c
stub/issue2651.zep.c
stub/issue2666.zep.c
stub/issue663.zep.c
stub/issue760.zep.c
stub/issue808.zep.c
Expand Down
2 changes: 1 addition & 1 deletion ext/config.w32
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ if (PHP_STUB != "no") {
}

ADD_SOURCES(configure_module_dirname + "/stub/invokes", "abstractprotected.zep.c abstractinvoker.zep.c abstractinvokercomplex.zep.c invokeprotected.zep.c invokeprotectedcomplex.zep.c", "stub");
ADD_SOURCES(configure_module_dirname + "/stub", "testinterface.zep.c scallparent.zep.c constantsparent.zep.c issue1628abstract.zep.c issue2324.zep.c issue2505.zep.c issue2537.zep.c methodinterface.zep.c propertycache.zep.c arithmetic.zep.c arrayaccessarr.zep.c arrayaccessobj.zep.c arrayaccessproperty.zep.c arrayaccesstest.zep.c arrayiterator.zep.c arrayiteratortest.zep.c arraymanipulation.zep.c arrayobject.zep.c arraysearch.zep.c assign.zep.c bench.zep.c bitwise.zep.c branchprediction.zep.c cast.zep.c cblock.zep.c chars.zep.c closures.zep.c compare.zep.c concat.zep.c constantparameterdefault.zep.c constants.zep.c constantsinterface.zep.c constantsinterfacea.zep.c constantsinterfaceb.zep.c declaretest.zep.c destructure.zep.c diinterface.zep.c echoes.zep.c emptytest.zep.c evaltest.zep.c exception.zep.c exceptions.zep.c exists.zep.c exitdie.zep.c extendedinterface.zep.c factorial.zep.c fannkuch.zep.c fasta.zep.c fcall.zep.c fetchtest.zep.c fibonnaci.zep.c flow.zep.c fortytwo.zep.c functional.zep.c functionexists.zep.c functions.zep.c generators.zep.c geometry.zep.c globals.zep.c instance.zep.c instanceoff.zep.c internalclasses.zep.c internalinterfaces.zep.c invoke.zep.c issettest.zep.c issue1097.zep.c issue1134.zep.c issue1404.zep.c issue1521.zep.c issue1628.zep.c issue1629.zep.c issue1704.zep.c issue1706.zep.c issue1790.zep.c issue2030.zep.c issue2061.zep.c issue2063.zep.c issue2167.zep.c issue2324extended.zep.c issue2385.zep.c issue2394.zep.c issue2409.zep.c issue2428.zep.c issue2469.zep.c issue2505crosschain.zep.c issue2505extended.zep.c issue2522.zep.c issue2533.zep.c issue2537child.zep.c issue2542.zep.c issue2543.zep.c issue2546.zep.c issue2564.zep.c issue2564padfactory.zep.c issue2565.zep.c issue2651.zep.c issue663.zep.c issue760.zep.c issue808.zep.c issue820.zep.c issue882.zep.c issue887.zep.c issue893.zep.c issue914.zep.c issues.zep.c json.zep.c logical.zep.c mcall.zep.c mcallchained.zep.c mcalldynamic.zep.c mcallinternal.zep.c methodabstract.zep.c methodargs.zep.c methodswithdefaultvalues.zep.c multidimarray.zep.c nativearray.zep.c oo.zep.c openssl.zep.c operator.zep.c pdostatement.zep.c pregmatch.zep.c propertycachechild.zep.c propertycachemagic.zep.c quantum.zep.c range.zep.c references.zep.c reflection.zep.c regexdna.zep.c requires.zep.c resourcetest.zep.c returns.zep.c router.zep.c scall.zep.c scalldynamic.zep.c scallexternal.zep.c scalllateconstruct.zep.c scope.zep.c sort.zep.c spectralnorm.zep.c spl.zep.c spropertyaccess.zep.c statements.zep.c strings.zep.c stubs.zep.c ternary.zep.c trytest.zep.c typeinstances.zep.c typeoff.zep.c unknownclass.zep.c unreachableloop.zep.c unsettest.zep.c unspacedminus.zep.c usetest.zep.c variadic.zep.c vars.zep.c 0__closure.zep.c 1__closure.zep.c 2__closure.zep.c 3__closure.zep.c 4__closure.zep.c 5__closure.zep.c 6__closure.zep.c 7__closure.zep.c 8__closure.zep.c 9__closure.zep.c 10__closure.zep.c 11__closure.zep.c 12__closure.zep.c 13__closure.zep.c 14__closure.zep.c 15__closure.zep.c 16__closure.zep.c 17__closure.zep.c 18__closure.zep.c 19__closure.zep.c 20__closure.zep.c 21__closure.zep.c 22__closure.zep.c 23__closure.zep.c 24__closure.zep.c 25__closure.zep.c 26__closure.zep.c 27__closure.zep.c 28__closure.zep.c 29__closure.zep.c 30__closure.zep.c 31__closure.zep.c 32__closure.zep.c 33__closure.zep.c 34__closure.zep.c 35__closure.zep.c 36__closure.zep.c 37__closure.zep.c 38__closure.zep.c 39__closure.zep.c 40__closure.zep.c 41__closure.zep.c 42__closure.zep.c 43__closure.zep.c 44__closure.zep.c 45__closure.zep.c 46__closure.zep.c", "stub");
ADD_SOURCES(configure_module_dirname + "/stub", "testinterface.zep.c scallparent.zep.c constantsparent.zep.c issue1628abstract.zep.c issue2324.zep.c issue2505.zep.c issue2537.zep.c methodinterface.zep.c propertycache.zep.c arithmetic.zep.c arrayaccessarr.zep.c arrayaccessobj.zep.c arrayaccessproperty.zep.c arrayaccesstest.zep.c arrayiterator.zep.c arrayiteratortest.zep.c arraymanipulation.zep.c arrayobject.zep.c arraysearch.zep.c assign.zep.c bench.zep.c bitwise.zep.c branchprediction.zep.c cast.zep.c cblock.zep.c chars.zep.c closures.zep.c compare.zep.c concat.zep.c constantparameterdefault.zep.c constants.zep.c constantsinterface.zep.c constantsinterfacea.zep.c constantsinterfaceb.zep.c declaretest.zep.c destructure.zep.c diinterface.zep.c echoes.zep.c emptytest.zep.c evaltest.zep.c exception.zep.c exceptions.zep.c exists.zep.c exitdie.zep.c extendedinterface.zep.c factorial.zep.c fannkuch.zep.c fasta.zep.c fcall.zep.c fetchtest.zep.c fibonnaci.zep.c flow.zep.c fortytwo.zep.c functional.zep.c functionexists.zep.c functions.zep.c generators.zep.c geometry.zep.c globals.zep.c instance.zep.c instanceoff.zep.c internalclasses.zep.c internalinterfaces.zep.c invoke.zep.c issettest.zep.c issue1097.zep.c issue1134.zep.c issue1404.zep.c issue1521.zep.c issue1628.zep.c issue1629.zep.c issue1704.zep.c issue1706.zep.c issue1790.zep.c issue2030.zep.c issue2061.zep.c issue2063.zep.c issue2167.zep.c issue2324extended.zep.c issue2385.zep.c issue2394.zep.c issue2409.zep.c issue2428.zep.c issue2469.zep.c issue2505crosschain.zep.c issue2505extended.zep.c issue2522.zep.c issue2533.zep.c issue2537child.zep.c issue2542.zep.c issue2543.zep.c issue2546.zep.c issue2564.zep.c issue2564padfactory.zep.c issue2565.zep.c issue2651.zep.c issue2666.zep.c issue663.zep.c issue760.zep.c issue808.zep.c issue820.zep.c issue882.zep.c issue887.zep.c issue893.zep.c issue914.zep.c issues.zep.c json.zep.c logical.zep.c mcall.zep.c mcallchained.zep.c mcalldynamic.zep.c mcallinternal.zep.c methodabstract.zep.c methodargs.zep.c methodswithdefaultvalues.zep.c multidimarray.zep.c nativearray.zep.c oo.zep.c openssl.zep.c operator.zep.c pdostatement.zep.c pregmatch.zep.c propertycachechild.zep.c propertycachemagic.zep.c quantum.zep.c range.zep.c references.zep.c reflection.zep.c regexdna.zep.c requires.zep.c resourcetest.zep.c returns.zep.c router.zep.c scall.zep.c scalldynamic.zep.c scallexternal.zep.c scalllateconstruct.zep.c scope.zep.c sort.zep.c spectralnorm.zep.c spl.zep.c spropertyaccess.zep.c statements.zep.c strings.zep.c stubs.zep.c ternary.zep.c trytest.zep.c typeinstances.zep.c typeoff.zep.c unknownclass.zep.c unreachableloop.zep.c unsettest.zep.c unspacedminus.zep.c usetest.zep.c variadic.zep.c vars.zep.c 0__closure.zep.c 1__closure.zep.c 2__closure.zep.c 3__closure.zep.c 4__closure.zep.c 5__closure.zep.c 6__closure.zep.c 7__closure.zep.c 8__closure.zep.c 9__closure.zep.c 10__closure.zep.c 11__closure.zep.c 12__closure.zep.c 13__closure.zep.c 14__closure.zep.c 15__closure.zep.c 16__closure.zep.c 17__closure.zep.c 18__closure.zep.c 19__closure.zep.c 20__closure.zep.c 21__closure.zep.c 22__closure.zep.c 23__closure.zep.c 24__closure.zep.c 25__closure.zep.c 26__closure.zep.c 27__closure.zep.c 28__closure.zep.c 29__closure.zep.c 30__closure.zep.c 31__closure.zep.c 32__closure.zep.c 33__closure.zep.c 34__closure.zep.c 35__closure.zep.c 36__closure.zep.c 37__closure.zep.c 38__closure.zep.c 39__closure.zep.c 40__closure.zep.c 41__closure.zep.c 42__closure.zep.c 43__closure.zep.c 44__closure.zep.c 45__closure.zep.c 46__closure.zep.c", "stub");
ADD_SOURCES(configure_module_dirname + "/stub/issue2635", "inner.zep.c outer.zep.c base.zep.c caller.zep.c impl.zep.c", "stub");
ADD_SOURCES(configure_module_dirname + "/stub/oo/extend", "exception.zep.c", "stub");
ADD_SOURCES(configure_module_dirname + "/stub/issue2165", "issueextendinterface.zep.c issueinterface.zep.c issue.zep.c", "stub");
Expand Down
53 changes: 28 additions & 25 deletions ext/kernel/array.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ int zephir_array_isset_string_fetch(zval *fetched, const zval *arr, char *index,
return 0;
}

int zephir_array_isset_long_fetch(zval *fetched, const zval *arr, unsigned long index, int readonly)
int zephir_array_isset_long_fetch(zval *fetched, const zval *arr, zend_long index, int readonly)
{
zval *zv;

Expand All @@ -245,7 +245,7 @@ int zephir_array_isset_long_fetch(zval *fetched, const zval *arr, unsigned long

return 0;
} else if (EXPECTED(Z_TYPE_P(arr) == IS_ARRAY)) {
if ((zv = zend_hash_index_find(Z_ARRVAL_P(arr), index)) != NULL) {
if ((zv = zend_hash_index_find(Z_ARRVAL_P(arr), (zend_ulong) index)) != NULL) {
zephir_ensure_array(zv);

if (!readonly) {
Expand All @@ -256,8 +256,8 @@ int zephir_array_isset_long_fetch(zval *fetched, const zval *arr, unsigned long
return 1;
}
} else if (UNEXPECTED(Z_TYPE_P(arr) == IS_STRING)) {
if (zephir_string_offset_isset(arr, (zend_long) index)) {
zephir_string_offset_read(fetched, (zval *) arr, (zend_long) index, 0);
if (zephir_string_offset_isset(arr, index)) {
zephir_string_offset_read(fetched, (zval *) arr, index, 0);

return 1;
}
Expand Down Expand Up @@ -347,7 +347,7 @@ int ZEPHIR_FASTCALL zephir_array_isset_string(const zval *arr, const char *index
return 0;
}

int ZEPHIR_FASTCALL zephir_array_isset_long(const zval *arr, unsigned long index)
int ZEPHIR_FASTCALL zephir_array_isset_long(const zval *arr, zend_long index)
{
if (UNEXPECTED(Z_TYPE_P(arr) == IS_OBJECT && zephir_instance_of_ev((zval *)arr, (const zend_class_entry *)zend_ce_arrayaccess))) {
zend_long ZEPHIR_LAST_CALL_STATUS;
Expand All @@ -361,9 +361,9 @@ int ZEPHIR_FASTCALL zephir_array_isset_long(const zval *arr, unsigned long index

return 0;
} else if (EXPECTED(Z_TYPE_P(arr) == IS_ARRAY)) {
return zend_hash_index_exists(Z_ARRVAL_P(arr), index);
return zend_hash_index_exists(Z_ARRVAL_P(arr), (zend_ulong) index);
} else if (UNEXPECTED(Z_TYPE_P(arr) == IS_STRING)) {
return zephir_string_offset_isset(arr, (zend_long) index);
return zephir_string_offset_isset(arr, index);
}

return 0;
Expand Down Expand Up @@ -458,7 +458,7 @@ int ZEPHIR_FASTCALL zephir_array_isset_value_string(const zval *arr, const char
return Z_TYPE_P(entry) != IS_NULL;
}

int ZEPHIR_FASTCALL zephir_array_isset_value_long(const zval *arr, unsigned long index)
int ZEPHIR_FASTCALL zephir_array_isset_value_long(const zval *arr, zend_long index)
{
zval *entry;

Expand All @@ -475,7 +475,7 @@ int ZEPHIR_FASTCALL zephir_array_isset_value_long(const zval *arr, unsigned long
return 0;
}

entry = zend_hash_index_find(Z_ARRVAL_P(arr), index);
entry = zend_hash_index_find(Z_ARRVAL_P(arr), (zend_ulong) index);
if (entry == NULL) {
return 0;
}
Expand Down Expand Up @@ -516,7 +516,7 @@ int zephir_isempty_dim(zval *container, zval *offset)
return zephir_isempty_dim_fetched(zephir_array_isset_fetch(&fetched, container, offset, 0), &fetched);
}

int zephir_isempty_dim_long(zval *container, unsigned long offset)
int zephir_isempty_dim_long(zval *container, zend_long offset)
{
zval fetched;

Expand Down Expand Up @@ -617,7 +617,7 @@ int ZEPHIR_FASTCALL zephir_array_unset_string(zval *arr, const char *index, uint
return zend_hash_str_del(Z_ARRVAL_P(arr), index, index_length);
}

int ZEPHIR_FASTCALL zephir_array_unset_long(zval *arr, unsigned long index, int flags)
int ZEPHIR_FASTCALL zephir_array_unset_long(zval *arr, zend_long index, int flags)
{
if (UNEXPECTED(Z_TYPE_P(arr) == IS_OBJECT && zephir_instance_of_ev(arr, (const zend_class_entry *)zend_ce_arrayaccess))) {
zend_long ZEPHIR_LAST_CALL_STATUS;
Expand All @@ -642,7 +642,7 @@ int ZEPHIR_FASTCALL zephir_array_unset_long(zval *arr, unsigned long index, int
SEPARATE_ARRAY(arr);
}

return zend_hash_index_del(Z_ARRVAL_P(arr), index);
return zend_hash_index_del(Z_ARRVAL_P(arr), (zend_ulong) index);
}

int zephir_array_append(zval *arr, zval *value, int flags ZEPHIR_DEBUG_PARAMS)
Expand Down Expand Up @@ -738,7 +738,7 @@ int zephir_array_fetch(zval *return_value, zval *arr, zval *index, int flags ZEP

if ((flags & PH_NOISY) == PH_NOISY) {
if (sidx == NULL) {
zend_error(E_NOTICE, "Undefined index: %ld in %s on line %d", uidx, file, line);
zend_error(E_NOTICE, "Undefined index: " ZEND_LONG_FMT " in %s on line %d", (zend_long) uidx, file, line);
} else {
zend_error(E_NOTICE, "Undefined index: %s in %s on line %d", sidx, file, line);
}
Expand Down Expand Up @@ -809,7 +809,7 @@ int zephir_array_fetch_string(zval *return_value, zval *arr, const char *index,
return FAILURE;
}

int zephir_array_fetch_long(zval *return_value, zval *arr, unsigned long index, int flags ZEPHIR_DEBUG_PARAMS)
int zephir_array_fetch_long(zval *return_value, zval *arr, zend_long index, int flags ZEPHIR_DEBUG_PARAMS)
{
zval *zv;

Expand All @@ -827,7 +827,7 @@ int zephir_array_fetch_long(zval *return_value, zval *arr, unsigned long index,

return FAILURE;
} else if (EXPECTED(Z_TYPE_P(arr) == IS_ARRAY)) {
if ((zv = zend_hash_index_find(Z_ARRVAL_P(arr), index)) != NULL) {
if ((zv = zend_hash_index_find(Z_ARRVAL_P(arr), (zend_ulong) index)) != NULL) {

if ((flags & PH_READONLY) == PH_READONLY) {
ZVAL_COPY_VALUE(return_value, zv);
Expand All @@ -837,13 +837,12 @@ int zephir_array_fetch_long(zval *return_value, zval *arr, unsigned long index,
return SUCCESS;
}
if ((flags & PH_NOISY) == PH_NOISY) {
zend_error(E_NOTICE, "Undefined index: %lu", index);
zend_error(E_NOTICE, "Undefined index: " ZEND_LONG_FMT, index);
}
} else if (UNEXPECTED(Z_TYPE_P(arr) == IS_STRING)) {
/* The compiler cannot prove a `var` holds a string, so the string
* offset is dispatched here. `index` is `unsigned long` for historical
* reasons: a negative offset arrives wrapped and the cast restores it. */
zephir_string_offset_read(return_value, arr, (zend_long) index, flags);
* offset is dispatched here. */
zephir_string_offset_read(return_value, arr, index, flags);

return SUCCESS;
} else {
Expand Down Expand Up @@ -998,7 +997,7 @@ int zephir_array_update_string(zval *arr, const char *index, uint32_t index_leng
return zend_hash_str_update(Z_ARRVAL_P(arr), index, index_length, value) ? SUCCESS : FAILURE;
}

int zephir_array_update_long(zval *arr, unsigned long index, zval *value, int flags ZEPHIR_DEBUG_PARAMS)
int zephir_array_update_long(zval *arr, zend_long index, zval *value, int flags ZEPHIR_DEBUG_PARAMS)
{
if (UNEXPECTED(Z_TYPE_P(arr) == IS_OBJECT && zephir_instance_of_ev(arr, (const zend_class_entry *)zend_ce_arrayaccess))) {
zend_long ZEPHIR_LAST_CALL_STATUS;
Expand All @@ -1011,7 +1010,7 @@ int zephir_array_update_long(zval *arr, unsigned long index, zval *value, int fl

return FAILURE;
} else if (UNEXPECTED(Z_TYPE_P(arr) == IS_STRING)) {
zephir_string_offset_write(arr, (zend_long) index, value);
zephir_string_offset_write(arr, index, value);

return EG(exception) ? FAILURE : SUCCESS;
} else if (Z_TYPE_P(arr) != IS_ARRAY) {
Expand All @@ -1032,7 +1031,7 @@ int zephir_array_update_long(zval *arr, unsigned long index, zval *value, int fl
SEPARATE_ARRAY(arr);
}

return zend_hash_index_update(Z_ARRVAL_P(arr), index, value) ? SUCCESS : FAILURE;
return zend_hash_index_update(Z_ARRVAL_P(arr), (zend_ulong) index, value) ? SUCCESS : FAILURE;
}

void zephir_array_keys(zval *return_value, zval *input)
Expand Down Expand Up @@ -1104,7 +1103,11 @@ void zephir_array_update_multi_ex(zval *arr, zval *value, const char *types, int
zval *item;
zval pzv;
zend_array *p;
int i, l, ll, re_update, must_continue, wrap_tmp;
int i, re_update, must_continue, wrap_tmp;
zend_long ll;
/* SL() yields sizeof(...) - 1, a size_t, so that is what the variadic
* slot holds. Reading it back as `int` was reading half of it. */
size_t l;

ZVAL_UNDEF(&pzv);

Expand All @@ -1128,7 +1131,7 @@ void zephir_array_update_multi_ex(zval *arr, zval *value, const char *types, int

case 's':
s = va_arg(ap, char*);
l = va_arg(ap, int);
l = va_arg(ap, size_t);

/*
* Issue #1884: the final offset overwrites its slot regardless of
Expand Down Expand Up @@ -1173,7 +1176,7 @@ void zephir_array_update_multi_ex(zval *arr, zval *value, const char *types, int
break;

case 'l':
ll = va_arg(ap, long);
ll = va_arg(ap, zend_long);

/* Issue #1884: final offset always overwrites -> store directly. */
if (i == (types_length - 1)) {
Expand Down
Loading
Loading