CSS file of 320 bytes takes 10+ seconds to parse
- Vorherrschende Sprache
- Python
- Sterne
- 92
- Forks
- 30
- PR-Merge-Kennzahlen
- Keine gemergten PRs in 30 T.
Beschreibung
I've encountered CSS file which `cssutils` library takes lots of seconds to parse (in fact, almost infinite).
After some investigation I've minified problematic sample (as possible) and prepared reproducible code example.
On my laptop (core i7-8550U) it takes **14 seconds** to parse file with just one line and 320 bytes of text.
Original file has 20kBytes of text and parser does not finish it in several hours.
Code:
https://gist.github.com/vdmit/ef9007170fa1c616cf5aba1fcebfce87
I'm using:
- latest stable `cssutils` release 2.3.0 from pypi repo
- python 3.8.10
- Ubuntu 20.04 linux distribution.
Notes:
- original CSS file was malformed and even contained non-printable characters. My minified example is still not valid CSS file, but it is a plain ANSI file.
- Adding line break in any place fixes problem;
- Removing of last style expression (`.s11...` reduces execution time from 14 seconds to 3 seconds).
- Adding of one more style expression increases execution time from 14 seconds to 50, 2 more styles yields ~260 seconds.
So, there is a **exponential** complexity somewhere, which is strange.
Traceback of interrupted script is following:
```python3 cssutils_infinite_loop_bug_example.py
Traceback (most recent call last):
File "cssutils_infinite_loop_bug_example.py", line 10, in
sheet = css_parser.parseString(cssText=css_text)
File "/home/vdmit/.local/lib/python3.8/site-packages/cssutils/parse.py", line 147, in parseString
sheet._setCssTextWithEncodingOverride(
File "/home/vdmit/.local/lib/python3.8/site-packages/cssutils/css/cssstylesheet.py", line 408, in _setCssTextWithEncodingOverride
self.cssText = cssText
File "/home/vdmit/.local/lib/python3.8/site-packages/cssutils/css/cssstylesheet.py", line 331, in _setCssText
wellformed, expected = self._parse(
File "/home/vdmit/.local/lib/python3.8/site-packages/cssutils/util.py", line 484, in _parse
expected = p(expected, seq, token, tokenizer)
File "/home/vdmit/.local/lib/python3.8/site-packages/cssutils/css/cssstylesheet.py", line 313, in ruleset
rule.cssText = self._tokensupto2(tokenizer, token)
File "/home/vdmit/.local/lib/python3.8/site-packages/cssutils/util.py", line 343, in _tokensupto2
for token in tokenizer:
File "/home/vdmit/.local/lib/python3.8/site-packages/cssutils/tokenize2.py", line 172, in tokenize
match = matcher(text, pos) # if no match try next production
KeyboardInterrupt
```
Beitragsleitfaden
Für dieses Repository ist kein Beitragsleitfaden indexiert
Rechercherichtung
Beginne mit dem verknüpften reproduzierbaren Beispiel und verfolge den gemeldeten Pfad durch cssutils/parse.py, cssutils/css/cssstylesheet.py, util.py und tokenize2.py. Führe Benchmarks für das Beispiel durch, während du Zeilenumbrüche und Stilausdrücke variierst, und füge einen Regressionstest hinzu, der zeigt, dass die Eingabe keine exponentielle Parsing-Zeit mehr hat.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- python
- Bereich
- performance
- Issue-Typ
- Bug
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Aktivitätsstatus
- Veraltet
- Klarheit
- Größtenteils klar
- Anfängerfreundlichkeit
- 42/100