Repository navigation
Python 3.11.0b3 chockes on regex sub from rjsmin, time grows seemingly exponentially #94675
Copy link
Copy link
Closed
Closed
Copy link
Labels
testsTests in the Lib/test dirTests in the Lib/test dirtopic-regextype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Description
Bug report
When building chromium in Fedora 37 with Python 3.11.0b3, the build hangs seemingly forever.
While isolating the hang, we've noticed it happens in rjsmin, at https://github.com/ndparker/rjsmin/blob/1.2.0/rjsmin.py#L361
I've further reduced the javascript input as much as I could but I kept the regex pattern intact.
Here's the reporucer:
import re, sys
# pattern from rjsmin
# Copyright 2011 - 2021 André Malo or his licensors, as applicable.
# Apache License Version 2.0
# https://github.com/ndparker/rjsmin/blob/1.2.0/rjsmin.py#L196
pattern = '(?<=[(,=:\\[!&|?{};\\r\\n+*-])(?:[\\000-\\011\\013\\014\\016-\\040]|(?:/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/))*(?:(?:(?://[^\\r\\n]*)?[\\r\\n])(?:[\\000-\\011\\013\\014\\016-\\040]|(?:/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/))*)*((?:/(?![\\r\\n/*])[^/\\\\\\[\\r\\n]*(?:(?:\\\\[^\\r\\n]|(?:\\[[^\\\\\\]\\r\\n]*(?:\\\\[^\\r\\n][^\\\\\\]\\r\\n]*)*\\]))[^/\\\\\\[\\r\\n]*)*/[a-z]*))((?:[\\000-\\011\\013\\014\\016-\\040]|(?:/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/))*(?:(?:(?://[^\\r\\n]*)?[\\r\\n])(?:[\\000-\\011\\013\\014\\016-\\040]|(?:/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/))*)+(?=[^\\000-\\040&)+,.:;=?\\]|}-]))?'
# (originally reported as) pattern = '([^\\047"\\140/\\000-\\040]+)|((?:(?:\\047[^\\047\\\\\\r\\n]*(?:\\\\(?:[^\\r\\n]|\\r?\\n|\\r)[^\\047\\\\\\r\\n]*)*\\047)|(?:"[^"\\\\\\r\\n]*(?:\\\\(?:[^\\r\\n]|\\r?\\n|\\r)[^"\\\\\\r\\n]*)*")|(?:\\140[^\\140\\\\]*(?:\\\\(?:[^\\r\\n]|\\r?\\n|\\r)[^\\140\\\\]*)*\\140))[^\\047"\\140/\\000-\\040]*)|(?<=[)])(?:[\\000-\\011\\013\\014\\016-\\040]|(?:/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/))*(?:(?:(?://[^\\r\\n]*)?[\\r\\n])(?:[\\000-\\011\\013\\014\\016-\\040]|(?:/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/))*)*((?:/(?![\\r\\n/*])[^/\\\\\\[\\r\\n]*(?:(?:\\\\[^\\r\\n]|(?:\\[[^\\\\\\]\\r\\n]*(?:\\\\[^\\r\\n][^\\\\\\]\\r\\n]*)*\\]))[^/\\\\\\[\\r\\n]*)*/[a-z]*))(?=(?:[\\000-\\011\\013\\014\\016-\\040]|(?:/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/))*(?:(?:(?://[^\\r\\n]*)?[\\r\\n])(?:[\\000-\\011\\013\\014\\016-\\040]|(?:/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/))*)*\\.(?:[\\000-\\011\\013\\014\\016-\\040]|(?:/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/))*(?:(?:(?://[^\\r\\n]*)?[\\r\\n])(?:[\\000-\\011\\013\\014\\016-\\040]|(?:/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/))*)*[a-z])|(?<=[(,=:\\[!&|?{};\\r\\n+*-])(?:[\\000-\\011\\013\\014\\016-\\040]|(?:/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/))*(?:(?:(?://[^\\r\\n]*)?[\\r\\n])(?:[\\000-\\011\\013\\014\\016-\\040]|(?:/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/))*)*((?:/(?![\\r\\n/*])[^/\\\\\\[\\r\\n]*(?:(?:\\\\[^\\r\\n]|(?:\\[[^\\\\\\]\\r\\n]*(?:\\\\[^\\r\\n][^\\\\\\]\\r\\n]*)*\\]))[^/\\\\\\[\\r\\n]*)*/[a-z]*))((?:[\\000-\\011\\013\\014\\016-\\040]|(?:/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/))*(?:(?:(?://[^\\r\\n]*)?[\\r\\n])(?:[\\000-\\011\\013\\014\\016-\\040]|(?:/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/))*)+(?=[^\\000-\\040&)+,.:;=?\\]|}-]))?|(?<=[\\000-#%-,./:-@\\[-^\\140{-~-]return)(?:[\\000-\\011\\013\\014\\016-\\040]|(?:/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/))*(?:((?:(?://[^\\r\\n]*)?[\\r\\n]))(?:[\\000-\\011\\013\\014\\016-\\040]|(?:/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/))*)*((?:/(?![\\r\\n/*])[^/\\\\\\[\\r\\n]*(?:(?:\\\\[^\\r\\n]|(?:\\[[^\\\\\\]\\r\\n]*(?:\\\\[^\\r\\n][^\\\\\\]\\r\\n]*)*\\]))[^/\\\\\\[\\r\\n]*)*/[a-z]*))((?:[\\000-\\011\\013\\014\\016-\\040]|(?:/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/))*(?:(?:(?://[^\\r\\n]*)?[\\r\\n])(?:[\\000-\\011\\013\\014\\016-\\040]|(?:/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/))*)+(?=[^\\000-\\040&)+,.:;=?\\]|}-]))?|(?<=[^\\000-!#%&(*,./:-@\\[\\\\^{|~])(?:[\\000-\\011\\013\\014\\016-\\040]|(?:/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/))*(?:((?:(?://[^\\r\\n]*)?[\\r\\n]))(?:[\\000-\\011\\013\\014\\016-\\040]|(?:/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/))*)+(?=[^\\000-\\040"#%-\\047)*,./:-@\\\\-^\\140|-~])|(?<=[^\\000-#%-,./:-@\\[-^\\140{-~-])((?:[\\000-\\011\\013\\014\\016-\\040]|(?:/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/)))+(?=[^\\000-#%-,./:-@\\[-^\\140{-~-])|(?<=\\+)((?:[\\000-\\011\\013\\014\\016-\\040]|(?:/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/)))+(?=\\+)|(?<=-)((?:[\\000-\\011\\013\\014\\016-\\040]|(?:/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/)))+(?=-)|(?:[\\000-\\011\\013\\014\\016-\\040]|(?:/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/))+|(?:(?:(?://[^\\r\\n]*)?[\\r\\n])(?:[\\000-\\011\\013\\014\\016-\\040]|(?:/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/))*)+'
input_data = """a(function() {{
{}
}});
""".format('/' * int(sys.argv[1]))
print(re.compile(pattern).sub('', input_data))The original input reduced from Chromium's JavaScript file looks like:
a(function() {
//////////////////////////////////////////////////////////////////////////
}); And here how long it takes with Python 3.10.5 and 3.11.0b3 for a reduced number of slashes.
$ time python3.10 reproducer.py 30
real 0m0,033s
$ time python3.11 reproducer.py 30
real 0m0,082s
$ time python3.10 reproducer.py 40
real 0m0,034s
$ time python3.11 reproducer.py 40
real 0m6,902s
$ time python3.10 reproducer.py 45
real 0m0,032s
$ time python3.11 reproducer.py 45
real 1m25,004s
$ time python3.10 reproducer.py 50
real 0m0,031s
$ time python3.11 reproducer.py 50
??? killed after 10+ minutes
For 74 slashes, I guess it would run forever.
Your environment
- CPython versions tested on: 3.11.0b3
- Operating system and architecture: Fedora Linux 35 or 37, x86_64
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
testsTests in the Lib/test dirTests in the Lib/test dirtopic-regextype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Activity
hroncok commentedon Jul 7, 2022
A more "real" example is to pipe the javascript input to https://github.com/ndparker/rjsmin/blob/1.2.0/rjsmin.py
hroncok commentedon Jul 7, 2022
I've simplified the regex to:
The following ones are even shorter and exhibit the same behavior but slightly different times, so I am not editing it in the original report:
hauntsaninja commentedon Jul 8, 2022
Can you repro on latest main?
A slowdown in Chromium build was previously reported here #91404 (comment)
I believe #93928 did not make beta 3
hauntsaninja commentedon Jul 8, 2022
(If #93928 did indeed fix, it would be nice to add your reduced example as a test case!)
hroncok commentedon Jul 8, 2022
Will test.
hroncok commentedon Jul 8, 2022
This is fixed on main.
hroncok commentedon Jul 8, 2022
#93928 also fixes it on 3.11
[-]Python 3.11 chockes on regex sub from rjsmin, time grows seemingly exponentially[/-][+]Python 3.11.0b3 chockes on regex sub from rjsmin, time grows seemingly exponentially[/+]hroncok commentedon Jul 8, 2022
@hauntsaninja Any idea how are the "does not take too long" cases handled in cpython tests?
hroncok commentedon Jul 8, 2022
I've added #94685 -- hoping that the general timeout thing would stop it on b3
fixup! pythongh-94675: Add a regression test for rjsmin re slowdown
00385: pythongh-91404: Revert "bpo-23689: re module, fix memory leak..."
00385: pythongh-94675: Add a regression test for rjsmin re slowdown
00385: pythongh-94675: Add a regression test for rjsmin re slowdown
pythongh-94675: Add a regression test for rjsmin re slowdown (pythonG…
gh-94675: Add a regression test for rjsmin re slowdown (GH-94685)
gh-94675: Add a regression test for rjsmin re slowdown (GH-94685)
kumaraditya303 commentedon Aug 10, 2022
Fixed by #94685
Fix speed regression in the re module which prevented chromium from b…