From 13760a9291a2702a1a29ecac142533d52ec10ae2 Mon Sep 17 00:00:00 2001 From: Shubham Padkonde Date: Thu, 1 Oct 2026 23:14:34 +0530 Subject: [PATCH] fix: reject negative subtitle word limits --- tests/test_utils.py | 42 ++++++++++++++++++++++++++++++++++++++++++ whisper/utils.py | 2 ++ 2 files changed, 44 insertions(+) create mode 100644 tests/test_utils.py diff --git a/tests/test_utils.py b/tests/test_utils.py new file mode 100644 index 000000000..9598075b6 --- /dev/null +++ b/tests/test_utils.py @@ -0,0 +1,42 @@ +import pytest + +from whisper.utils import WriteSRT, WriteVTT + + +@pytest.mark.parametrize("writer_class", [WriteSRT, WriteVTT]) +@pytest.mark.parametrize("use_options", [False, True]) +@pytest.mark.parametrize("empty", [False, True]) +def test_negative_word_limit(writer_class, use_options, empty): + writer = writer_class(".") + limits = {"max_words_per_line": -1} + kwargs = {"options": limits} if use_options else limits + segments = ( + [] + if empty + else [{"start": 0.0, "words": [{"start": 0.0, "end": 1.0, "word": "one"}]}] + ) + with pytest.raises(ValueError, match="max_words_per_line"): + list(writer.iterate_result({"segments": segments}, **kwargs)) + + +@pytest.mark.parametrize("writer_class", [WriteSRT, WriteVTT]) +@pytest.mark.parametrize( + "limit,expected", + [(None, ["one two"]), (0, ["one two"]), (1, ["one", "two"]), (2, ["one two"])], +) +def test_word_limit(writer_class, limit, expected): + result = { + "segments": [ + { + "start": 0.0, + "end": 2.0, + "text": "one two", + "words": [ + {"start": 0.0, "end": 1.0, "word": "one"}, + {"start": 1.0, "end": 2.0, "word": " two"}, + ], + } + ] + } + subtitles = writer_class(".").iterate_result(result, max_words_per_line=limit) + assert [text for _, _, text in subtitles] == expected diff --git a/whisper/utils.py b/whisper/utils.py index 79658fc75..65a386eef 100644 --- a/whisper/utils.py +++ b/whisper/utils.py @@ -135,6 +135,8 @@ def iterate_result( max_line_count = max_line_count or options.get("max_line_count") highlight_words = highlight_words or options.get("highlight_words", False) max_words_per_line = max_words_per_line or options.get("max_words_per_line") + if max_words_per_line is not None and max_words_per_line < 0: + raise ValueError("max_words_per_line must be non-negative") preserve_segments = max_line_count is None or max_line_width is None max_line_width = max_line_width or 1000 max_words_per_line = max_words_per_line or 1000