CSS file of 320 bytes takes 10+ seconds to parse
- Lingua principale
- Python
- Stelle
- 92
- Fork
- 30
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Descrizione
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
```
Guida per i contributori
Nessuna guida per i contributori indicizzata per questo repository
Direzione di ricerca
Inizia con l'esempio riproducibile collegato e traccia il percorso segnalato attraverso cssutils/parse.py, cssutils/css/cssstylesheet.py, util.py e tokenize2.py. Esegui benchmark sull'esempio variando le interruzioni di riga e le espressioni di stile, quindi aggiungi un test di regressione che mostri che l'input non ha più un tempo di parsing esponenziale.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- python
- Ambito
- performance
- Tipo di issue
- Bug
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Stato di attività
- Ferma
- Chiarezza
- Abbastanza chiara
- Idoneità per principianti
- 42/100