Hi Drupal folks,

Couple of moths ago i came across a rare issue with the JsOptimizer the generated .JS file was empty.
After a few hours of debugging i came across the JsOptimizer::clean regex and saw that it gave NULL back as return.

$contents = preg_replace('/\/\/(#|@)\s(sourceURL|sourceMappingURL)=\s*(\S*?)\s*$/m', '', $contents);

No errors or notices in the logging what so ever, but i guess it was the "Backtracking limit" that the issue because there where a lot of javascript files that was optimised to one file. So i decide to rewrite the preg_replace to this one:

$contents = preg_replace('/\/\/(#|@)\s(sourceURL|sourceMappingURL)=\s*[^$\s]*\s*$/m', '', $contents);

And everything was working, i didn't have a test case with sourceURL|sourceMappingURL so thats needs to be tested if the preg_replace is working. I added the patch in this issue that we are using right now with success.

PHP Version: 7.1.x
Drupal version: 8.5.x

Issue fork drupal-2990907

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

Lennard Westerveld created an issue. See original summary.

lennard westerveld’s picture

lennard westerveld’s picture

Issue summary: View changes

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

heddn’s picture

Status: Active » Needs work
Issue tags: +Needs tests

Yes, this is an issue. I can confirm it. In my case, I had several minified vendor js files that all had source maps. This fixed it. Still needs tests. So back to NW.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

codebymikey made their first commit to this issue’s fork.

codebymikey’s picture

Version: 8.9.x-dev » 9.3.x-dev

Did some sandboxing over various regexes, and the best way to address this is to do away with any backtracking whatsoever.

Source: https://stackoverflow.com/a/36629670

And sandbox for various regexes: https://3v4l.org/JagL4

codebymikey’s picture

Status: Needs work » Needs review
StatusFileSize
new2.75 KB
new2.11 KB

Attached a patch and test for the new non-backtracking regex.

codebymikey’s picture

Issue tags: -Needs tests

Status: Needs review » Needs work
codebymikey’s picture

Status: Needs work » Needs review
StatusFileSize
new2.11 KB

Use an appropriately named test-only-fail patch so as not to trigger the "Needs work" tag.

Edit: This was a misconception on my part, Drupal apparently doesn't have a convention for skipping the "Needs work" tag trigger.

Status: Needs review » Needs work
codebymikey’s picture

Status: Needs work » Needs review
codebymikey’s picture

Status: Needs review » Needs work

The proposed patch breaks the page if the javascript happens to contain:

// ...
(t.evaluate||Ht).source+"|$","g"),p="//# sourceURL="+(bl.call(t,"sourceURL")?(t.sourceURL+"").replace(/\s/g," "):"lodash.templateSources["+ ++Zr+"]")+"\n";
// ...

e.g. https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js

The regex needs to only match against the last line rather than attempt to match potential sourceMaps located in the middle of the code.

szeidler’s picture

I can confirm the issue and the observation in #16 when applying the patch.

Edit: In my case I was able to fix it, by running webpack in production mode, so that sourcemaps have not been created. But that only works as long you have problem in your own scope. The general problem still exists. In my case it was also the lodash library.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

notfloran’s picture

I confirm the observation of szeidler, after running webpack in production mode the problem is gone.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

joseph.olstad’s picture

Status: Needs work » Needs review
StatusFileSize
new2.75 KB
new2.11 KB

straight reroll

joseph.olstad’s picture

Status: Needs review » Reviewed & tested by the community

RTBC:

has tests, passes tests

tests only fails

Related issues are linked

The last submitted patch, 24: 2990907-24.patch, failed testing. View results

catch’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/tests/Drupal/Tests/Core/Asset/JsOptimizerUnitTest.php
@@ -75,6 +75,35 @@ public function testClean($js_asset, $expected) {
+  /**
+   * Tests that the javascript may be cleaned without backtracking.
+   */
+  public function testCleanWithRecursionLimit() {
+    // Specify a hard backtracking limit.
+    ini_set('pcre.backtrack_limit', 100);
+    $backtrack_limit = (int) ini_get('pcre.backtrack_limit');
+    $this->assertEquals(100, $backtrack_limit);
+    $script = <<<JS
+(function($) { "use strict"; })
+//# sourceMappingURL=data:application/json;charset=utf-8;base64,
+JS;
+    // Generate a source map URL that would exceed the backtrack limit.
+    $script .= str_repeat('x', $backtrack_limit);
+    // Add an empty space after the sourcemap, followed by other
+    // miscellaneous code.
+    $script .= <<<JS
+ // I appear after the sourcemap URL.
+(function($) { "use strict"; console.log('Hello'); })
+JS;
+    $expected_script = <<<JS
+(function($) { "use strict"; })
+// I appear after the sourcemap URL.
+(function($) { "use strict"; console.log('Hello'); })
+JS;
+
+    $this->assertEquals($expected_script, $this->optimizer->clean($script));
+  }
+

Overall this looks good but the regexp is trying to find both sourceURL and sourceMappingURL so I think we should probably have coverage for both?

It could be an extra method with nearly identical content or maybe one method with a data provider.

codebymikey’s picture

I think we'd ideally also have test coverage for the issue raised in #16 when the source code itself contains //# sourceURL= in a string, but should not be stripped.

codebymikey’s picture

Issue tags: +Need tests
catch’s picture

@codebymikey yes I think that's needed too.

catch’s picture

Actually I wonder if this code is needed at all with Peast - if it strips this already, then we don't need the regexp?

dieterholvoet made their first commit to this issue’s fork.

dieterholvoet’s picture

I rebased the last patch and added it to a MR.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.