Skip to content

Commit ed4481f

Browse files
committed
Address cpburnz#44: raise informative exception for invalid git patterns
We've addressed the issue that GitWildMatchPattern would raise a cryptic IndexError for invalid git patterns. Instead, we raise an informative exception explaining that an invalid pattern was encountered. This exception is raised for at least the following patterns: - `!` - `\`
1 parent c00b332 commit ed4481f

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

pathspec/patterns/gitwildmatch.py

+15
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@
2525
_BYTES_ENCODING = 'latin1'
2626

2727

28+
class GitWildMatchPatternError(ValueError):
29+
"""
30+
The :class:`GitWildMatchPatternError` indicates an invalid git wild match
31+
pattern.
32+
"""
33+
pass
34+
35+
2836
class GitWildMatchPattern(RegexPattern):
2937
"""
3038
The :class:`GitWildMatchPattern` class represents a compiled Git
@@ -56,6 +64,7 @@ def pattern_to_regex(cls, pattern):
5664
else:
5765
raise TypeError("pattern:{!r} is not a unicode or byte string.".format(pattern))
5866

67+
original_pattern = pattern
5968
pattern = pattern.strip()
6069

6170
if pattern.startswith('#'):
@@ -137,6 +146,12 @@ def pattern_to_regex(cls, pattern):
137146
# according to `git check-ignore` (v2.4.1).
138147
pass
139148

149+
if not pattern_segs:
150+
# After resolving the edge cases, we end up with no
151+
# pattern at all. This must be because the pattern is
152+
# invalid.
153+
raise GitWildMatchPatternError("Invalid git pattern: %r" % (original_pattern,))
154+
140155
if not pattern_segs[-1] and len(pattern_segs) > 1:
141156
# A pattern ending with a slash ('/') will match all
142157
# descendant paths if it is a directory but not if it is a

pathspec/tests/test_gitwildmatch.py

+19-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
import pathspec.patterns.gitwildmatch
1212
import pathspec.util
13-
from pathspec.patterns.gitwildmatch import GitWildMatchPattern
13+
from pathspec.patterns.gitwildmatch import GitWildMatchPattern, GitWildMatchPatternError
1414

1515
if sys.version_info[0] >= 3:
1616
unichr = chr
@@ -528,3 +528,21 @@ def test_08_escape(self):
528528
escaped = r"file\!with\*weird\#naming_\[1\].t\?t"
529529
result = GitWildMatchPattern.escape(fname)
530530
self.assertEqual(result, escaped)
531+
532+
def test_09_single_escape_fail(self):
533+
"""
534+
Test an escape on a line by itself.
535+
"""
536+
self._check_invalid_pattern("\\")
537+
538+
def test_09_single_exclamation_mark_fail(self):
539+
"""
540+
Test an escape on a line by itself.
541+
"""
542+
self._check_invalid_pattern("!")
543+
544+
def _check_invalid_pattern(self, git_ignore_pattern):
545+
expected_message_pattern = re.escape(repr(git_ignore_pattern))
546+
with self.assertRaisesRegexp(GitWildMatchPatternError, expected_message_pattern):
547+
GitWildMatchPattern(git_ignore_pattern)
548+

0 commit comments

Comments
 (0)