瀏覽代碼

Fix empty-title wikilinks being incorrectly parsed as Wikilink nodes

MediaWiki does not treat [[]] or [[|...]] as wikilinks because their
title is empty. Calls to filter_wikilinks() on text containing these
sequences returned false positives.

The fix is in builder.py (pure Python, runs for both the C and Python
tokenizers): when a WikilinkClose token is encountered and the resulting
title is an empty string, the node is demoted to a plain Text node
containing the original bracket sequence instead of being wrapped in a
Wikilink.

Fixes #292.
pull/362/head
Vincent Gao 3 月之前
父節點
當前提交
3cee6bd2f0
沒有發現已知的金鑰在資料庫的簽署中 GPG 金鑰 ID: 4EB74F921300AF3B
共有 2 個檔案被更改,包括 29 行新增 和 2 行删除
  1. +8
    -2
      src/mwparserfromhell/parser/builder.py
  2. +21
    -0
      tests/test_parser.py

+ 8
- 2
src/mwparserfromhell/parser/builder.py 查看文件

@@ -162,8 +162,14 @@ class Builder:
self._push()
elif isinstance(token, tokens.WikilinkClose):
if title is not None:
return Wikilink(title, self._pop())
return Wikilink(self._pop())
wikilink = Wikilink(title, self._pop())
else:
wikilink = Wikilink(self._pop())
# MediaWiki treats [[]] and [[|...]] (empty title) as plain
# text rather than actual wikilinks.
if not str(wikilink.title):
return Text(str(wikilink))
return wikilink
else:
self._write(self._handle_token(token))
raise ParserError("_handle_wikilink() missed a close token")


+ 21
- 0
tests/test_parser.py 查看文件

@@ -102,3 +102,24 @@ def test_skip_style_tags(pyparser):
without_style = parser.Parser().parse(text, skip_style_tags=True)
assert_wikicode_equal(a, with_style)
assert_wikicode_equal(b, without_style)


@pytest.mark.parametrize(
"text",
[
"[[]]",
"[[|]]",
"[[|foo]]",
"[[|||]]",
],
)
def test_empty_title_wikilink_is_text(text):
"""[[]] and [[|...]] have an empty title and should not be wikilinks.

MediaWiki does not render these as hyperlinks; the parser must treat them
as plain text so that filter_wikilinks() does not return false positives.
Regression test for https://github.com/earwig/mwparserfromhell/issues/292.
"""
parsed = parser.Parser().parse(text)
assert parsed.filter_wikilinks() == []
assert str(parsed) == text

Loading…
取消
儲存