2 commits - src/cairo-pdf-interchange.c test/pdf-structure.c

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue May 21 11:59:23 UTC 2024


 src/cairo-pdf-interchange.c |   10 +++++++-
 test/pdf-structure.c        |   50 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+), 1 deletion(-)

New commits:
commit d253188651f6c4ce9b170b815102a981623b51fd
Merge: 4b775b97b 1a0933d67
Author: Emmanuele Bassi <ebassi at gmail.com>
Date:   Tue May 21 11:59:14 2024 +0000

    Merge branch 'moz-bug-1896173' into 'master'
    
    pdf tags: Fix crash when popping the top most group following by a show_text
    
    See merge request cairo/cairo!549

commit 1a0933d67d4aa333ca4b04956e2129079633723d
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sun May 19 10:50:35 2024 +0930

    pdf tags: Fix crash when popping the top most group following by a show_text
    
    https://bugzilla.mozilla.org/show_bug.cgi?id=1896173

diff --git a/src/cairo-pdf-interchange.c b/src/cairo-pdf-interchange.c
index 6bda9e8b8..0e910fd22 100644
--- a/src/cairo-pdf-interchange.c
+++ b/src/cairo-pdf-interchange.c
@@ -1991,14 +1991,22 @@ _cairo_pdf_interchange_command_id (cairo_pdf_surface_t  *surface,
     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_RENDER && ic->current_render_node) {
 	/* TODO If the group does not have tags we don't need to close the current tag. */
 	if (command_list_is_group (surface, command_id)) {
+	    /* A "Do /xnnn" can not be inside a tag (since the
+	     * XObject may also contain tags). Close the tag.
+	     */
 	    if (ic->marked_content_open) {
 		status = _cairo_pdf_operators_tag_end (&surface->pdf_operators);
 		ic->marked_content_open = FALSE;
 	    }
-	    if (command_list_has_content (surface, command_id, NULL)) {
+	    /* If there is any more content after this and we are
+	     * inside a tag (current node is not the root node),
+	     * ensure that the next command will open the tag.
+	     */
+	    if (command_list_has_content (surface, command_id, NULL) && ic->current_render_node->parent) {
 		ic->render_next_command_has_content = TRUE;
 	    }
 	} else if (ic->render_next_command_has_content) {
+	    /* After a "Do /xnnn" operation, if there is more content, open the tag. */
 	    add_mcid_to_node (surface, ic->current_render_node, ic->command_id, &mcid);
 	    status = _cairo_pdf_operators_tag_begin (&surface->pdf_operators,
 						     ic->current_render_node->name, mcid);
diff --git a/test/pdf-structure.c b/test/pdf-structure.c
index ee4efe511..3ade6de8c 100644
--- a/test/pdf-structure.c
+++ b/test/pdf-structure.c
@@ -177,6 +177,54 @@ test_group (cairo_t *cr)
     cairo_tag_end (cr, "Document");
 }
 
+/* https://bugzilla.mozilla.org/show_bug.cgi?id=1896173
+ * This particular combination of tags and groups resulted in a crash.
+ */
+static void
+test_group2 (cairo_t *cr)
+{
+    cairo_tag_begin (cr, "H", "");
+    text (cr, "Heading");
+    cairo_tag_end (cr, "H");
+
+    cairo_push_group (cr);
+
+    cairo_tag_begin (cr, "P", "");
+    text (cr, "Para1");
+    cairo_tag_end (cr, "P");
+
+    cairo_pop_group_to_source (cr);
+    cairo_paint (cr);
+
+    cairo_set_source_rgb (cr, 0, 0, 0);
+    text (cr, "text");
+}
+
+/* Check that the fix for test_group2() works when there is a top level tag. */
+static void
+test_group3 (cairo_t *cr)
+{
+    cairo_tag_begin (cr, "Document", NULL);
+
+    cairo_tag_begin (cr, "H", "");
+    text (cr, "Heading");
+    cairo_tag_end (cr, "H");
+
+    cairo_push_group (cr);
+
+    cairo_tag_begin (cr, "P", "");
+    text (cr, "Para1");
+    cairo_tag_end (cr, "P");
+
+    cairo_pop_group_to_source (cr);
+    cairo_paint (cr);
+
+    cairo_set_source_rgb (cr, 0, 0, 0);
+    text (cr, "text");
+
+    cairo_tag_end (cr, "Document");
+}
+
 static void
 test_group_ref (cairo_t *cr)
 {
@@ -434,6 +482,8 @@ static const struct pdf_structure_test pdf_structure_tests[] = {
     { "simple", test_simple },
     { "simple-ref", test_simple_ref },
     { "group", test_group },
+    { "group2", test_group2 },
+    { "group3", test_group3 },
     { "group-ref", test_group_ref },
     { "repeated-group", test_repeated_group },
     { "multipage-simple", test_multipage_simple },


More information about the cairo-commit mailing list