From d70e500ce7c63f3f4f1a504dfaae1ac537775f1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Andr=C3=A9?= Date: Sat, 27 Jan 2024 16:10:44 +0100 Subject: [PATCH] [AssetMapper] Fix JavaScript compiler load imports from JS strings --- .../Compiler/JavaScriptImportPathCompiler.php | 9 ++- .../JavaScriptImportPathCompilerTest.php | 58 +++++++++++++++++++ 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/AssetMapper/Compiler/JavaScriptImportPathCompiler.php b/src/Symfony/Component/AssetMapper/Compiler/JavaScriptImportPathCompiler.php index 090b1dc7847c1..be81a58027edf 100644 --- a/src/Symfony/Component/AssetMapper/Compiler/JavaScriptImportPathCompiler.php +++ b/src/Symfony/Component/AssetMapper/Compiler/JavaScriptImportPathCompiler.php @@ -27,8 +27,8 @@ */ final class JavaScriptImportPathCompiler implements AssetCompilerInterface { - // https://regex101.com/r/fquriB/1 - private const IMPORT_PATTERN = '/(?:import\s*(?:(?:\*\s*as\s+\w+|[\w\s{},*]+)\s*from\s*)?|\bimport\()\s*[\'"`](\.\/[^\'"`]+|(\.\.\/)*[^\'"`]+)[\'"`]\s*[;\)]?/m'; + // https://regex101.com/r/qFoeoR/1 + private const IMPORT_PATTERN = '/(?:\'(?:[^\'\\\\]|\\\\.)*\'|"(?:[^"\\\\]|\\\\.)*")|(?:import\s*(?:(?:\*\s*as\s+\w+|[\w\s{},*]+)\s*from\s*)?|\bimport\()\s*[\'"`](\.\/[^\'"`]+|(\.\.\/)*[^\'"`]+)[\'"`]\s*[;\)]?/m'; public function __construct( private readonly ImportMapConfigReader $importMapConfigReader, @@ -42,6 +42,11 @@ public function compile(string $content, MappedAsset $asset, AssetMapperInterfac return preg_replace_callback(self::IMPORT_PATTERN, function ($matches) use ($asset, $assetMapper, $content) { $fullImportString = $matches[0][0]; + // Ignore enquoted strings (e.g. console.log("import 'foo';") + if (!isset($matches[1][0])) { + return $fullImportString; + } + if ($this->isCommentedOut($matches[0][1], $content)) { return $fullImportString; } diff --git a/src/Symfony/Component/AssetMapper/Tests/Compiler/JavaScriptImportPathCompilerTest.php b/src/Symfony/Component/AssetMapper/Tests/Compiler/JavaScriptImportPathCompilerTest.php index c0894825b62aa..e616211b5b9dc 100644 --- a/src/Symfony/Component/AssetMapper/Tests/Compiler/JavaScriptImportPathCompilerTest.php +++ b/src/Symfony/Component/AssetMapper/Tests/Compiler/JavaScriptImportPathCompilerTest.php @@ -67,6 +67,7 @@ public function testCompileFindsCorrectImports(string $input, array $expectedJav ->method('getAssetFromSourcePath') ->willReturnCallback(function ($path) { return match ($path) { + '/project/assets/foo.js' => new MappedAsset('foo.js', '/can/be/anything.js', publicPathWithoutDigest: '/assets/foo.js'), '/project/assets/other.js' => new MappedAsset('other.js', '/can/be/anything.js', publicPathWithoutDigest: '/assets/other.js'), '/project/assets/subdir/foo.js' => new MappedAsset('subdir/foo.js', '/can/be/anything.js', publicPathWithoutDigest: '/assets/subdir/foo.js'), '/project/assets/styles.css' => new MappedAsset('styles.css', '/can/be/anything.js', publicPathWithoutDigest: '/assets/styles.css'), @@ -269,6 +270,63 @@ public static function provideCompileTests(): iterable 'expectedJavaScriptImports' => ['/assets/other.js' => ['lazy' => true, 'asset' => 'other.js', 'add' => true]], ]; + yield 'import_in_double_quoted_string_is_ignored' => [ + 'input' => << [], + ]; + + yield 'import_in_double_quoted_string_with_escaped_quote_is_ignored' => [ + 'input' => << [], + ]; + + yield 'import_in_single_quoted_string_is_ignored' => [ + 'input' => << [], + ]; + + yield 'import_after_a_string_is_parsed' => [ + 'input' => << ['/assets/foo.js' => ['lazy' => true, 'asset' => 'foo.js', 'add' => true]], + ]; + + yield 'import_before_a_string_is_parsed' => [ + 'input' => << ['/assets/other.js' => ['lazy' => true, 'asset' => 'other.js', 'add' => true]], + ]; + + yield 'import_before_and_after_a_string_is_parsed' => [ + 'input' => << [ + '/assets/other.js' => ['lazy' => true, 'asset' => 'other.js', 'add' => true], + '/assets/subdir/foo.js' => ['lazy' => true, 'asset' => 'subdir/foo.js', 'add' => true], + ], + ]; + yield 'bare_import_not_in_importmap' => [ 'input' => 'import "some_module";', 'expectedJavaScriptImports' => [], pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy