summaryrefslogtreecommitdiff
path: root/Lib/fnmatch.py
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2022-06-05 02:39:03 -0700
committerGitHub <noreply@github.com>2022-06-05 02:39:03 -0700
commit2f8aae38b9ce19dfd00356927a68cd00366331bc (patch)
treef0f466b433886157170e7403c18a197b00f4e1f7 /Lib/fnmatch.py
parent60adc4b92a8a6fe115a023c8f639a6de4730fac1 (diff)
downloadcpython-git-2f8aae38b9ce19dfd00356927a68cd00366331bc.tar.gz
gh-89973: Fix re.error in the fnmatch module. (GH-93072)
Character ranges with upper bound less that lower bound (e.g. [c-a]) are now interpreted as empty ranges, for compatibility with other glob pattern implementations. Previously it was re.error. (cherry picked from commit 0902c3d8edf7ef67972dd95f6a21670f5d1a4251) Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Diffstat (limited to 'Lib/fnmatch.py')
-rw-r--r--Lib/fnmatch.py30
1 files changed, 23 insertions, 7 deletions
diff --git a/Lib/fnmatch.py b/Lib/fnmatch.py
index 7c52c23067..fee59bf73f 100644
--- a/Lib/fnmatch.py
+++ b/Lib/fnmatch.py
@@ -108,7 +108,7 @@ def translate(pat):
add('\\[')
else:
stuff = pat[i:j]
- if '--' not in stuff:
+ if '-' not in stuff:
stuff = stuff.replace('\\', r'\\')
else:
chunks = []
@@ -120,7 +120,16 @@ def translate(pat):
chunks.append(pat[i:k])
i = k+1
k = k+3
- chunks.append(pat[i:j])
+ chunk = pat[i:j]
+ if chunk:
+ chunks.append(chunk)
+ else:
+ chunks[-1] += '-'
+ # Remove empty ranges -- invalid in RE.
+ for k in range(len(chunks)-1, 0, -1):
+ if chunks[k-1][-1] > chunks[k][0]:
+ chunks[k-1] = chunks[k-1][:-1] + chunks[k][1:]
+ del chunks[k]
# Escape backslashes and hyphens for set difference (--).
# Hyphens that create ranges shouldn't be escaped.
stuff = '-'.join(s.replace('\\', r'\\').replace('-', r'\-')
@@ -128,11 +137,18 @@ def translate(pat):
# Escape set operations (&&, ~~ and ||).
stuff = re.sub(r'([&~|])', r'\\\1', stuff)
i = j+1
- if stuff[0] == '!':
- stuff = '^' + stuff[1:]
- elif stuff[0] in ('^', '['):
- stuff = '\\' + stuff
- add(f'[{stuff}]')
+ if not stuff:
+ # Empty range: never match.
+ add('(?!)')
+ elif stuff == '!':
+ # Negated empty range: match any character.
+ add('.')
+ else:
+ if stuff[0] == '!':
+ stuff = '^' + stuff[1:]
+ elif stuff[0] in ('^', '['):
+ stuff = '\\' + stuff
+ add(f'[{stuff}]')
else:
add(re.escape(c))
assert i == n