Skip to content

Commit 82c82f2

Browse files
mahveotmjenkins-bot
authored andcommitted
textlib: Reject nested wikilinks in file captions
Do not match a file link when a wikilink in its caption contains another wikilink. MediaWiki treats this malformed markup as plain text, so replaceExcept must not skip replacements there. Prevent the single-bracket fallback from accepting double brackets. Require each repeated caption alternative to consume characters, avoiding empty matches that hang the PyPy regex engine on malformed captions. Keep the existing unbalanced input as a regression test, preserving its brackets and replacing both x occurrences. Remove expectedFailure and rename the test to describe the malformed input. Bug: T396721 Change-Id: Ib1cec8ddd36d1b2454bf176603e841413d9e0b88
1 parent 00780a9 commit 82c82f2

2 files changed

Lines changed: 13 additions & 16 deletions

File tree

‎pywikibot/textlib.py‎

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,8 @@
7272

7373
# Regex matching file links with optional parameters.
7474
#
75-
# Captures the filename and parameters, including nested links
76-
# within the parameters. The regex safely matches the closing
77-
# brackets even if inner wikilinks contain [[ or ]].
75+
# Captures the filename and parameters, including links within the
76+
# parameters. Inner wikilinks cannot contain nested wikilinks.
7877
# The Namespace names must be substituted into the pattern, e.g.:
7978
# FILE_LINK_REGEX % 'File'
8079
# or: FILE_LINK_REGEX % '|'.join(site.namespaces[6])
@@ -93,17 +92,16 @@
9392
(
9493
\|
9594
(
96-
(
97-
(?=(?P<inner_link>
98-
\[\[.*?\]\]
99-
))(?P=inner_link)
100-
)?
95+
(?=(?P<inner_link>
96+
\[\[(?:(?!\[\[).)*?\]\]
97+
))(?P=inner_link)
98+
|
10199
(?=(?P<other_chars>
102-
[^\[\]]*
100+
[^\[\]]+
103101
))(?P=other_chars)
104102
|
105103
(?=(?P<not_wikilink>
106-
\[[^]]*\]
104+
\[(?!\[)[^]]*\]
107105
))(?P=not_wikilink)
108106
)*?
109107
)??

‎tests/textlib_tests.py‎

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1448,16 +1448,15 @@ def test_replace_tag_file_invalid(self) -> None:
14481448
'x', 'y', ['file'], site=self.site),
14491449
'[[File:a|[[foo]] [[bar [invalid ]].x]][[y]]')
14501450

1451-
@unittest.expectedFailure # T396721
1452-
def test_replace_tag_file_failure(self) -> None:
1453-
"""Test showing limits of the file link regex."""
1454-
# When the double brackets are unbalanced, the regex
1455-
# does not correctly detect the end of the file link.
1451+
def test_replace_tag_file_unbalanced(self) -> None:
1452+
"""Test replacing text in a file link with invalid nested wikilinks."""
1453+
# MediaWiki does not render this as a file link, so both occurrences
1454+
# of x should be replaced without changing the malformed brackets.
14561455
self.assertEqual(
14571456
textlib.replaceExcept(
14581457
'[[File:a|[[foo]] [[bar [[invalid ]].x]][[x]]',
14591458
'x', 'y', ['file'], site=self.site),
1460-
'[[File:a|[[foo]] [[bar [invalid] ]].x]][[y]]')
1459+
'[[File:a|[[foo]] [[bar [[invalid ]].y]][[y]]')
14611460

14621461
def test_replace_tags_interwiki(self) -> None:
14631462
"""Test replacing not inside interwiki links."""

0 commit comments

Comments
 (0)