diff options
| author | Michael Williamson <mike@zwobble.org> | 2026-09-12 09:57:20 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2026-09-12 09:57:20 +0100 |
| commit | d9678f1c64103c2062f30dc0dd66a5679ef0cf01 (patch) | |
| tree | 9b69ff684284da6ba80ac70f463984f58eebfbc4 | |
| parent | fd2f9f53fce3f7d07f1f6152e983b01a445c3049 (diff) | |
Handle missing complex field start characters
| -rw-r--r-- | NEWS | 3 | ||||
| -rw-r--r-- | mammoth/docx/body_xml.py | 10 | ||||
| -rw-r--r-- | tests/docx/body_xml_tests.py | 26 |
3 files changed, 39 insertions, 0 deletions
@@ -7,6 +7,9 @@ Note that it is still strongly recommended to process untrusted documents in a separate thread with a timeout to avoid potential similar issues. +* Handle complex field separator and end characters without corresponding start + characters. + # 1.12.1 * Fix: on Windows, when an image's content type includes a backslash in the diff --git a/mammoth/docx/body_xml.py b/mammoth/docx/body_xml.py index 2a1ffaf..4abf7f3 100644 --- a/mammoth/docx/body_xml.py +++ b/mammoth/docx/body_xml.py @@ -203,6 +203,11 @@ def _create_reader(numbering, content_types, relationships, styles, docx_file, f del current_instr_text[:] elif fld_char_type == "end": + if len(complex_field_stack) == 0: + return _empty_result_with_message(results.warning( + "ignoring complex field end character without corresponding start character", + )) + complex_field = complex_field_stack.pop() if isinstance(complex_field, complex_fields.Begin): complex_field = parse_current_instr_text(complex_field) @@ -211,6 +216,11 @@ def _create_reader(numbering, content_types, relationships, styles, docx_file, f return _success(documents.checkbox(checked=complex_field.checked)) elif fld_char_type == "separate": + if len(complex_field_stack) == 0: + return _empty_result_with_message(results.warning( + "ignoring complex field separator character without corresponding start character", + )) + complex_field_separate = complex_field_stack.pop() complex_field = parse_current_instr_text(complex_field_separate) complex_field_stack.append(complex_field) diff --git a/tests/docx/body_xml_tests.py b/tests/docx/body_xml_tests.py index 664fb5a..b524392 100644 --- a/tests/docx/body_xml_tests.py +++ b/tests/docx/body_xml_tests.py @@ -681,6 +681,32 @@ class ComplexFieldTests(object): is_empty_run, ))) + def test_separator_character_without_corresponding_start_character_is_ignored(self): + element = xml_element("w:p", {}, [ + self._SEPARATE_COMPLEX_FIELD, + ]) + + result = _read_document_xml_element(element) + + assert_that(result.value, is_paragraph(children=is_sequence( + is_empty_run, + ))) + expected_warning = results.warning("ignoring complex field separator character without corresponding start character") + assert_equal([expected_warning], result.messages) + + def test_end_character_without_corresponding_start_character_is_ignored(self): + element = xml_element("w:p", {}, [ + self._END_COMPLEX_FIELD, + ]) + + result = _read_document_xml_element(element) + + assert_that(result.value, is_paragraph(children=is_sequence( + is_empty_run, + ))) + expected_warning = results.warning("ignoring complex field end character without corresponding start character") + assert_equal([expected_warning], result.messages) + class CheckboxTests: def test_complex_field_checkbox_without_separate_is_read(self): |
