not->toBeFalse(); $end = strpos($reportsSource, "\n}\n", $start); $body = substr($reportsSource, $start, $end - $start); expect($body)->toContain('$format_file = basename($format_file);'); }); test('GHSA-5x27: reports_load_format_file rejects a traversal-only result before any file IO', function () use ($reportsSource) { $start = strpos($reportsSource, 'function reports_load_format_file('); $end = strpos($reportsSource, "\n}\n", $start); $body = substr($reportsSource, $start, $end - $start); $basenamePos = strpos($body, '$format_file = basename($format_file);'); $rejectPos = strpos($body, "\$format_file === '' || \$format_file === '.' || \$format_file === '..'"); $existsPos = strpos($body, 'file_exists($format_file)'); expect($basenamePos)->not->toBeFalse(); expect($rejectPos)->not->toBeFalse(); expect($existsPos)->not->toBeFalse(); expect($basenamePos)->toBeLessThan($rejectPos); expect($rejectPos)->toBeLessThan($existsPos); }); test('GHSA-5x27: the save path confines format_file to a bare filename before it reaches the database', function () use ($htmlReportsSource) { expect($htmlReportsSource)->toContain("\$save['format_file'] = basename((string) (\$post['format_file'] ?? ''));"); }); test('GHSA-5x27: a traversal payload resolves to a harmless bare filename', function () { $payload = '../../../../../../etc/passwd'; expect(basename($payload))->toBe('passwd'); });