Skip to content

Commit ccfa1d9

Browse files
committed
Handle an invalid plural index in msgstr[...] instead of raising ValueError
read_po parsed the plural index of a `msgstr[N]` line with `int(idxarg[:-1])`, which leaked a bare `ValueError: invalid literal for int()` to the caller when N was not an integer (e.g. `msgstr[\x0c]`). Route a non-integer index through the parser's existing `_invalid_pofile` handling, so it raises a `PoFileError` when `abort_invalid=True` and otherwise warns and skips the line, consistent with other malformed input. Fixes #1209
1 parent baf9431 commit ccfa1d9

2 files changed

Lines changed: 19 additions & 1 deletion

File tree

babel/messages/pofile.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,11 @@ def _process_keyword_line(self, lineno, line, obsolete=False) -> None:
276276
self.in_msgid = False
277277
self.in_msgstr = True
278278
kwarg, has_bracket, idxarg = keyword.partition('[')
279-
idx = int(idxarg[:-1]) if has_bracket else 0
279+
try:
280+
idx = int(idxarg[:-1]) if has_bracket else 0
281+
except ValueError:
282+
self._invalid_pofile(line, lineno, f"Invalid plural index in keyword {keyword!r}")
283+
return
280284
s = _NormalizedString(arg) if arg != '""' else _NormalizedString()
281285
self.translations.append([idx, s])
282286
return

tests/messages/test_pofile.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,3 +160,17 @@ def test_issue_1134(case: str, abort_invalid: bool):
160160
output = pofile.read_po(buf)
161161
assert len(output) == 1
162162
assert output["foo"].string in ((''), ('', ''))
163+
164+
165+
@pytest.mark.parametrize("abort_invalid", [False, True])
166+
def test_invalid_msgstr_index_issue_1209(abort_invalid: bool):
167+
# Regression test for #1209: a non-integer plural index in msgstr[...] must be reported
168+
# through the normal invalid-pofile handling, not leak a bare ValueError from int().
169+
buf = StringIO('msgstr[\x0c]')
170+
171+
if abort_invalid:
172+
with pytest.raises(pofile.PoFileError):
173+
pofile.read_po(buf, abort_invalid=True)
174+
else:
175+
# No crash: an invalid entry is skipped with a warning.
176+
pofile.read_po(buf)

0 commit comments

Comments
 (0)