diff options
author | Andrew Svetlov <andrew.svetlov@gmail.com> | 2012-08-04 18:42:48 (GMT) |
---|---|---|
committer | Andrew Svetlov <andrew.svetlov@gmail.com> | 2012-08-04 18:42:48 (GMT) |
commit | fa556bd75cd5470b1f9f4355b6db36cc7d67b739 (patch) | |
tree | 1f71a2dc2956dd9f6e01e461f367aae284749bca | |
parent | ba5010a64963e93e8b4dccb076e998a1e42bd71d (diff) | |
parent | 5ad514d281239479d957e21f602ff5c0d2ff5fec (diff) | |
download | cpython-fa556bd75cd5470b1f9f4355b6db36cc7d67b739.zip cpython-fa556bd75cd5470b1f9f4355b6db36cc7d67b739.tar.gz cpython-fa556bd75cd5470b1f9f4355b6db36cc7d67b739.tar.bz2 |
Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog ended with '\'.
Patch by Roger Serwy.
-rw-r--r-- | Lib/idlelib/ReplaceDialog.py | 31 | ||||
-rw-r--r-- | Misc/NEWS | 3 |
2 files changed, 29 insertions, 5 deletions
diff --git a/Lib/idlelib/ReplaceDialog.py b/Lib/idlelib/ReplaceDialog.py index d713e61..e5a1371 100644 --- a/Lib/idlelib/ReplaceDialog.py +++ b/Lib/idlelib/ReplaceDialog.py @@ -2,6 +2,8 @@ from tkinter import * from idlelib import SearchEngine from idlelib.SearchDialogBase import SearchDialogBase +import re + def replace(text): root = text._root() @@ -11,6 +13,7 @@ def replace(text): dialog = engine._replacedialog dialog.open(text) + class ReplaceDialog(SearchDialogBase): title = "Replace Dialog" @@ -55,8 +58,23 @@ class ReplaceDialog(SearchDialogBase): def default_command(self, event=None): if self.do_find(self.ok): - self.do_replace() - self.do_find(0) + if self.do_replace(): # Only find next match if replace succeeded. + # A bad re can cause a it to fail. + self.do_find(0) + + def _replace_expand(self, m, repl): + """ Helper function for expanding a regular expression + in the replace field, if needed. """ + if self.engine.isre(): + try: + new = m.expand(repl) + except re.error: + self.engine.report_error(repl, 'Invalid Replace Expression') + new = None + else: + new = repl + + return new def replace_all(self, event=None): prog = self.engine.getprog() @@ -86,7 +104,9 @@ class ReplaceDialog(SearchDialogBase): line, m = res chars = text.get("%d.0" % line, "%d.0" % (line+1)) orig = m.group() - new = m.expand(repl) + new = self._replace_expand(m, repl) + if new is None: + break i, j = m.span() first = "%d.%d" % (line, i) last = "%d.%d" % (line, j) @@ -103,7 +123,6 @@ class ReplaceDialog(SearchDialogBase): text.undo_block_stop() if first and last: self.show_hit(first, last) - self.close() def do_find(self, ok=0): if not self.engine.getprog(): @@ -138,7 +157,9 @@ class ReplaceDialog(SearchDialogBase): m = prog.match(chars, col) if not prog: return False - new = m.expand(self.replvar.get()) + new = self._replace_expand(m, self.replvar.get()) + if new is None: + return False text.mark_set("insert", first) text.undo_block_start() if m.group(): @@ -77,6 +77,9 @@ Core and Builtins Library ------- +- Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog + ended with '\'. Patch by Roger Serwy. + - Issue #12655: Instead of requiring a custom type, os.sched_getaffinity and os.sched_setaffinity now use regular sets of integers to represent the CPUs a process is restricted to. |