diff --git a/appsec/src/extension/php_compat.h b/appsec/src/extension/php_compat.h index 68aa33c352a..4bbea5d4aab 100644 --- a/appsec/src/extension/php_compat.h +++ b/appsec/src/extension/php_compat.h @@ -139,7 +139,7 @@ static zend_always_inline void _gc_try_delref(zend_refcounted_h *rc) # define ZEND_HASH_FOREACH_FROM(_ht, indirect, _from) \ do { \ Bucket *_p = (_ht)->arData + _from; \ - Bucket *_end = _p + (_ht)->nNumUsed; \ + Bucket *_end = (_ht)->arData + (_ht)->nNumUsed; \ for (; _p != _end; _p++) { \ zval *_z = &_p->val; \ if (indirect && Z_TYPE_P(_z) == IS_INDIRECT) { \ diff --git a/appsec/tests/extension/generate_backtrace_08.phpt b/appsec/tests/extension/generate_backtrace_08.phpt new file mode 100644 index 00000000000..9ceb134f95e --- /dev/null +++ b/appsec/tests/extension/generate_backtrace_08.phpt @@ -0,0 +1,84 @@ +--TEST-- +Regression: ZEND_HASH_FOREACH_FROM end pointer must be arData+nNumUsed, not _p+nNumUsed +--SKIPIF-- +=')) { + die('skip: custom ZEND_HASH_FOREACH_FROM only compiled for PHP < 8.1'); +} +?> +--INI-- +extension=ddtrace.so +--ENV-- +DD_APPSEC_MAX_STACK_TRACE_DEPTH=4 +--FILE-- + +--EXPECTF-- +array(3) { + ["language"]=> + string(3) "php" + ["id"]=> + string(7) "some id" + ["frames"]=> + array(4) { + [0]=> + array(4) { + ["line"]=> + int(12) + ["function"]=> + string(18) "recursive_function" + ["file"]=> + string(25) "generate_backtrace_08.php" + ["id"]=> + int(0) + } + [1]=> + array(4) { + ["line"]=> + int(12) + ["function"]=> + string(18) "recursive_function" + ["file"]=> + string(25) "generate_backtrace_08.php" + ["id"]=> + int(5) + } + [2]=> + array(4) { + ["line"]=> + int(12) + ["function"]=> + string(18) "recursive_function" + ["file"]=> + string(25) "generate_backtrace_08.php" + ["id"]=> + int(6) + } + [3]=> + array(4) { + ["line"]=> + int(15) + ["function"]=> + string(18) "recursive_function" + ["file"]=> + string(25) "generate_backtrace_08.php" + ["id"]=> + int(7) + } + } +}