Skip to content

Commit 01394db

Browse files
committed
Be more careful with glob.glob (fixes bpython#491)
If we have glob.escape, use it. Signed-off-by: Sebastian Ramacher <sebastian+dev@ramacher.at> (cherry picked from commit 846ca4d)
1 parent 6fb64c6 commit 01394db

File tree

2 files changed

+20
-8
lines changed

2 files changed

+20
-8
lines changed

bpython/autocomplete.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,15 @@
2323

2424
import __main__
2525
import abc
26+
import glob
2627
import keyword
2728
import os
29+
import re
2830
import rlcompleter
31+
import sys
2932
from six.moves import range, builtins
3033
from six import string_types
3134

32-
from glob import glob
33-
3435
from bpython import inspection
3536
from bpython import importcompletion
3637
from bpython import line as lineparts
@@ -151,6 +152,17 @@ class FilenameCompletion(BaseCompletionType):
151152
def __init__(self):
152153
super(FilenameCompletion, self).__init__(False)
153154

155+
if sys.version_info[:2] >= (3, 4):
156+
def safe_glob(self, pathname):
157+
return glob.glob(glob.escape(pathname) + '*')
158+
else:
159+
def safe_glob(self, pathname):
160+
try:
161+
return glob.glob(pathname + '*')
162+
except re.error:
163+
# see #491
164+
return tuple()
165+
154166
def matches(self, cursor_offset, line, **kwargs):
155167
cs = lineparts.current_string(cursor_offset, line)
156168
if cs is None:
@@ -159,7 +171,7 @@ def matches(self, cursor_offset, line, **kwargs):
159171
matches = set()
160172
username = text.split(os.path.sep, 1)[0]
161173
user_dir = os.path.expanduser(username)
162-
for filename in glob(os.path.expanduser(text + '*')):
174+
for filename in self.safe_glob(os.path.expanduser(text)):
163175
if os.path.isdir(filename):
164176
filename += os.path.sep
165177
if text.startswith('~'):

bpython/test/test_autocomplete.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -120,15 +120,15 @@ def test_locate_fails_when_not_in_string(self):
120120
def test_locate_succeeds_when_in_string(self):
121121
self.assertEqual(self.completer.locate(4, "a'bc'd"), (2, 4, 'bc'))
122122

123-
@mock.patch('bpython.autocomplete.glob', new=lambda text: [])
123+
@mock.patch('glob.glob', new=lambda text: [])
124124
def test_match_returns_none_if_not_in_string(self):
125125
self.assertEqual(self.completer.matches(2, 'abcd'), None)
126126

127-
@mock.patch('bpython.autocomplete.glob', new=lambda text: [])
127+
@mock.patch('glob.glob', new=lambda text: [])
128128
def test_match_returns_empty_list_when_no_files(self):
129129
self.assertEqual(self.completer.matches(2, '"a'), set())
130130

131-
@mock.patch('bpython.autocomplete.glob',
131+
@mock.patch('glob.glob',
132132
new=lambda text: ['abcde', 'aaaaa'])
133133
@mock.patch('os.path.expanduser', new=lambda text: text)
134134
@mock.patch('os.path.isdir', new=lambda text: False)
@@ -137,7 +137,7 @@ def test_match_returns_files_when_files_exist(self):
137137
self.assertEqual(sorted(self.completer.matches(2, '"x')),
138138
['aaaaa', 'abcde'])
139139

140-
@mock.patch('bpython.autocomplete.glob',
140+
@mock.patch('glob.glob',
141141
new=lambda text: ['abcde', 'aaaaa'])
142142
@mock.patch('os.path.expanduser', new=lambda text: text)
143143
@mock.patch('os.path.isdir', new=lambda text: True)
@@ -146,7 +146,7 @@ def test_match_returns_dirs_when_dirs_exist(self):
146146
self.assertEqual(sorted(self.completer.matches(2, '"x')),
147147
['aaaaa/', 'abcde/'])
148148

149-
@mock.patch('bpython.autocomplete.glob',
149+
@mock.patch('glob.glob',
150150
new=lambda text: ['/expand/ed/abcde', '/expand/ed/aaaaa'])
151151
@mock.patch('os.path.expanduser',
152152
new=lambda text: text.replace('~', '/expand/ed'))

0 commit comments

Comments
 (0)