diff --git a/src/wikitextprocessor/parserfns.py b/src/wikitextprocessor/parserfns.py
index 796e779d..11723dc2 100644
--- a/src/wikitextprocessor/parserfns.py
+++ b/src/wikitextprocessor/parserfns.py
@@ -586,12 +586,20 @@ def ucfirst_fn(
return capitalizeFirstOnly(t)
+ALLOWED = {".", ",", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"}
+
+
def formatnum_fn(
ctx: "Wtp", fn_name: str, args: list[str], expander: Callable[[str], str]
) -> str:
"""Implements the formatnum parser function."""
arg0 = expander(args[0]).strip() if args else ""
+ if arg0 == "" or not (set(arg0) <= ALLOWED) or arg0.count(".") > 1:
+ return arg0
arg1 = expander(args[1]).strip() if len(args) >= 2 else ""
+ if "," in arg0:
+ if arg1 != "R":
+ return arg0
if arg1 == "R":
# Reverse formatting
# XXX this is a very simplified implementation, should handle more cases
diff --git a/tests/test_wikiprocess.py b/tests/test_wikiprocess.py
index 58b5ebfa..632b66c1 100644
--- a/tests/test_wikiprocess.py
+++ b/tests/test_wikiprocess.py
@@ -608,6 +608,30 @@ def test_formatnum9(self):
def test_formatnum10(self):
self.parserfn("{{formatnum:12345}}", "12,345")
+ def test_formatnum11(self):
+ # only numerals + . + ,
+ self.parserfn("{{formatnum:µB}}", "µB")
+
+ def test_formatnum12(self):
+ # no bad decimals
+ self.parserfn("{{formatnum:123.4.5}}", "123.4.5")
+
+ def test_formatnum13(self):
+ # no spaces
+ self.parserfn("{{formatnum:123 4.5}}", "123 4.5")
+
+ def test_formatnum13_b(self):
+ # ... except a the start and end
+ self.parserfn("{{formatnum: 1234.5 }}", "1,234.5")
+
+ def test_formatnum14(self):
+ # bad commas allowed when |R|eversing
+ self.parserfn("{{formatnum:123,4.5|R}}", "1234.5")
+
+ def test_formatnum15(self):
+ # commas in decimals allowed when |R|eversing
+ self.parserfn("{{formatnum:1234.5,4|R}}", "1234.54")
+
def test_dateformat1(self):
self.parserfn("{{#dateformat:25 dec 2009|ymd}}", "2009 Dec 25")