From b426d88c7f77ece0cca739af403d191066357b1f Mon Sep 17 00:00:00 2001 From: Sebastian Rasmussen Date: Thu, 12 Sep 2024 17:46:01 +0200 Subject: [PATCH] Move run processor initialization inside fz_try() to avoid leak upon TRYLATER. Without this fix if TRYLATER is thrown while looking up RoleMap the run processor and all its resources leak. --- source/pdf/pdf-op-run.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/source/pdf/pdf-op-run.c b/source/pdf/pdf-op-run.c index eb1c750806..2cd304f2f0 100644 --- a/source/pdf/pdf-op-run.c +++ b/source/pdf/pdf-op-run.c @@ -3195,6 +3195,26 @@ pdf_new_run_processor(fz_context *ctx, pdf_document *doc, fz_device *dev, fz_mat proc->gstate[0].clip_depth = 0; proc->gstate[0].ctm = ctm; } + + /* We need to save an extra level to allow for level 0 to be the parent gstate level. */ + pdf_gsave(ctx, proc); + + /* Structure details */ + { + pdf_obj *struct_tree_root = pdf_dict_getl(ctx, pdf_trailer(ctx, doc), PDF_NAME(Root), PDF_NAME(StructTreeRoot), NULL); + proc->struct_parent = struct_parent; + proc->role_map = pdf_keep_obj(ctx, pdf_dict_get(ctx, struct_tree_root, PDF_NAME(RoleMap))); + + /* Annotations and XObjects can be their own content items. We spot this by + * the struct_parent looking up to be a singular object. */ + if (struct_parent != -1 && struct_tree_root) + { + pdf_obj *struct_obj = pdf_lookup_number(ctx, pdf_dict_get(ctx, struct_tree_root, PDF_NAME(ParentTree)), struct_parent); + if (pdf_is_dict(ctx, struct_obj)) + send_begin_structure(ctx, proc, struct_obj); + /* We always end structure as required on closedown, so this is safe. */ + } + } } fz_catch(ctx) { @@ -3203,25 +3223,5 @@ pdf_new_run_processor(fz_context *ctx, pdf_document *doc, fz_device *dev, fz_mat fz_rethrow(ctx); } - /* We need to save an extra level to allow for level 0 to be the parent gstate level. */ - pdf_gsave(ctx, proc); - - /* Structure details */ - { - pdf_obj *struct_tree_root = pdf_dict_getl(ctx, pdf_trailer(ctx, doc), PDF_NAME(Root), PDF_NAME(StructTreeRoot), NULL); - proc->struct_parent = struct_parent; - proc->role_map = pdf_keep_obj(ctx, pdf_dict_get(ctx, struct_tree_root, PDF_NAME(RoleMap))); - - /* Annotations and XObjects can be their own content items. We spot this by - * the struct_parent looking up to be a singular object. */ - if (struct_parent != -1 && struct_tree_root) - { - pdf_obj *struct_obj = pdf_lookup_number(ctx, pdf_dict_get(ctx, struct_tree_root, PDF_NAME(ParentTree)), struct_parent); - if (pdf_is_dict(ctx, struct_obj)) - send_begin_structure(ctx, proc, struct_obj); - /* We always end structure as required on closedown, so this is safe. */ - } - } - return (pdf_processor*)proc; }