summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorAndrew Svetlov <andrew.svetlov@gmail.com>2012-08-04 18:42:48 (GMT)
committerAndrew Svetlov <andrew.svetlov@gmail.com>2012-08-04 18:42:48 (GMT)
commitfa556bd75cd5470b1f9f4355b6db36cc7d67b739 (patch)
tree1f71a2dc2956dd9f6e01e461f367aae284749bca /Lib
parentba5010a64963e93e8b4dccb076e998a1e42bd71d (diff)
parent5ad514d281239479d957e21f602ff5c0d2ff5fec (diff)
downloadcpython-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.
Diffstat (limited to 'Lib')
-rw-r--r--Lib/idlelib/ReplaceDialog.py31
1 files changed, 26 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():