From 36be97b99d4de786746a8d80bbcd41de03752df9 Mon Sep 17 00:00:00 2001 From: James Bligh Date: Wed, 4 Mar 2026 14:12:06 +0000 Subject: Fixed #21080 -- Ignored urls inside comments during collectstatic. Thanks Mariusz Felisiak for the review. Co-authored-by: Nathan Gaberel --- django/contrib/staticfiles/storage.py | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) (limited to 'django') diff --git a/django/contrib/staticfiles/storage.py b/django/contrib/staticfiles/storage.py index b16c77757c..c889bcb4a4 100644 --- a/django/contrib/staticfiles/storage.py +++ b/django/contrib/staticfiles/storage.py @@ -11,6 +11,12 @@ from django.core.exceptions import ImproperlyConfigured from django.core.files.base import ContentFile from django.core.files.storage import FileSystemStorage, storages from django.utils.functional import LazyObject +from django.utils.regex_helper import _lazy_re_compile + +comment_re = _lazy_re_compile(r"\/\*[^*]*\*+([^/*][^*]*\*+)*\/", re.DOTALL) +line_comment_re = _lazy_re_compile( + r"\/\*[^*]*\*+([^/*][^*]*\*+)*\/|\/\/[^\n]*", re.DOTALL +) class StaticFilesStorage(FileSystemStorage): @@ -204,7 +210,22 @@ class HashedFilesMixin: """ return self._url(self.stored_name, name, force) - def url_converter(self, name, hashed_files, template=None): + def get_comment_blocks(self, content, include_line_comments=False): + """ + Return a list of (start, end) tuples for each comment block. + """ + pattern = line_comment_re if include_line_comments else comment_re + return [(match.start(), match.end()) for match in re.finditer(pattern, content)] + + def is_in_comment(self, pos, comments): + for start, end in comments: + if start < pos and pos < end: + return True + if pos < start: + return False + return False + + def url_converter(self, name, hashed_files, template=None, comment_blocks=None): """ Return the custom URL converter for the given file name. """ @@ -222,6 +243,10 @@ class HashedFilesMixin: matched = matches["matched"] url = matches["url"] + # Ignore URLs in comments. + if comment_blocks and self.is_in_comment(matchobj.start(), comment_blocks): + return matched + # Ignore absolute/protocol-relative and data-uri URLs. if re.match(r"^[a-z]+:", url) or url.startswith("//"): return matched @@ -375,7 +400,13 @@ class HashedFilesMixin: if matches_patterns(path, (extension,)): for pattern, template in patterns: converter = self.url_converter( - name, hashed_files, template + name, + hashed_files, + template, + self.get_comment_blocks( + content, + include_line_comments=path.endswith(".js"), + ), ) try: content = pattern.sub(converter, content) -- cgit v1.3