�ɲɾ�����ӯ�����һ��ˣ��������С���˴��ͣ�������P���ҹ��ñ˽��ά�Բ��������˸߸ԣ�������ơ��ҹ��ñ�����ά�Բ���ˡ���˳^�ӣ������ӡ� ���ͯj�ӣ��ƺ���ӣ� ? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!PK a_2]"b b NodeJs.phpnu [ fileExists($packageFile)) { return new EmptyMatchResult(); } $json = []; try { $json = json_decode($fs->read($packageFile), true, 512, JSON_THROW_ON_ERROR); } catch (JsonException) { // ignore package.json errors } return new MatchResult($path, null, $json['name'] ?? null); } } PK a_2]L- - EmDash.phpnu [ fileExists($packageJsonPath)) { return new EmptyMatchResult(); } $json = json_decode($fs->read($packageJsonPath), true); return is_array($json) && (isset($json['emdash']) || isset($json['dependencies']['emdash'])) ? new MatchResult($path) : new EmptyMatchResult(); } } PK a_2]T Duda.phpnu [ getCssFile($fs, $rTrimPath); $inspectorHelper = new InspectorHelper(); if ($cssFile !== null) { $cssFileContent = $fs->read($rTrimPath . $cssFile); if ( $inspectorHelper->fileContentContainsString($cssFileContent, 'dmDudaonePreviewBody') || $inspectorHelper->fileContentContainsString($cssFileContent, 'dudaSnipcartProductGalleryId') ) { return new MatchResult($path); } } if (!$fs->fileExists($rTrimPath . self::RUNTIME_JS_FILE)) { return new EmptyMatchResult(); } return $inspectorHelper->fileContainsString($fs, $rTrimPath . self::RUNTIME_JS_FILE, 'duda') ? new MatchResult($path) : new EmptyMatchResult(); } private function getCssFile(Filesystem $fs, string $path): ?string { foreach (self::CSS_FILES as $cssFile) { if ($fs->fileExists($path . $cssFile)) { return $cssFile; } } return null; } } PK a_2]K Laravel.phpnu [ fileExists($path . '/' . self::ARTISAN)) { return new EmptyMatchResult(); } return new MatchResult($path, $this->detectVersion($path, $fs)); } private function detectVersion(string $path, Filesystem $fs): ?string { $result = null; $versionFile = $path . '/' . self::VERSION_FILE; if ($fs->fileExists($versionFile)) { preg_match("/VERSION\\s*=\\s*'([^']+)'/", $fs->read($versionFile), $matches); if ($matches !== []) { $result = $matches[1]; } } else { $composerJsonFile = $path . '/' . self::COMPOSER_JSON; if ($fs->fileExists($composerJsonFile)) { try { $json = json_decode($fs->read($composerJsonFile), true, 512, JSON_THROW_ON_ERROR); if ($laravelPackage = $json['require']['laravel/framework'] ?? null) { $result = str_replace('^', '', $laravelPackage); } } catch (JsonException) { // ignore composer.json errors } } } return $result; } } PK a_2]%' ' Joomla.phpnu [ [ "/includes/version.php", "/libraries/joomla/version.php", "/libraries/cms/version/version.php", "/libraries/src/Version.php", ], "regex_release" => "/\\\$?RELEASE\s*=\s*'([\d.]+)';/", "regex_devlevel" => "/\\\$?DEV_LEVEL\s*=\s*'([^']+)';/", "regex_major" => "/\\\$?MAJOR_VERSION\s*=\s*([\d.]+);/", "regex_minor" => "/\\\$?MINOR_VERSION\s*=\s*([\d.]+);/", "regex_patch" => "/\\\$?PATCH_VERSION\s*=\s*([\d.]+);/", ]; /** * @throws FilesystemException */ private function isJoomla(Filesystem $fs, string $path): bool { $configFile = rtrim($path, '/') . '/' . self::CONFIG_FILE; if (!$fs->fileExists($configFile)) { return false; } $configContents = $fs->read($configFile); if ( stripos($configContents, 'JConfig') === false && stripos($configContents, 'mosConfig') === false ) { return false; } // False positive "Akeeba Backup Installer" if (stripos($configContents, 'class ABIConfiguration') !== false) { return false; } // False positive mock file in unit test folder if (stripos($configContents, 'Joomla.UnitTest') !== false) { return false; } // False positive mock file in unit test folder return stripos($configContents, "Joomla\Framework\Test") === false; } /** * @throws FilesystemException */ private function detectVersion(Filesystem $fs, string $path): ?string { // Iterate through version files foreach (self::VERSION['files'] as $file) { $versionFile = rtrim($path, '/') . '/' . $file; if (!$fs->fileExists($versionFile)) { continue; } $fileContents = $fs->read($versionFile); preg_match(self::VERSION['regex_major'], $fileContents, $major); preg_match(self::VERSION['regex_minor'], $fileContents, $minor); preg_match(self::VERSION['regex_patch'], $fileContents, $patch); if (count($major) && count($minor) && count($patch)) { return $major[1] . '.' . $minor[1] . '.' . $patch[1]; } if (count($major) && count($minor)) { return $major[1] . '.' . $minor[1] . 'x'; } if ($major !== []) { return $major[1] . '.x.x'; } // Legacy handling for all version < 3.8.0 preg_match(self::VERSION['regex_release'], $fileContents, $release); preg_match(self::VERSION['regex_devlevel'], $fileContents, $devlevel); if (count($release) && count($devlevel)) { return $release[1] . '.' . $devlevel[1]; } if ($release !== []) { return $release[1] . '.x'; } } return null; } /** * @throws FilesystemException */ public function match(Filesystem $fs, string $path): MatchResultInterface { if (!$this->isJoomla($fs, $path)) { return new EmptyMatchResult(); } return new MatchResult($path, $this->detectVersion($fs, $path)); } } PK a_2]Kɑ Yii.phpnu [ 'yii', 'versionFile' => '/vendor/yiisoft/yii2/BaseYii.php', 'versionRegexp' => '/public static function getVersion\(\)\s*\{\s*return \'([^\']+)\';\s*}/', ], [ 'file' => 'framework/yiic', 'versionFile' => '/framework/YiiBase.php', 'versionRegexp' => '/public static function getVersion\(\)\s*\{\s*return \'([^\']+)\';\s*}/', ], ]; public function match(Filesystem $fs, string $path): MatchResultInterface { $path = rtrim($path, '/'); foreach (self::VERSIONS as $version) { if (!$fs->fileExists($path . '/' . $version['file'])) { continue; } return new MatchResult($path, $this->detectVersion($fs, $path, $version)); } return new EmptyMatchResult(); } private function detectVersion(Filesystem $fs, string $path, array $versionInfo): ?string { $version = null; $yii2VersionFile = $path . $versionInfo['versionFile']; if ($fs->fileExists($yii2VersionFile)) { preg_match($versionInfo['versionRegexp'], $fs->read($yii2VersionFile), $matches); if (isset($matches[1])) { $version = $matches[1]; } } return $version; } } PK a_2]S[ Symfony.phpnu [ fileExists($symfonyLockFile)) { return new EmptyMatchResult(); } $json = []; try { $json = json_decode($fs->read($symfonyLockFile), true, 512, JSON_THROW_ON_ERROR); } catch (JsonException) { // ignore symfony.lock errors } return new MatchResult($path, $json["symfony/framework-bundle"]["version"] ?? null); } } PK a_2] Sitepro.phpnu [ directoryExists($siteproFolderPath)) { return new EmptyMatchResult(); } $inspectorHelper = new InspectorHelper(); return $inspectorHelper->fileContainsString($fs, $rTrimPath . '/web.config', 'sitepro') || $inspectorHelper->fileContainsString($fs, $rTrimPath . '/.htaccess', 'sitepro') ? new MatchResult($path) : new EmptyMatchResult(); } } PK a_2]1 Typo3.phpnu [ 'typo3/sysext/core/Classes/Information/Typo3Version.php', 'regexp' => '/VERSION = \'(.*?)\'/', ], [ 'filename' => 'typo3/sysext/core/Classes/Core/SystemEnvironmentBuilder.php', 'regexp' => '/define\\(\'TYPO3_version\', \'(.*?)\'\\)/', ], [ 'filename' => 't3lib/config_default.php', 'regexp' => '/TYPO_VERSION = \'(.*?)\'/', ], ]; public function match(Filesystem $fs, string $path): MatchResultInterface { foreach (self::VERSIONS as $version) { $versionFile = rtrim($path, '/') . '/' . $version['filename']; if (!$fs->fileExists($versionFile)) { continue; } if ($version = $this->detectVersion($version['regexp'], $versionFile, $fs)) { return new MatchResult($path, $version); } } return new EmptyMatchResult(); } public function detectVersion(string $regexPattern, string $versionFile, Filesystem $fs): ?string { try { preg_match($regexPattern, $fs->read($versionFile), $matches); return count($matches) > 1 ? $matches[1] : null; } catch (FilesystemException) { // ignore file reading problem return null; } } } PK a_2]>} Python.phpnu [ listContents($path) as $item) { /** @var StorageAttributes $item */ if ($item->isFile() && str_ends_with($item->path(), '.py')) { return new MatchResult($path); } } return new EmptyMatchResult(); } } PK a_2]^\ Wordpress.phpnu [ read($versionFile), $matches); if ($matches !== []) { return $matches[1]; } return null; } /** * @throws FilesystemException */ private function isWordpress(Filesystem $fs, string $path): bool { $versionFile = rtrim($path, '/') . '/' . self::VERSION_FILE; if (!$fs->fileExists($versionFile)) { return false; } $fileContents = $fs->read($versionFile); return stripos($fileContents, '$wp_version =') !== false; } /** * @throws FilesystemException */ public function match(Filesystem $fs, string $path): MatchResultInterface { if (!$this->isWordpress($fs, $path)) { return new EmptyMatchResult(); } return new MatchResult($path, $this->detectVersion($fs, $path)); } } PK a_2]GqF Prestashop.phpnu [ '/config/settings.inc.php', 'regexp' => '/define\\(\'_PS_VERSION_\', \'(.+)\'\\)/', ], ]; /** * @throws FilesystemException */ public function match(Filesystem $fs, string $path): MatchResultInterface { foreach (self::VERSIONS as $version) { $versionFile = rtrim($path, '/') . '/' . $version['filename']; if (!$fs->fileExists($versionFile)) { continue; } return new MatchResult($path, $this->getVersion($version, $fs, $versionFile)); } return new EmptyMatchResult(); } public function getVersion(array $version, Filesystem $fs, string $versionFile): ?string { $result = null; try { if (preg_match($version['regexp'], $fs->read($versionFile), $matches) && count($matches) > 1) { $result = $matches[1]; } } catch (FilesystemException) { // ignore filesystem extensions } return $result; } } PK a_2] UpLevelMatcherTrait.phpnu [ safeScanDir($fs, $path); if ($matcher instanceof EmptyMatchResult) { $matcher = $this->safeScanDir($fs, rtrim($path) . '/../'); } return $matcher; } private function safeScanDir(Filesystem $fs, string $path): MatchResultInterface { try { $result = $this->doMatch($fs, $path); } catch (FilesystemException) { // skip dir if it is inaccessible $result = new EmptyMatchResult(); } return $result; } } PK a_2]?7 7 DotNet.phpnu [ listContents($path) as $item) { /** @var StorageAttributes $item */ if (!$item->isFile() || !str_ends_with($item->path(), '.dll')) { continue; } $handle = $fs->readStream($item->path()); $hex = bin2hex(fread($handle, 4)); if (str_contains($hex, self::HEX_SIGNATURE)) { return new MatchResult($path); } } return new EmptyMatchResult(); } } PK a_2] Ruby.phpnu [ fileExists(rtrim($path, '/') . '/' . self::RAKEFILE)) { return new EmptyMatchResult(); } return new MatchResult($path); } } PK a_2][ CakePHP.phpnu [ fileExists($path . '/bin/cake')) { return new EmptyMatchResult(); } $version = $this->detectVersion($fs, $path); return new MatchResult($path, $version); } private function detectVersion(Filesystem $fs, string $path): ?string { $version = null; $versionFile = $path . '/vendor/cakephp/cakephp/VERSION.txt'; if ($fs->fileExists($versionFile)) { $versionData = explode("\n", trim($fs->read($versionFile))); $version = trim(array_pop($versionData)); } return $version; } } PK a_2]њ8 CodeIgniter.phpnu [ fileExists($path . '/spark')) { return new EmptyMatchResult(); } return new MatchResult($path, $this->detectVersion($fs, $path)); } /** * @throws FilesystemException */ private function detectVersion(Filesystem $fs, string $path): ?string { $versionFile = $path . '/vendor/codeigniter4/framework/system/CodeIgniter.php'; if (!$fs->fileExists($versionFile)) { return null; } preg_match("/CI_VERSION\\s*=\\s*'([^']+)'/", $fs->read($versionFile), $matches); if ($matches !== []) { return $matches[1]; } return null; } } PK a_2]2 p Drupal.phpnu [ 'modules/system/system.info', 'regex' => "/version\\s*=\\s*\"(\\d\\.[^']+)\"[\\s\\S]*project\\s*=\\s*\"drupal\"/", ], [ 'file' => 'core/modules/system/system.info.yml', 'regex' => "/version:\\s*'(\\d+\\.[^']+)'[\\s\\S]*project:\\s*'drupal'/", ], ]; /** * @throws FilesystemException */ public function match(Filesystem $fs, string $path): MatchResultInterface { // Iterate through version patterns foreach (self::VERSIONS as $version) { $versionFile = rtrim($path, '/') . '/' . $version['file']; if (!$fs->fileExists($versionFile)) { continue; } $version = $this->detectVersion($version['regex'], $versionFile, $fs); return new MatchResult($path, $version); } return new EmptyMatchResult(); } private function detectVersion(string $regexPattern, string $versionFile, Filesystem $fs): ?string { preg_match($regexPattern, $fs->read($versionFile), $matches); return count($matches) ? $matches[1] : null; } } PK a_2]8c'W W MatcherInterface.phpnu [ getPath($path); if (!$fs->fileExists($composerJsonFile)) { return new EmptyMatchResult(); } $json = []; try { $json = json_decode($fs->read($composerJsonFile), true, 512, JSON_THROW_ON_ERROR); } catch (JsonException) { // ignore composer.json errors } return new MatchResult($path, $json['version'] ?? 'dev', $json['name'] ?? 'unknown'); } } PK a_2]UMe!H H Php.phpnu [ listContents($path); foreach ($list as $item) { /** @var StorageAttributes $item */ if ($item->isFile() && str_ends_with($item->path(), '.php')) { return new MatchResult($path); } if ($item->isDir() && $item->path() === ltrim(rtrim($path, '/') . '/src', '/')) { return $this->match($fs, rtrim($path, '/') . '/src'); } } } catch (FilesystemException) { // skip dir if it is inaccessible } return new EmptyMatchResult(); } } PK a_2]-* * Siteplus.phpnu [ fileContainsString($fs, $rTrimPath . '/index.html', 'edit.site')) { return new EmptyMatchResult(); } if (!$fs->directoryExists($rTrimPath . self::PUBLISH_DIR_PATH)) { return new EmptyMatchResult(); } $publishDirList = $fs->listContents($rTrimPath . self::PUBLISH_DIR_PATH, false); // do not check if the item is a directory as on the server when the files a copied the type of the // directory is determined as 'file'. // By default, there should be just 1 directory in the publish directory $versionDirPath = $publishDirList->toArray()[0]['path'] ?? null; if ($versionDirPath === null) { return new EmptyMatchResult(); } return $inspectorHelper->fileContainsString($fs, $versionDirPath . '/bundle.js', 'siteplus') ? new MatchResult($rTrimPath, $this->getSiteplusVersion($versionDirPath)) : new EmptyMatchResult(); } private function getSiteplusVersion(string $versionDirPath): string { // get the last part of the path $versionDirPathParts = explode('/', $versionDirPath); return end($versionDirPathParts); } } PK a_2]^Z WebPresenceBuilder.phpnu [ fileExists($indexHtmlPath)) { return new EmptyMatchResult(); } $fileContent = $fs->read($indexHtmlPath); $inspectorHelper = new InspectorHelper(); return $inspectorHelper->fileContentMatchesString( $fileContent, '//' ) || $this->fileContainsDOMStructure($fileContent) ? new MatchResult($path) : new EmptyMatchResult(); } private function fileContainsDOMStructure(string $fileContent): bool { $dom = new DOMDocument(); try { libxml_use_internal_errors(true); $domIsLoaded = $dom->loadHTML($fileContent); libxml_clear_errors(); } catch (Throwable) { return false; } if ($domIsLoaded === false) { return false; } $xpath = new DOMXPath($dom); // Find the