diff options
Diffstat (limited to 'pdf/ghostpdf.h')
-rw-r--r-- | pdf/ghostpdf.h | 141 |
1 files changed, 53 insertions, 88 deletions
diff --git a/pdf/ghostpdf.h b/pdf/ghostpdf.h index 3cc1b8cd..49c91808 100644 --- a/pdf/ghostpdf.h +++ b/pdf/ghostpdf.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018-2021 Artifex Software, Inc. +/* Copyright (C) 2018-2022 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -32,6 +32,18 @@ #define PDFI_LEAK_CHECK 0 #endif +/* A structure for setting/resetting the interpreter graphics state + * and some graphics state content when switching between Ghostscript + * and pdfi, when running under GS. + */ +typedef struct pdf_context_switch { + gs_gstate *pgs; + gs_font *psfont; + gs_gstate_client_procs procs; + void *client_data; + void *profile_cache; +} pdfi_switch_t; + /* * The interpreter context. */ @@ -42,82 +54,13 @@ * how to deal with this. */ typedef enum pdf_error_e { - E_PDF_NOERROR, - E_PDF_NOHEADER, - E_PDF_NOHEADERVERSION, - E_PDF_NOSTARTXREF, - E_PDF_BADSTARTXREF, - E_PDF_BADXREFSTREAM, - E_PDF_BADXREF, - E_PDF_SHORTXREF, - E_PDF_MISSINGENDSTREAM, - E_PDF_UNKNOWNFILTER, - E_PDF_MISSINGWHITESPACE, - E_PDF_MALFORMEDNUMBER, - E_PDF_UNESCAPEDSTRING, - E_PDF_BADOBJNUMBER, - E_PDF_MISSINGENDOBJ, - E_PDF_TOKENERROR, - E_PDF_KEYWORDTOOLONG, - E_PDF_BADPAGETYPE, - E_PDF_CIRCULARREF, - E_PDF_UNREPAIRABLE, - E_PDF_REPAIRED, - E_PDF_BADSTREAM, - E_PDF_MISSINGOBJ, - E_PDF_BADPAGEDICT, - E_PDF_OUTOFMEMORY, - E_PDF_PAGEDICTERROR, - E_PDF_STACKUNDERFLOWERROR, - E_PDF_BADSTREAMDICT, - E_PDF_INHERITED_STREAM_RESOURCE, - E_PDF_DEREF_FREE_OBJ, - E_PDF_INVALID_TRANS_XOBJECT, - E_PDF_NO_SUBTYPE, - E_PDF_IMAGECOLOR_ERROR, - E_PDF_MAX_ERROR /* Must be last entry, add new errors immediately before this and update pdf_error_strings in ghostpdf.c */ +#include "pdf_errors.h" + E_PDF_MAX_ERROR /* last entry */ }pdf_error; typedef enum pdf_warning_e { - W_PDF_NOWARNING, - W_PDF_BAD_XREF_SIZE, - W_PDF_BAD_INLINEFILTER, - W_PDF_BAD_INLINECOLORSPACE, - W_PDF_BAD_INLINEIMAGEKEY, - W_PDF_IMAGE_ERROR, - W_PDF_BAD_IMAGEDICT, - W_PDF_TOOMANYQ, - W_PDF_TOOMANYq, - W_PDF_STACKGARBAGE, - W_PDF_STACKUNDERFLOW, - W_PDF_GROUPERROR, - W_PDF_OPINVALIDINTEXT, - W_PDF_NOTINCHARPROC, - W_PDF_NESTEDTEXTBLOCK, - W_PDF_ETNOTEXTBLOCK, - W_PDF_TEXTOPNOBT, - W_PDF_DEGENERATETM, - W_PDF_BADICC_USE_ALT, - W_PDF_BADICC_USECOMPS, - W_PDF_BADTRSWITCH, - W_PDF_BADSHADING, - W_PDF_BADPATTERN, - W_PDF_NONSTANDARD_OP, - W_PDF_NUM_EXPONENT, - W_PDF_STREAM_HAS_CONTENTS, - W_PDF_STREAM_BAD_DECODEPARMS, - W_PDF_MASK_ERROR, - W_PDF_ANNOT_AP_ERROR, - W_PDF_BAD_NAME_ESCAPE, - W_PDF_TYPECHECK, - W_PDF_BAD_TRAILER, - W_PDF_ANNOT_ERROR, - W_PDF_BAD_ICC_PROFILE_LINK, - W_PDF_OVERFLOW_REAL, - W_PDF_INVALID_REAL, - W_PDF_DEVICEN_USES_ALL, - W_PDF_BAD_MEDIABOX, - W_PDF_MAX_WARNING /* Must be last entry, add new warnings immediately before this and update pdf_warning_strings in ghostpdf.c */ +#include "pdf_warnings.h" + W_PDF_MAX_WARNING /* last entry */ } pdf_warning; #define PDF_ERROR_BYTE_SIZE ((E_PDF_MAX_ERROR - 1) / (sizeof(char) * 8) + 1) @@ -132,12 +75,11 @@ typedef enum pdf_crypt_filter_e { CRYPT_AESV3, /* 256-bit AES */ } pdf_crypt_filter; - -typedef enum pdf_overprint_control_e { - PDF_OVERPRINT_ENABLE = 0,/* Default */ - PDF_OVERPRINT_DISABLE, - PDF_OVERPRINT_SIMULATE -} pdf_overprint_control_t; +typedef enum pdf_type3_d_type_e { + pdf_type3_d_none, + pdf_type3_d0, + pdf_type3_d1 +} pdf_type3_d_type; #define INITIAL_STACK_SIZE 32 #define MAX_STACK_SIZE 524288 @@ -188,6 +130,7 @@ typedef struct cmd_args_s { bool dopdfmarks; bool preserveannots; char **preserveannottypes; /* Null terminated array of strings, NULL if none */ + bool preservemarkedcontent; bool nouserunit; bool renderttnotdef; bool pdfinfo; @@ -196,11 +139,14 @@ typedef struct cmd_args_s { bool ditherppi; int PDFX3Profile_num; char *UseOutputIntent; - pdf_overprint_control_t overprint_control; /* Overprint -- enabled, disabled, simulated */ char *PageList; bool QUIET; bool verbose_errors; bool verbose_warnings; + gs_string cidsubstpath; + gs_string cidsubstfont; + bool ignoretounicode; + bool nonativefontmap; } cmd_args_t; typedef struct encryption_state_s { @@ -285,8 +231,14 @@ typedef struct text_state_s { /* We need to know if we're in a type 3 CharProc which has executed a 'd1' operator. * Colour operators are technically invalid if we are in a 'd1' context and we must * ignore them. + * OSS-fuzz #45320 has a type 3 font with a BuildChar which has a 'RG' before the + * d1. This is (obviously) illegal because the spec says the first operation must + * be either a d0 or d1, in addition because of the graphics state depth hackery + * (see comments in pdf_d0() in pdf_font.c) this messes up the reference counting + * of the colour spaces, leading to a crash. So what was a boolean flag is now an + * enumerated type; pdf_type3_d_none, pdf_type3_d0 or pdf_type3_d1. */ - bool CharProc_is_d1; + pdf_type3_d_type CharProc_d_type; /* If there is no current point when we do a BT we start by doing a 0 0 moveto in order * to establish an initial point. However, this also starts a path. When we finish * off with a BT we need to clear that path by doing a newpath, otherwise we might @@ -342,6 +294,7 @@ typedef struct search_paths_s typedef struct pdf_context_s { + pdf_obj_common; void *instance; gs_memory_t *memory; @@ -376,6 +329,7 @@ typedef struct pdf_context_s /* Optional/Marked Content stuff */ void *OFFlevels; uint64_t BMClevel; + bool BDCWasOC; /* Bitfields recording whether any errors or warnings were encountered */ char pdf_errors[PDF_ERROR_BYTE_SIZE]; @@ -424,6 +378,9 @@ typedef struct pdf_context_s /* Document level PDF objects */ xref_table_t *xref_table; + /* Warning! Do not use ctx->Trailer directly as it may be replaced if the file is repaired. + * See pdf_doc.c, pdf_read_Root() + */ pdf_dict *Trailer; pdf_dict *Root; pdf_dict *Info; @@ -433,9 +390,6 @@ typedef struct pdf_context_s pdf_dict *AcroForm; bool NeedAppearances; /* From AcroForm, if any */ - - /* Interpreter level PDF objects */ - /* The interpreter operand stack */ uint32_t stack_size; pdf_obj **stack_bot; @@ -463,8 +417,13 @@ typedef struct pdf_context_s /* A name table :-( */ pdfi_name_entry_t *name_table; + gs_string *fontmapfiles; + int num_fontmapfiles; + search_paths_t search_paths; pdf_dict *pdffontmap; + pdf_dict *pdfnativefontmap; /* Explicit mappings take precedence, hence we need separate dictionaries */ + pdf_dict *pdfcidfmap; /* These function pointers can be replaced by ones intended to replicate * PostScript functionality when running inside the Ghostscript PostScript @@ -475,7 +434,7 @@ typedef struct pdf_context_s int (*get_glyph_index)(gs_font *font, byte *str, uint size, uint *glyph); #if REFCNT_DEBUG - uint64_t UID; + uint64_t ref_UID; #endif #if CACHE_STATISTICS uint64_t hits; @@ -493,6 +452,7 @@ typedef struct pdf_context_s int pdfi_add_paths_to_search_paths(pdf_context *ctx, const char *ppath, int l, bool fontpath); int pdfi_add_initial_paths_to_search_paths(pdf_context *ctx, const char *ppath, int l); +int pdfi_add_fontmapfiles(pdf_context *ctx, const char *ppath, int l); pdf_context *pdfi_create_context(gs_memory_t *pmem); int pdfi_clear_context(pdf_context *ctx); @@ -506,9 +466,10 @@ int pdfi_set_input_stream(pdf_context *ctx, stream *stm); int pdfi_process_pdf_file(pdf_context *ctx, char *filename); int pdfi_prep_collection(pdf_context *ctx, uint64_t *TotalFiles, char ***names_array); int pdfi_close_pdf_file(pdf_context *ctx); -void pdfi_gstate_from_PS(pdf_context *ctx, gs_gstate *pgs, void **saved_client_data, gs_gstate_client_procs *saved_procs); -void pdfi_gstate_to_PS(pdf_context *ctx, gs_gstate *pgs, void *client_data, const gs_gstate_client_procs *procs); +int pdfi_gstate_from_PS(pdf_context *ctx, gs_gstate *pgs, pdfi_switch_t *i_switch, gsicc_profile_cache_t *profile_cache); +void pdfi_gstate_to_PS(pdf_context *ctx, gs_gstate *pgs, pdfi_switch_t *i_switch); +void pdfi_report_errors(pdf_context *ctx); void pdfi_verbose_error(pdf_context *ctx, int gs_error, const char *gs_lib_function, int pdfi_error, const char *pdfi_function_name, const char *extra_info); void pdfi_verbose_warning(pdf_context *ctx, int gs_error, const char *gs_lib_function, int pdfi_warning, const char *pdfi_function_name, const char *extra_info); void pdfi_log_info(pdf_context *ctx, const char *pdfi_function, const char *info); @@ -528,6 +489,10 @@ static inline void pdfi_set_warning(pdf_context *ctx, int gs_error, const char * pdfi_verbose_warning(ctx, gs_error, gs_lib_function, pdfi_warning, pdfi_function_name, extra_info); } +/* Variants of the above that work in a printf style. */ +void pdfi_set_error_var(pdf_context *ctx, int gs_error, const char *gs_lib_function, pdf_error pdfi_error, const char *pdfi_function_name, const char *fmt, ...); +void pdfi_set_warning_var(pdf_context *ctx, int gs_error, const char *gs_lib_function, pdf_warning pdfi_warning, const char *pdfi_function_name, const char *fmt, ...); + #define PURGE_CACHE_PER_PAGE 0 #if PURGE_CACHE_PER_PAGE |