From bf57c0122cdf6da7a509be8bca12d4350c50ac8a Mon Sep 17 00:00:00 2001 From: Ryan Roden-Corrent Date: Mon, 28 Dec 2020 12:57:55 -0500 Subject: Don't crash on long search patterns. Entering an overly long search term into the completion causes a crash: ``` PyQt5.QtCore.QRegularExpression.PatternOptions(1)) is not valid: regular expression is too large ``` This can happen, for example, when pressing `go` at the qutebrowser error page. I'm unclear on exactly what the limit is, but 50k characters seems to trip it on my machine. Still, it seems like any pattern larger than a certain amount is likely an error, so I settled on limiting it to 5k. Fixes #5973 --- qutebrowser/completion/models/listcategory.py | 3 +++ tests/unit/completion/test_listcategory.py | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/qutebrowser/completion/models/listcategory.py b/qutebrowser/completion/models/listcategory.py index d4193b6d8..8b52f97d0 100644 --- a/qutebrowser/completion/models/listcategory.py +++ b/qutebrowser/completion/models/listcategory.py @@ -63,6 +63,9 @@ class ListCategory(QSortFilterProxyModel): val = re.sub(r' +', r' ', val) # See #1919 val = re.escape(val) val = val.replace(r'\ ', '.*') + if len(val) > 5000: # avoid crash on huge search terms (#5973) + log.completion.warning("Pattern too long ({})".format(len(val))) + val = "^$" rx = QRegularExpression(val, QRegularExpression.CaseInsensitiveOption) qtutils.ensure_valid(rx) self.setFilterRegularExpression(rx) diff --git a/tests/unit/completion/test_listcategory.py b/tests/unit/completion/test_listcategory.py index 1a54ac814..3a4fa895d 100644 --- a/tests/unit/completion/test_listcategory.py +++ b/tests/unit/completion/test_listcategory.py @@ -20,6 +20,7 @@ """Tests for CompletionFilterModel.""" import pytest +import logging from qutebrowser.completion.models import listcategory @@ -57,3 +58,9 @@ def test_set_pattern(pattern, before, after, after_nosort, model_validator): model_validator.set_model(cat) cat.set_pattern(pattern) model_validator.validate(after_nosort) + + +def test_long_pattern(caplog): + """Validate that a huge pattern doesn't crash (#5973).""" + with caplog.at_level(logging.WARNING): + listcategory.ListCategory('Foo', []).set_pattern('a' * 50000) -- cgit v1.2.3-54-g00ecf From 4123cda88a7de7c200072fa78cadfd88b3b450e4 Mon Sep 17 00:00:00 2001 From: Ryan Roden-Corrent Date: Mon, 28 Dec 2020 17:08:49 -0500 Subject: Use f-string for log line. Co-authored-by: Florian Bruhin --- qutebrowser/completion/models/listcategory.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qutebrowser/completion/models/listcategory.py b/qutebrowser/completion/models/listcategory.py index 8b52f97d0..307e1ec33 100644 --- a/qutebrowser/completion/models/listcategory.py +++ b/qutebrowser/completion/models/listcategory.py @@ -64,7 +64,7 @@ class ListCategory(QSortFilterProxyModel): val = re.escape(val) val = val.replace(r'\ ', '.*') if len(val) > 5000: # avoid crash on huge search terms (#5973) - log.completion.warning("Pattern too long ({})".format(len(val))) + log.completion.warning(f"Pattern too long ({len(val)})") val = "^$" rx = QRegularExpression(val, QRegularExpression.CaseInsensitiveOption) qtutils.ensure_valid(rx) -- cgit v1.2.3-54-g00ecf From faa4d519301e5399dd7ef0fef344d28845ccd1d4 Mon Sep 17 00:00:00 2001 From: Ryan Roden-Corrent Date: Mon, 28 Dec 2020 18:20:26 -0500 Subject: Trim long patterns rather than clearing them. Fixes #5973. --- qutebrowser/completion/models/listcategory.py | 6 +++--- tests/unit/completion/test_listcategory.py | 7 +++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/qutebrowser/completion/models/listcategory.py b/qutebrowser/completion/models/listcategory.py index 307e1ec33..fbe742ddb 100644 --- a/qutebrowser/completion/models/listcategory.py +++ b/qutebrowser/completion/models/listcategory.py @@ -59,13 +59,13 @@ class ListCategory(QSortFilterProxyModel): Args: val: The value to set. """ + if len(val) > 5000: # avoid crash on huge search terms (#5973) + log.completion.warning(f"Trimming {len(val)}-char pattern to 5000") + val = val[:5000] self._pattern = val val = re.sub(r' +', r' ', val) # See #1919 val = re.escape(val) val = val.replace(r'\ ', '.*') - if len(val) > 5000: # avoid crash on huge search terms (#5973) - log.completion.warning(f"Pattern too long ({len(val)})") - val = "^$" rx = QRegularExpression(val, QRegularExpression.CaseInsensitiveOption) qtutils.ensure_valid(rx) self.setFilterRegularExpression(rx) diff --git a/tests/unit/completion/test_listcategory.py b/tests/unit/completion/test_listcategory.py index 3a4fa895d..b00ab595e 100644 --- a/tests/unit/completion/test_listcategory.py +++ b/tests/unit/completion/test_listcategory.py @@ -60,7 +60,10 @@ def test_set_pattern(pattern, before, after, after_nosort, model_validator): model_validator.validate(after_nosort) -def test_long_pattern(caplog): +def test_long_pattern(caplog, model_validator): """Validate that a huge pattern doesn't crash (#5973).""" with caplog.at_level(logging.WARNING): - listcategory.ListCategory('Foo', []).set_pattern('a' * 50000) + cat = listcategory.ListCategory('Foo', [('a' * 5000, '')]) + model_validator.set_model(cat) + cat.set_pattern('a' * 50000) + model_validator.validate([('a' * 5000, '')]) -- cgit v1.2.3-54-g00ecf From ba1bbd555c6869215c56490c595f20259c311744 Mon Sep 17 00:00:00 2001 From: Ryan Roden-Corrent Date: Tue, 29 Dec 2020 07:35:44 -0500 Subject: Correct import order (pylint). --- tests/unit/completion/test_listcategory.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/unit/completion/test_listcategory.py b/tests/unit/completion/test_listcategory.py index b00ab595e..d2eeaeb24 100644 --- a/tests/unit/completion/test_listcategory.py +++ b/tests/unit/completion/test_listcategory.py @@ -19,9 +19,10 @@ """Tests for CompletionFilterModel.""" -import pytest import logging +import pytest + from qutebrowser.completion.models import listcategory -- cgit v1.2.3-54-g00ecf