babel / minify

:scissors: An ES6+ aware minifier based on the Babel toolchain (beta)
https://babeljs.io/repl
MIT License
4.39k stars 225 forks source link

minify-dead-code-elimination cause regexp match infinite loop. #981

Closed andycall closed 2 years ago

andycall commented 4 years ago

Describe the bug

To Reproduce

Minimal code to reproduce the bug

function getElementTransforms(el) {
  if (!is.dom(el)) return;
  const str = el.style.transform || '';
  const reg = /(\w+)\(([^)]*)\)/g;
  const transforms = new Map();
  let m; while (m = reg.exec(str)) transforms.set(m[1], m[2]);
  return transforms;
}

Actual Output

If there is no Error thrown,

function getElementTransforms(el) {
  if (!is.dom(el)) return;
  var str = el.style.transform || '';
  var transforms = new Map();
  var m;

  while (m = /(\w+)\(([^)]*)\)/g.exec(str)) {
    transforms.set(m[1], m[2]);
  }

  return transforms;
}

Expected Output

function getElementTransforms(el) {
  if (!is.dom(el)) return;
  var str = el.style.transform || '';
  var reg = /(\w+)\(([^)]*)\)/g;
  var transforms = new Map();
  var m;

  while (m = reg.exec(str)) {
    transforms.set(m[1], m[2]);
  }

  return transforms;
}

Configuration Can be reproduce Using Babel's Online Try Out

babel-minify CLI

babel-plugin-minify-dead-code-elimination: 0.5.1

babel version : 7.9.0

babel-minify-config: default without config

kingback commented 4 years ago

Yes,It breaks while compile querystringify https://github.com/unshiftio/querystringify/blob/master/index.js#L48

wssgcg1213 commented 4 years ago

@kingback In our situation, we pass the compile, but make chrome 100% CPU usage and block debugging :(

kingback commented 4 years ago

@kingback In our situation, we pass the compile, but make chrome 100% CPU usage and block debugging :(

bug code

use resolutions to lock the version of @babel/types, it works for me

{
  "resolutions": {
    "@babel/types": "7.8.7"
  }
}
JLHwung commented 4 years ago

As a workaround, you may replace regexp literal by constructor calls:

--- const reg = /(\w+)\(([^)]*)\)/g;
+++ const reg = new RegExp("(\w+)\(([^)]*)\)", "g");
ChrisCindy commented 4 years ago

Should the plugin provide an option called like 'keepVariable' that doesn't eliminate variables that can be eliminated after evaluating expressions ? We have met the situation that the variables can't be replaced by its value. @JLHwung

ehoogeveen-medweb commented 4 years ago

It seems strange to me that babel-plugin-minify-dead-code-elimination is even doing anything here - after all, the code isn't dead.

Replacing named constants that are only used in one place seems like a reasonable thing to do in general, but I would expect a different plugin to be responsible for it.

mwgamble commented 4 years ago

I just ran into this with jQuery. It causes an infinite loop which makes the entire page unresponsive.

neemzy commented 3 years ago

I just ran into this with jQuery. It causes an infinite loop which makes the entire page unresponsive.

Same here!