[Python-checkins] cpython (2.7): Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog

andrew.svetlov python-checkins at python.org
Sat Aug 4 20:45:51 CEST 2012


http://hg.python.org/cpython/rev/44c00de723b3
changeset:   78417:44c00de723b3
branch:      2.7
parent:      78412:1bc398a63444
user:        Andrew Svetlov <andrew.svetlov at gmail.com>
date:        Sat Aug 04 21:45:23 2012 +0300
summary:
  Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog ended with '\'.

Patch by Roger Serwy.

files:
  Lib/idlelib/ReplaceDialog.py |  30 ++++++++++++++++++++----
  Misc/NEWS                    |   3 ++
  2 files changed, 28 insertions(+), 5 deletions(-)


diff --git a/Lib/idlelib/ReplaceDialog.py b/Lib/idlelib/ReplaceDialog.py
--- a/Lib/idlelib/ReplaceDialog.py
+++ b/Lib/idlelib/ReplaceDialog.py
@@ -2,6 +2,8 @@
 
 from idlelib import SearchEngine
 from idlelib.SearchDialogBase import SearchDialogBase
+import re
+
 
 def replace(text):
     root = text._root()
@@ -11,6 +13,7 @@
     dialog = engine._replacedialog
     dialog.open(text)
 
+
 class ReplaceDialog(SearchDialogBase):
 
     title = "Replace Dialog"
@@ -55,8 +58,22 @@
 
     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 +103,9 @@
             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 +122,6 @@
         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 +156,9 @@
         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():
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -92,6 +92,9 @@
 Library
 -------
 
+- Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog
+  ended with '\'. Patch by Roger Serwy.
+
 - Issue #15538: Fix compilation of the getnameinfo() / getaddrinfo()
   emulation code.  Patch by Philipp Hagemeister.
 

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list