From 3cdba90bb04642b7ccf9a182347b172225b51933 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Thu, 24 Feb 2022 21:06:28 +0100 Subject: [PATCH 1/5] Fix document margin recursion error (#1007) --- novelwriter/gui/doceditor.py | 2 +- novelwriter/gui/docviewer.py | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/novelwriter/gui/doceditor.py b/novelwriter/gui/doceditor.py index 41442385..b1760be4 100644 --- a/novelwriter/gui/doceditor.py +++ b/novelwriter/gui/doceditor.py @@ -1061,8 +1061,8 @@ class GuiDocEditor(QTextEdit): """If the text editor is resized, we must make sure the document has its margins adjusted according to user preferences. """ - QTextEdit.resizeEvent(self, theEvent) self.updateDocMargins() + QTextEdit.resizeEvent(self, theEvent) return ## diff --git a/novelwriter/gui/docviewer.py b/novelwriter/gui/docviewer.py index 72c142a0..4ec59570 100644 --- a/novelwriter/gui/docviewer.py +++ b/novelwriter/gui/docviewer.py @@ -471,10 +471,11 @@ class GuiDocViewer(QTextBrowser): ## def resizeEvent(self, theEvent): - """Make sure the document title is the same width as the window. + """If the text editor is resized, we must make sure the document + has its margins adjusted according to user preferences. """ - QTextBrowser.resizeEvent(self, theEvent) self.updateDocMargins() + QTextBrowser.resizeEvent(self, theEvent) return def mouseReleaseEvent(self, theEvent): From 7532fdb1fc696066cb831baad53c0c0411e9ff89 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Thu, 24 Feb 2022 21:08:42 +0100 Subject: [PATCH 2/5] Fix project file icon path in Windows installer (#1006) --- setup/win_setup_embed.iss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/win_setup_embed.iss b/setup/win_setup_embed.iss index 84911592..7505f6c1 100644 --- a/setup/win_setup_embed.iss +++ b/setup/win_setup_embed.iss @@ -51,6 +51,6 @@ Filename: "{app}\pythonw.exe"; Parameters: "{#nwAppExeName}"; Description: "{cm [Registry] Root: HKA; Subkey: "Software\Classes\.nwx\OpenWithProgids"; ValueType: string; ValueName: "novelWriterProject.nwx"; ValueData: ""; Flags: uninsdeletevalue Root: HKA; Subkey: "Software\Classes\novelWriterProject.nwx"; ValueType: string; ValueName: ""; ValueData: "novelWriter Project File"; Flags: uninsdeletekey -Root: HKA; Subkey: "Software\Classes\novelWriterProject.nwx\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\assets\icons\x-novelwriter-project.ico" +Root: HKA; Subkey: "Software\Classes\novelWriterProject.nwx\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\novelwriter\assets\icons\x-novelwriter-project.ico" Root: HKA; Subkey: "Software\Classes\novelWriterProject.nwx\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\pythonw.exe"" ""{app}\{#nwAppExeName}"" ""%1""" Root: HKA; Subkey: "Software\Classes\Applications\{#nwAppExeName}\SupportedTypes"; ValueType: string; ValueName: ".nwx"; ValueData: ""; Flags: uninsdeletekey From 1c7708babd433de4b486efd612bbab8d2fc74bd9 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Wed, 16 Mar 2022 22:34:29 +0100 Subject: [PATCH 3/5] Fix infinite search loop bug (#1016) * Make sure the search loop in the editor cannot run infinitely * Add test coverage of infinite search case * Run GitHub actions against the patch branch --- .github/workflows/syntax.yml | 2 ++ .github/workflows/test_linux.yml | 2 ++ .github/workflows/test_mac.yml | 2 ++ .github/workflows/test_win.yml | 2 ++ novelwriter/gui/doceditor.py | 14 ++++++++++---- tests/test_gui/test_gui_doceditor.py | 17 ++++++++++++----- 6 files changed, 30 insertions(+), 9 deletions(-) diff --git a/.github/workflows/syntax.yml b/.github/workflows/syntax.yml index 560dd7dc..a0b56ce1 100644 --- a/.github/workflows/syntax.yml +++ b/.github/workflows/syntax.yml @@ -4,9 +4,11 @@ on: push: branches: - main + - patch pull_request: branches: - main + - patch jobs: checkSyntax: diff --git a/.github/workflows/test_linux.yml b/.github/workflows/test_linux.yml index 5699d8a8..caf147ef 100644 --- a/.github/workflows/test_linux.yml +++ b/.github/workflows/test_linux.yml @@ -4,9 +4,11 @@ on: push: branches: - main + - patch pull_request: branches: - main + - patch jobs: testLinux: diff --git a/.github/workflows/test_mac.yml b/.github/workflows/test_mac.yml index c9b4497c..a011b51e 100644 --- a/.github/workflows/test_mac.yml +++ b/.github/workflows/test_mac.yml @@ -4,9 +4,11 @@ on: push: branches: - main + - patch pull_request: branches: - main + - patch jobs: testMac: diff --git a/.github/workflows/test_win.yml b/.github/workflows/test_win.yml index 85a0fda6..b41ccbf5 100644 --- a/.github/workflows/test_win.yml +++ b/.github/workflows/test_win.yml @@ -4,9 +4,11 @@ on: push: branches: - main + - patch pull_request: branches: - main + - patch jobs: testWin: diff --git a/novelwriter/gui/doceditor.py b/novelwriter/gui/doceditor.py index b1760be4..4d35c978 100644 --- a/novelwriter/gui/doceditor.py +++ b/novelwriter/gui/doceditor.py @@ -1436,10 +1436,16 @@ class GuiDocEditor(QTextEdit): theCursor.setPosition(0) self.setTextCursor(theCursor) - while self.find(searchFor, findOpt): + # Search up to a maximum of 1000, and make sure certain special + # searches like a regex search for .* turns into an infinite loop + while self.find(searchFor, findOpt) and len(resE) <= 1000: theCursor = self.textCursor() - resS.append(theCursor.selectionStart()) - resE.append(theCursor.selectionEnd()) + if theCursor.hasSelection(): + resS.append(theCursor.selectionStart()) + resE.append(theCursor.selectionEnd()) + else: + logger.warning("The search returned an empty result") + break if hasSelection: theCursor.setPosition(origA, QTextCursor.MoveAnchor) @@ -2410,7 +2416,7 @@ class GuiDocEditSearch(QFrame): """Set the count values for the current search. """ currRes = "?" if currRes is None else currRes - resCount = "?" if resCount is None else resCount + resCount = "?" if resCount is None else "1000+" if resCount > 1000 else resCount minWidth = self.theTheme.getTextWidth(f"{resCount}//{resCount}", self.boxFont) self.resultLabel.setText(f"{currRes}/{resCount}") self.resultLabel.setMinimumWidth(minWidth) diff --git a/tests/test_gui/test_gui_doceditor.py b/tests/test_gui/test_gui_doceditor.py index 241acd24..8057ca41 100644 --- a/tests/test_gui/test_gui_doceditor.py +++ b/tests/test_gui/test_gui_doceditor.py @@ -1286,13 +1286,13 @@ def testGuiEditor_Search(qtbot, monkeypatch, nwGUI, nwLipsum): monkeypatch.setattr(GuiDocEditor, "hasFocus", lambda *a: True) nwGUI.theProject.projTree.setSeed(42) - assert nwGUI.openProject(nwLipsum) - assert nwGUI.openDocument("4c4f28287af27") + assert nwGUI.openProject(nwLipsum) is True + assert nwGUI.openDocument("4c4f28287af27") is True origText = nwGUI.docEditor.getText() qtbot.wait(stepDelay) # Select the Word "est" - assert nwGUI.docEditor.setCursorPosition(630) + nwGUI.docEditor.setCursorPosition(630) nwGUI.docEditor._makeSelection(QTextCursor.WordUnderCursor) theCursor = nwGUI.docEditor.textCursor() assert theCursor.selectedText() == "est" @@ -1331,7 +1331,7 @@ def testGuiEditor_Search(qtbot, monkeypatch, nwGUI, nwLipsum): assert nwGUI.docEditor.docSearch.isVisible() is True # Search for non-existing - assert nwGUI.docEditor.setCursorPosition(0) + nwGUI.docEditor.setCursorPosition(0) assert nwGUI.docEditor.docSearch.setSearchText("abcdef") qtbot.mouseClick(nwGUI.docEditor.docSearch.searchButton, Qt.LeftButton, delay=keyDelay) assert nwGUI.docEditor.getCursorPosition() < 3 # No result @@ -1342,11 +1342,18 @@ def testGuiEditor_Search(qtbot, monkeypatch, nwGUI, nwLipsum): assert nwGUI.docEditor.docSearch.isRegEx is True # Set invalid RegEx - assert nwGUI.docEditor.setCursorPosition(0) + nwGUI.docEditor.setCursorPosition(0) assert nwGUI.docEditor.docSearch.setSearchText(r"\bSus[") qtbot.mouseClick(nwGUI.docEditor.docSearch.searchButton, Qt.LeftButton, delay=keyDelay) assert nwGUI.docEditor.getCursorPosition() < 3 # No result + # Set dangerous RegEx (issue #1015) + # If this doesn't get caught, the app will hang + nwGUI.docEditor.setCursorPosition(0) + assert nwGUI.docEditor.docSearch.setSearchText(r".*") + qtbot.mouseClick(nwGUI.docEditor.docSearch.searchButton, Qt.LeftButton, delay=keyDelay) + assert abs(nwGUI.docEditor.getCursorPosition() - 14) < 3 + # Set valid RegEx assert nwGUI.docEditor.docSearch.setSearchText(r"\bSus") qtbot.mouseClick(nwGUI.docEditor.docSearch.searchButton, Qt.LeftButton, delay=keyDelay) From 9e76498f65516a102d725c5b16d0e42ecc8378ef Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Wed, 16 Mar 2022 22:41:52 +0100 Subject: [PATCH 4/5] Update Latin American Spanish translation (#1017) --- i18n/nw_es_419.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/i18n/nw_es_419.ts b/i18n/nw_es_419.ts index 223d9acf..e465c54f 100644 --- a/i18n/nw_es_419.ts +++ b/i18n/nw_es_419.ts @@ -535,12 +535,12 @@ Hide scene - Hide scene + Ocultar la escena Hide section - Hide section + Ocultar la sección From 4cbbae6d2febdba4c46b8ff336a3463b569618a3 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Wed, 16 Mar 2022 23:01:14 +0100 Subject: [PATCH 5/5] Release 1.6.1 (#1018) --- CHANGELOG.md | 33 +++++++++++++++++++++++ novelwriter/__init__.py | 6 ++--- novelwriter/assets/text/release_notes.htm | 8 ++++++ sample/nwProject.nwx | 6 ++--- 4 files changed, 47 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1dcc02db..1c864ca1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,38 @@ # novelWriter Changelog +## Version 1.6.1 [2022-03-16] + +### Release Notes + +This is a bugfix and patch release that fixes two recursion/loop issues. One can cause a crash if +the window is resized rapidly, and one can cause a hang with certain search parameters in the +editor's search box. The Latin American Spanish translation has also been updated. + +### Detailed Changelog + +**Installation** + +* When using the new installer on Windows, the project file mime type icon path would not be + correctly configured in registry. The correct path is now used. PR #1006. + +**Internationalisation** + +* The Latin American Spanish translation has been updated with two missing translation strings. + PR #1017. + +**Bugfixes** + +* Fix a bug where rapidly resizing the main window could trigger the recursion detector in Python + if done on a slower system. The actual issue may be a race condition or similar, and the change + made at least makes it harder to trigger. PR #1007. +* With some document searches, it was possible to trigger an infinite loop in the function that + counts results. It seems to be caused by the QTextEdit widget's find function returning a + successful result status, but no actual result selection. The fix will now write a warning to the + log and exit in such cases. The number of results is also now capped at 1000. Issue #1015. + PR #1016. + +---- + ## Version 1.6 [2022-02-20] ### Release Notes diff --git a/novelwriter/__init__.py b/novelwriter/__init__.py index 98247c68..485dc406 100644 --- a/novelwriter/__init__.py +++ b/novelwriter/__init__.py @@ -60,9 +60,9 @@ __license__ = "GPLv3" __author__ = "Veronica Berglyd Olsen" __maintainer__ = "Veronica Berglyd Olsen" __email__ = "code@vkbo.net" -__version__ = "1.6" -__hexversion__ = "0x010600f0" -__date__ = "2022-02-20" +__version__ = "1.6.1" +__hexversion__ = "0x010601f0" +__date__ = "2022-03-16" __status__ = "Stable" __domain__ = "novelwriter.io" __url__ = "https://novelwriter.io" diff --git a/novelwriter/assets/text/release_notes.htm b/novelwriter/assets/text/release_notes.htm index d315a9a4..6c4a7d99 100644 --- a/novelwriter/assets/text/release_notes.htm +++ b/novelwriter/assets/text/release_notes.htm @@ -37,5 +37,13 @@ not compatible.

See also the Releases page.

+

Patch Notes

+ +

Patch 1.6.1 – 16 March 2022

+ +

This is a bugfix and patch release that fixes two recursion/loop issues. One can cause a crash +if the window is resized rapidly, and one can cause a hang with certain search parameters in the +editor's search box. The Latin American Spanish translation has also been updated.

+ diff --git a/sample/nwProject.nwx b/sample/nwProject.nwx index 9e37d34a..95a4d168 100644 --- a/sample/nwProject.nwx +++ b/sample/nwProject.nwx @@ -1,13 +1,13 @@ - + Sample Project Sample Project Jane Smith Jay Doh - 1299 + 1301 199 - 64923 + 64982 False