From 9b9c805cedb08621bd5dc58a01a6478eb7cc49a9 Mon Sep 17 00:00:00 2001 From: Mariusz Felisiak Date: Wed, 2 Aug 2023 19:53:16 +0200 Subject: [PATCH] Removed unneeded escapes in regexes. Special characters lose their special meaning inside sets of characters. "-" lose its special meaning if it's placed as the first or last character. Follow up to 7c6b66383da5f9a67142334cd2ed2d769739e8f1. --- django/contrib/admindocs/urls.py | 2 +- django/contrib/flatpages/forms.py | 2 +- django/contrib/gis/db/models/lookups.py | 2 +- django/contrib/gis/geometry.py | 2 +- django/contrib/staticfiles/storage.py | 6 +++--- django/db/models/functions/comparison.py | 2 +- django/db/models/sql/query.py | 2 +- django/template/base.py | 2 +- django/utils/dateparse.py | 14 +++++++------- docs/conf.py | 4 ++-- tests/validators/tests.py | 22 +++++++++++----------- 11 files changed, 30 insertions(+), 30 deletions(-) diff --git a/django/contrib/admindocs/urls.py b/django/contrib/admindocs/urls.py index 6ee14ac67b..5de2dbacc6 100644 --- a/django/contrib/admindocs/urls.py +++ b/django/contrib/admindocs/urls.py @@ -38,7 +38,7 @@ urlpatterns = [ name="django-admindocs-models-index", ), re_path( - r"^models/(?P[^\.]+)\.(?P[^/]+)/$", + r"^models/(?P[^.]+)\.(?P[^/]+)/$", views.ModelDetailView.as_view(), name="django-admindocs-models-detail", ), diff --git a/django/contrib/flatpages/forms.py b/django/contrib/flatpages/forms.py index a6619c51e7..136fd02767 100644 --- a/django/contrib/flatpages/forms.py +++ b/django/contrib/flatpages/forms.py @@ -10,7 +10,7 @@ class FlatpageForm(forms.ModelForm): url = forms.RegexField( label=_("URL"), max_length=100, - regex=r"^[-\w/\.~]+$", + regex=r"^[-\w/.~]+$", help_text=_( "Example: “/about/contact/”. Make sure to have leading and trailing " "slashes." diff --git a/django/contrib/gis/db/models/lookups.py b/django/contrib/gis/db/models/lookups.py index 07762d0a13..b9686fa65f 100644 --- a/django/contrib/gis/db/models/lookups.py +++ b/django/contrib/gis/db/models/lookups.py @@ -273,7 +273,7 @@ class OverlapsLookup(GISLookup): class RelateLookup(GISLookup): lookup_name = "relate" sql_template = "%(func)s(%(lhs)s, %(rhs)s, %%s)" - pattern_regex = _lazy_re_compile(r"^[012TF\*]{9}$") + pattern_regex = _lazy_re_compile(r"^[012TF*]{9}$") def process_rhs(self, compiler, connection): # Check the pattern argument diff --git a/django/contrib/gis/geometry.py b/django/contrib/gis/geometry.py index 0b289cf355..b5caf04be4 100644 --- a/django/contrib/gis/geometry.py +++ b/django/contrib/gis/geometry.py @@ -11,7 +11,7 @@ wkt_regex = _lazy_re_compile( r"(?P" r"(?PPOINT|LINESTRING|LINEARRING|POLYGON|MULTIPOINT|" r"MULTILINESTRING|MULTIPOLYGON|GEOMETRYCOLLECTION)" - r"[ACEGIMLONPSRUTYZ0-9,\.\-\+\(\) ]+)$", + r"[ACEGIMLONPSRUTYZ0-9,.+() -]+)$", re.I, ) json_regex = _lazy_re_compile(r"^(\s+)?\{.*}(\s+)?$", re.DOTALL) diff --git a/django/contrib/staticfiles/storage.py b/django/contrib/staticfiles/storage.py index 186f8d7535..85172ea42d 100644 --- a/django/contrib/staticfiles/storage.py +++ b/django/contrib/staticfiles/storage.py @@ -54,19 +54,19 @@ class HashedFilesMixin: ( ( r"""(?Pimport(?s:(?P[\s\{].*?))""" - r"""\s*from\s*['"](?P[\.\/].*?)["']\s*;)""" + r"""\s*from\s*['"](?P[./].*?)["']\s*;)""" ), """import%(import)s from "%(url)s";""", ), ( ( r"""(?Pexport(?s:(?P[\s\{].*?))""" - r"""\s*from\s*["'](?P[\.\/].*?)["']\s*;)""" + r"""\s*from\s*["'](?P[./].*?)["']\s*;)""" ), """export%(exports)s from "%(url)s";""", ), ( - r"""(?Pimport\s*['"](?P[\.\/].*?)["']\s*;)""", + r"""(?Pimport\s*['"](?P[./].*?)["']\s*;)""", """import"%(url)s";""", ), ( diff --git a/django/db/models/functions/comparison.py b/django/db/models/functions/comparison.py index 108d904712..eec2ab752d 100644 --- a/django/db/models/functions/comparison.py +++ b/django/db/models/functions/comparison.py @@ -108,7 +108,7 @@ class Collate(Func): allowed_default = False # Inspired from # https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS - collation_re = _lazy_re_compile(r"^[\w\-]+$") + collation_re = _lazy_re_compile(r"^[\w-]+$") def __init__(self, expression, collation): if not (collation and self.collation_re.match(collation)): diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index 220ae92754..9853919482 100644 --- a/django/db/models/sql/query.py +++ b/django/db/models/sql/query.py @@ -52,7 +52,7 @@ FORBIDDEN_ALIAS_PATTERN = _lazy_re_compile(r"['`\"\]\[;\s]|--|/\*|\*/") # Inspired from # https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS -EXPLAIN_OPTIONS_PATTERN = _lazy_re_compile(r"[\w\-]+") +EXPLAIN_OPTIONS_PATTERN = _lazy_re_compile(r"[\w-]+") def get_field_names_from_opts(opts): diff --git a/django/template/base.py b/django/template/base.py index 4762d20516..f7e4f94f51 100644 --- a/django/template/base.py +++ b/django/template/base.py @@ -632,7 +632,7 @@ filter_raw_string = r""" )? )""" % { "constant": constant_string, - "num": r"[-+\.]?\d[\d\.e]*", + "num": r"[-+.]?\d[\d.e]*", "var_chars": r"\w\.", "filter_sep": re.escape(FILTER_SEPARATOR), "arg_sep": re.escape(FILTER_ARGUMENT_SEPARATOR), diff --git a/django/utils/dateparse.py b/django/utils/dateparse.py index 08651f57ad..5cedd1affa 100644 --- a/django/utils/dateparse.py +++ b/django/utils/dateparse.py @@ -14,13 +14,13 @@ date_re = _lazy_re_compile(r"(?P\d{4})-(?P\d{1,2})-(?P\d{1,2}) time_re = _lazy_re_compile( r"(?P\d{1,2}):(?P\d{1,2})" - r"(?::(?P\d{1,2})(?:[\.,](?P\d{1,6})\d{0,6})?)?$" + r"(?::(?P\d{1,2})(?:[.,](?P\d{1,6})\d{0,6})?)?$" ) datetime_re = _lazy_re_compile( r"(?P\d{4})-(?P\d{1,2})-(?P\d{1,2})" r"[T ](?P\d{1,2}):(?P\d{1,2})" - r"(?::(?P\d{1,2})(?:[\.,](?P\d{1,6})\d{0,6})?)?" + r"(?::(?P\d{1,2})(?:[.,](?P\d{1,6})\d{0,6})?)?" r"\s*(?PZ|[+-]\d{2}(?::?\d{2})?)?$" ) @@ -31,7 +31,7 @@ standard_duration_re = _lazy_re_compile( r"((?:(?P\d+):)(?=\d+:\d+))?" r"(?:(?P\d+):)?" r"(?P\d+)" - r"(?:[\.,](?P\d{1,6})\d{0,6})?" + r"(?:[.,](?P\d{1,6})\d{0,6})?" r"$" ) @@ -40,11 +40,11 @@ standard_duration_re = _lazy_re_compile( iso8601_duration_re = _lazy_re_compile( r"^(?P[-+]?)" r"P" - r"(?:(?P\d+([\.,]\d+)?)D)?" + r"(?:(?P\d+([.,]\d+)?)D)?" r"(?:T" - r"(?:(?P\d+([\.,]\d+)?)H)?" - r"(?:(?P\d+([\.,]\d+)?)M)?" - r"(?:(?P\d+([\.,]\d+)?)S)?" + r"(?:(?P\d+([.,]\d+)?)H)?" + r"(?:(?P\d+([.,]\d+)?)M)?" + r"(?:(?P\d+([.,]\d+)?)S)?" r")?" r"$" ) diff --git a/docs/conf.py b/docs/conf.py index 2b37639eab..31478ae79d 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -54,8 +54,8 @@ autosectionlabel_maxdepth = 2 linkcheck_ignore = [ # Special-use addresses and domain names. (RFC 6761/6890) r"^https?://(?:127\.0\.0\.1|\[::1\])(?::\d+)?/", - r"^https?://(?:[^/\.]+\.)*example\.(?:com|net|org)(?::\d+)?/", - r"^https?://(?:[^/\.]+\.)*(?:example|invalid|localhost|test)(?::\d+)?/", + r"^https?://(?:[^/.]+\.)*example\.(?:com|net|org)(?::\d+)?/", + r"^https?://(?:[^/.]+\.)*(?:example|invalid|localhost|test)(?::\d+)?/", # Pages that are inaccessible because they require authentication. r"^https://github\.com/[^/]+/[^/]+/fork", r"^https://code\.djangoproject\.com/github/login", diff --git a/tests/validators/tests.py b/tests/validators/tests.py index e689435e3c..cf64638ebb 100644 --- a/tests/validators/tests.py +++ b/tests/validators/tests.py @@ -690,24 +690,24 @@ class TestValidatorEquality(TestCase): def test_regex_equality(self): self.assertEqual( - RegexValidator(r"^(?:[a-z0-9\.\-]*)://"), - RegexValidator(r"^(?:[a-z0-9\.\-]*)://"), + RegexValidator(r"^(?:[a-z0-9.-]*)://"), + RegexValidator(r"^(?:[a-z0-9.-]*)://"), ) self.assertNotEqual( - RegexValidator(r"^(?:[a-z0-9\.\-]*)://"), - RegexValidator(r"^(?:[0-9\.\-]*)://"), + RegexValidator(r"^(?:[a-z0-9.-]*)://"), + RegexValidator(r"^(?:[0-9.-]*)://"), ) self.assertEqual( - RegexValidator(r"^(?:[a-z0-9\.\-]*)://", "oh noes", "invalid"), - RegexValidator(r"^(?:[a-z0-9\.\-]*)://", "oh noes", "invalid"), + RegexValidator(r"^(?:[a-z0-9.-]*)://", "oh noes", "invalid"), + RegexValidator(r"^(?:[a-z0-9.-]*)://", "oh noes", "invalid"), ) self.assertNotEqual( - RegexValidator(r"^(?:[a-z0-9\.\-]*)://", "oh", "invalid"), - RegexValidator(r"^(?:[a-z0-9\.\-]*)://", "oh noes", "invalid"), + RegexValidator(r"^(?:[a-z0-9.-]*)://", "oh", "invalid"), + RegexValidator(r"^(?:[a-z0-9.-]*)://", "oh noes", "invalid"), ) self.assertNotEqual( - RegexValidator(r"^(?:[a-z0-9\.\-]*)://", "oh noes", "invalid"), - RegexValidator(r"^(?:[a-z0-9\.\-]*)://"), + RegexValidator(r"^(?:[a-z0-9.-]*)://", "oh noes", "invalid"), + RegexValidator(r"^(?:[a-z0-9.-]*)://"), ) self.assertNotEqual( @@ -721,7 +721,7 @@ class TestValidatorEquality(TestCase): ) def test_regex_equality_nocache(self): - pattern = r"^(?:[a-z0-9\.\-]*)://" + pattern = r"^(?:[a-z0-9.-]*)://" left = RegexValidator(pattern) re.purge() right = RegexValidator(pattern)