From ac616c270dbcfaf5a70aef97cf989407f757fcbe Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sat, 13 Feb 2021 10:00:42 +0100 Subject: [PATCH] Fix a memory leak with cairo_tag_begin() + pdf The error paths in _cairo_pdf_interchange_begin_dest_tag() do not clean up and cause some memory to be leaked. Fix this by adding the necessary free()s. The first hunk, the missing free(dest) was found by oss-fuzz (see link below). The second hunk is an obvious follow up. It also cleans up the memory allocated by _cairo_tag_parse_dest_attributes(). The cleanup in the second hunk is similar to the function _named_dest_pluck() in the same function, but that function also removes the entry from a hash table. The error case here is that exactly this hash table insertion failed. Thus, the code cannot simply use the already existing function. Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=30880 Signed-off-by: Uli Schlachter --- src/cairo-pdf-interchange.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/cairo-pdf-interchange.c b/src/cairo-pdf-interchange.c index 0f896d351..434486cc9 100644 --- a/src/cairo-pdf-interchange.c +++ b/src/cairo-pdf-interchange.c @@ -1134,13 +1134,20 @@ _cairo_pdf_interchange_begin_dest_tag (cairo_pdf_surface_t *surface, status = _cairo_tag_parse_dest_attributes (attributes, &dest->attrs); if (unlikely (status)) + { + free (dest); return status; + } dest->page = _cairo_array_num_elements (&surface->pages); init_named_dest_key (dest); status = _cairo_hash_table_insert (ic->named_dests, &dest->base); if (unlikely (status)) + { + free (dest->attrs.name); + free (dest); return status; + } _cairo_tag_stack_set_top_data (&ic->analysis_tag_stack, dest); cairo_list_add_tail (&dest->extents.link, &ic->extents_list);