diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml index 7a8b28e..ba7e053 100644 --- a/.github/workflows/cifuzz.yml +++ b/.github/workflows/cifuzz.yml @@ -25,13 +25,13 @@ jobs: steps: - name: Build Fuzzers id: build - uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@675ddfb89ae1c614f1dfa99d18b91cd6d1d6b88b # master 2026-04-10 + uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@9ff5089dbb11800055b6bc1af919a84b06dee2c8 # master 2026-04-27 with: oss-fuzz-project-name: "python-multipart" language: python - name: Run Fuzzers - uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@675ddfb89ae1c614f1dfa99d18b91cd6d1d6b88b # master 2026-04-10 + uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@9ff5089dbb11800055b6bc1af919a84b06dee2c8 # master 2026-04-27 with: oss-fuzz-project-name: "python-multipart" language: python diff --git a/python_multipart/multipart.py b/python_multipart/multipart.py index 2435bdc..3b7d385 100644 --- a/python_multipart/multipart.py +++ b/python_multipart/multipart.py @@ -171,7 +171,10 @@ def parse_options_header(value: str | bytes | None) -> tuple[bytes, dict[bytes, # ctype, rest = value.split(b';', 1) message = Message() message["content-type"] = value - params = message.get_params() + try: + params = message.get_params() + except (TypeError, ValueError): + return (value.lower().strip().encode("latin-1"), {}) # If there were no parameters, this would have already returned above assert params, "At least the content type value should be present" ctype = params.pop(0)[0].encode("latin-1") diff --git a/tests/test_multipart.py b/tests/test_multipart.py index fce3253..b541ab1 100644 --- a/tests/test_multipart.py +++ b/tests/test_multipart.py @@ -304,6 +304,18 @@ def test_handles_rfc_2231(self) -> None: self.assertEqual(p[b"param"], b"encoded message") + def test_handles_oversized_rfc_2231_index(self) -> None: + t, p = parse_options_header("text/plain; filename*" + ("1" * 4301) + "*=utf-8''x") + + self.assertEqual(t, b"text/plain; filename*" + (b"1" * 4301) + b"*=utf-8''x") + self.assertEqual(p, {}) + + def test_handles_mixed_rfc_2231_continuations(self) -> None: + t, p = parse_options_header("text/plain; filename*=utf-8''a; filename*0*=utf-8''b") + + self.assertIn(t, (b"text/plain", b"text/plain; filename*=utf-8''a; filename*0*=utf-8''b")) + self.assertIn(p, ({}, {b"filename": b"b"})) + class TestBaseParser(unittest.TestCase): def setUp(self) -> None: