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
This commit is contained in:
Emmanuele Bassi 2024-05-21 11:59:14 +00:00
commit d253188651
2 changed files with 59 additions and 1 deletions

View file

@ -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);

View file

@ -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 },