From 3e222308effa81d058182b10e1f4bbaae50ac22b Mon Sep 17 00:00:00 2001 From: Reinfi Date: Tue, 13 Dec 2022 21:54:13 +0100 Subject: [PATCH 1/3] add test case for invokables --- .../EventLogging/EventContextProviderTest.php | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 test/EventLogging/EventContextProviderTest.php diff --git a/test/EventLogging/EventContextProviderTest.php b/test/EventLogging/EventContextProviderTest.php new file mode 100644 index 0000000..08be96f --- /dev/null +++ b/test/EventLogging/EventContextProviderTest.php @@ -0,0 +1,44 @@ +getEventTriggerFile(); + } + }; + + return $eventProviderClass($eventProviderClass, 3); + } + }; + + $eventTriggerFile = $eventProviderClass(); + + self::assertSame( + '', + $eventTriggerFile, + 'trigger file should be empty because user function calls do not refer to a file' + ); + } +} From bfefcbcfd4ba0e30315ae4dc282fbb19eefb9cf7 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Thu, 15 Dec 2022 15:06:25 +0100 Subject: [PATCH 2/3] Rewrote `EventContextProviderTest` to avoid using `call_user_func()` `call_user_func()` is automatically optimized away by PHP-SRC starting from early PHP 7 releases, and therefore cannot be used to generate artificial stack frames that are detected in PHP-SRC itself. With this change, we use `array_map()` instead, which (for now) is not optimized away (yet). --- .../EventLogging/EventContextProviderTest.php | 59 ++++++++++--------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/test/EventLogging/EventContextProviderTest.php b/test/EventLogging/EventContextProviderTest.php index 08be96f..bfb986d 100644 --- a/test/EventLogging/EventContextProviderTest.php +++ b/test/EventLogging/EventContextProviderTest.php @@ -7,38 +7,43 @@ use Laminas\DeveloperTools\EventLogging\EventContextProvider; use PHPUnit\Framework\TestCase; +use function array_map; + +/** @covers \Laminas\DeveloperTools\EventLogging\EventContextProvider */ class EventContextProviderTest extends TestCase { - public function testEventTriggerFileForInvokables() + public function testEventTriggerFileDetectsEmptyFileLocationWhenStackFrameIsInPhpItself(): void { - $eventProviderClass = new class { - public function __invoke() { - return call_user_func([$this, 'get']); - } - - private function get() - { - $eventProviderClass = new class { - public function __invoke($invokableClass, int $maxLevel, int $level = 0) - { - if ($level < $maxLevel) { - return $invokableClass($invokableClass, $maxLevel, ++$level); - } - - return (new EventContextProvider())->getEventTriggerFile(); - } - }; - - return $eventProviderClass($eventProviderClass, 3); - } - }; - - $eventTriggerFile = $eventProviderClass(); - self::assertSame( - '', - $eventTriggerFile, + [ + 'stack frame on this file: EventLogging/EventContextProviderTest.php', + 'stack frame in php core: ', + 'stack frame on this file: EventLogging/EventContextProviderTest.php', + ], + // Important: `array_map()` needed here, as it produces a stack frame without "file" location + array_map( + [$this, 'callEventContextProviderWithStackTraceNestingLevelAndName'], + [ + 'stack frame on this file', + 'stack frame in php core', + 'stack frame on this file', + ], + [ + 3, + 4, + 5, + ] + ), 'trigger file should be empty because user function calls do not refer to a file' ); } + + private function callEventContextProviderWithStackTraceNestingLevelAndName(string $name, int $level): string + { + if ($level > 0) { + return $this->callEventContextProviderWithStackTraceNestingLevelAndName($name, $level - 1); + } + + return $name . ': ' . (new EventContextProvider())->getEventTriggerFile(); + } } From 7c1f50db354fad9a2d0d8990533229b23c8c36ab Mon Sep 17 00:00:00 2001 From: "martin.reinfandt" Date: Thu, 25 Aug 2022 12:06:13 +0200 Subject: [PATCH 3/3] fix access of undefined array index file --- src/EventLogging/EventContextProvider.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/EventLogging/EventContextProvider.php b/src/EventLogging/EventContextProvider.php index a0ac3e5..ff4479f 100644 --- a/src/EventLogging/EventContextProvider.php +++ b/src/EventLogging/EventContextProvider.php @@ -128,6 +128,10 @@ public function getEventTriggerFile() { $backtrace = $this->getDebugBacktrace(); + if (! isset($backtrace[4]['file'])) { + return ''; + } + if (file_exists($backtrace[4]['file'])) { return basename(dirname($backtrace[4]['file'])) . '/' . basename($backtrace[4]['file']); }