@@ -694,3 +694,38 @@ def test_get_qualified_field_name__cyclic() -> None:
694694 match = r"^Detected cycle in /Parent hierarchy when retrieving qualified field name\.$"
695695 ):
696696 _ = writer ._get_qualified_field_name (parent = dictionary1 )
697+
698+
699+ def test_build_outline_item__non_array_color (caplog ):
700+ """A malformed outline item whose /C is not an array must not crash."""
701+ writer = PdfWriter ()
702+ writer .add_blank_page (72 , 72 )
703+
704+ item = DictionaryObject ()
705+ writer ._add_object (item )
706+ item .update ({
707+ NameObject ("/Title" ): TextStringObject ("Bad color" ),
708+ NameObject ("/Dest" ): ArrayObject (
709+ [writer .pages [0 ].indirect_reference , NameObject ("/Fit" )]
710+ ),
711+ NameObject ("/C" ): NumberObject (5 ), # should be an [r, g, b] array
712+ })
713+ outlines = DictionaryObject ()
714+ writer ._add_object (outlines )
715+ outlines .update ({
716+ NameObject ("/Type" ): NameObject ("/Outlines" ),
717+ NameObject ("/First" ): item .indirect_reference ,
718+ NameObject ("/Last" ): item .indirect_reference ,
719+ })
720+ item [NameObject ("/Parent" )] = outlines .indirect_reference
721+ writer ._root_object [NameObject ("/Outlines" )] = outlines .indirect_reference
722+
723+ outline = writer .outline
724+ assert outline [0 ]["/Title" ] == "Bad color"
725+ assert "/C" not in outline [0 ]
726+ assert any ("outline color" in message for message in caplog .messages )
727+
728+ # The same value is read again, unsanitised, while cloning the outline
729+ # during append, so that path must tolerate it too.
730+ target = PdfWriter ()
731+ target .append (writer )
0 commit comments