diff options
Diffstat (limited to 'pdf/pdf_obj.c')
-rw-r--r-- | pdf/pdf_obj.c | 135 |
1 files changed, 108 insertions, 27 deletions
diff --git a/pdf/pdf_obj.c b/pdf/pdf_obj.c index 58bd59b0..aae9401b 100644 --- a/pdf/pdf_obj.c +++ b/pdf/pdf_obj.c @@ -36,12 +36,12 @@ int pdfi_object_alloc(pdf_context *ctx, pdf_obj_type type, unsigned int size, pdf_obj **obj) { int bytes = 0; + int code = 0; switch(type) { case PDF_ARRAY_MARK: case PDF_DICT_MARK: case PDF_PROC_MARK: - case PDF_NULL: bytes = sizeof(pdf_obj); break; case PDF_INT: @@ -50,7 +50,10 @@ int pdfi_object_alloc(pdf_context *ctx, pdf_obj_type type, unsigned int size, pd break; case PDF_STRING: case PDF_NAME: - bytes = sizeof(pdf_string) + size - sizeof(PDF_NAME_DECLARED_LENGTH); + bytes = sizeof(pdf_string) + size - PDF_NAME_DECLARED_LENGTH; + break; + case PDF_BUFFER: + bytes = sizeof(pdf_buffer); break; case PDF_ARRAY: bytes = sizeof(pdf_array); @@ -61,11 +64,8 @@ int pdfi_object_alloc(pdf_context *ctx, pdf_obj_type type, unsigned int size, pd case PDF_INDIRECT: bytes = sizeof(pdf_indirect_ref); break; - case PDF_BOOL: - bytes = sizeof(pdf_bool); - break; case PDF_KEYWORD: - bytes = sizeof(pdf_keyword) + size - sizeof(PDF_NAME_DECLARED_LENGTH); + bytes = sizeof(pdf_keyword) + size - PDF_NAME_DECLARED_LENGTH; break; /* The following aren't PDF object types, but are objects we either want to * reference count, or store on the stack. @@ -76,23 +76,34 @@ int pdfi_object_alloc(pdf_context *ctx, pdf_obj_type type, unsigned int size, pd case PDF_STREAM: bytes = sizeof(pdf_stream); break; + case PDF_NULL: + case PDF_BOOL: default: - return_error(gs_error_typecheck); + code = gs_note_error(gs_error_typecheck); + goto error_out; } *obj = (pdf_obj *)gs_alloc_bytes(ctx->memory, bytes, "pdfi_object_alloc"); - if (*obj == NULL) - return_error(gs_error_VMerror); + if (*obj == NULL) { + code = gs_note_error(gs_error_VMerror); + goto error_out; + } memset(*obj, 0x00, bytes); (*obj)->ctx = ctx; (*obj)->type = type; switch(type) { +/* PDF_NULL and PDF_BOOL are now handled as special (not allocated) data types + and we will return an error in the switch above if we get a call to allocate + one of these. Having the cases isn't harmful but Coverity complains of dead + code, so commenting these out to silence Coverity while preserving the old + semantics to indicate what's happening. case PDF_NULL: + case PDF_BOOL: */ + case PDF_INT: case PDF_REAL: case PDF_INDIRECT: - case PDF_BOOL: case PDF_ARRAY_MARK: case PDF_DICT_MARK: case PDF_PROC_MARK: @@ -102,6 +113,24 @@ int pdfi_object_alloc(pdf_context *ctx, pdf_obj_type type, unsigned int size, pd case PDF_NAME: ((pdf_string *)*obj)->length = size; break; + case PDF_BUFFER: + { + pdf_buffer *b = (pdf_buffer *)*obj; + /* NOTE: size can be 0 if the caller wants to allocate the data area itself + */ + if (size > 0) { + b->data = gs_alloc_bytes(ctx->memory, size, "pdfi_object_alloc"); + if (b->data == NULL) { + code = gs_note_error(gs_error_VMerror); + goto error_out; + } + } + else { + b->data = NULL; + } + b->length = size; + } + break; case PDF_ARRAY: { pdf_obj **values = NULL; @@ -110,10 +139,8 @@ int pdfi_object_alloc(pdf_context *ctx, pdf_obj_type type, unsigned int size, pd if (size > 0) { values = (pdf_obj **)gs_alloc_bytes(ctx->memory, size * sizeof(pdf_obj *), "pdfi_object_alloc"); if (values == NULL) { - gs_free_object(ctx->memory, *obj, "pdfi_object_alloc"); - gs_free_object(ctx->memory, values, "pdfi_object_alloc"); - *obj = NULL; - return_error(gs_error_VMerror); + code = gs_note_error(gs_error_VMerror); + goto error_out; } ((pdf_array *)*obj)->values = values; memset(((pdf_array *)*obj)->values, 0x00, size * sizeof(pdf_obj *)); @@ -128,9 +155,8 @@ int pdfi_object_alloc(pdf_context *ctx, pdf_obj_type type, unsigned int size, pd if (size > 0) { entries = (pdf_dict_entry *)gs_alloc_bytes(ctx->memory, size * sizeof(pdf_dict_entry), "pdfi_object_alloc"); if (entries == NULL) { - gs_free_object(ctx->memory, *obj, "pdfi_object_alloc"); - *obj = NULL; - return_error(gs_error_VMerror); + code = gs_note_error(gs_error_VMerror); + goto error_out; } ((pdf_dict *)*obj)->list = entries; memset(((pdf_dict *)*obj)->list, 0x00, size * sizeof(pdf_dict_entry)); @@ -150,6 +176,10 @@ int pdfi_object_alloc(pdf_context *ctx, pdf_obj_type type, unsigned int size, pd dmprintf2(ctx->memory, "Allocated object of type %c with UID %"PRIi64"\n", (*obj)->type, (*obj)->UID); #endif return 0; +error_out: + gs_free_object(ctx->memory, *obj, "pdfi_object_alloc"); + *obj = NULL; + return code; } /* Create a PDF number object from a numeric value. Attempts to create @@ -217,25 +247,36 @@ static void pdfi_free_stream(pdf_obj *o) gs_free_object(OBJ_MEMORY(o), o, "pdfi_free_stream"); } +static void pdfi_free_buffer(pdf_obj *o) +{ + pdf_buffer *b = (pdf_buffer *)o; + + gs_free_object(OBJ_MEMORY(b), b->data, "pdfi_free_buffer(data)"); + gs_free_object(OBJ_MEMORY(o), o, "pdfi_free_buffer"); +} + void pdfi_free_object(pdf_obj *o) { if (o == NULL) return; + if ((intptr_t)o < (intptr_t)TOKEN__LAST_KEY) + return; switch(o->type) { case PDF_ARRAY_MARK: case PDF_DICT_MARK: case PDF_PROC_MARK: - case PDF_NULL: case PDF_INT: case PDF_REAL: case PDF_INDIRECT: - case PDF_BOOL: gs_free_object(OBJ_MEMORY(o), o, "pdf interpreter object refcount to 0"); break; case PDF_STRING: case PDF_NAME: pdfi_free_namestring(o); break; + case PDF_BUFFER: + pdfi_free_buffer(o); + break; case PDF_ARRAY: pdfi_free_array(o); break; @@ -257,8 +298,12 @@ void pdfi_free_object(pdf_obj *o) case PDF_CMAP: pdfi_free_cmap(o); break; + case PDF_BOOL: + case PDF_NULL: + dbgmprintf(OBJ_MEMORY(o), "!!! Attempting to free non-allocated object type !!!\n"); + break; default: - dbgmprintf(OBJ_MEMORY(o), "!!! Attempting to free unknown obect type !!!\n"); + dbgmprintf(OBJ_MEMORY(o), "!!! Attempting to free unknown object type !!!\n"); break; } } @@ -274,7 +319,7 @@ int pdfi_obj_dict_to_stream(pdf_context *ctx, pdf_dict *dict, pdf_stream **strea int code = 0; pdf_stream *new_stream = NULL; - if (dict->type != PDF_DICT) + if (pdfi_type_of(dict) != PDF_DICT) return_error(gs_error_typecheck); code = pdfi_object_alloc(ctx, PDF_STREAM, 0, (pdf_obj **)&new_stream); @@ -445,7 +490,7 @@ int pdfi_obj_get_label(pdf_context *ctx, pdf_obj *obj, char **label) goto exit; } - if (obj->type == PDF_INDIRECT) + if (pdfi_type_of(obj) == PDF_INDIRECT) snprintf(string, length, template, ref->ref_object_num, ref->ref_generation_num); else snprintf(string, length, template, obj->object_num, obj->generation_num); @@ -566,10 +611,10 @@ static int pdfi_obj_indirect_str(pdf_context *ctx, pdf_obj *obj, byte **data, in if (code < 0 && code != gs_error_circular_reference) goto exit; if (code == 0) { - if (object->type == PDF_STREAM) { + if (pdfi_type_of(object) == PDF_STREAM) { code = pdfi_pdfmark_stream(ctx, (pdf_stream *)object); if (code < 0) goto exit; - } else if (object->type == PDF_DICT) { + } else if (pdfi_type_of(object) == PDF_DICT) { code = pdfi_pdfmark_dict(ctx, (pdf_dict *)object); if (code < 0) goto exit; } else { @@ -596,13 +641,12 @@ static int pdfi_obj_bool_str(pdf_context *ctx, pdf_obj *obj, byte **data, int *l { int code = 0; int size = 5; - pdf_bool *bool = (pdf_bool *)obj; char *buf; buf = (char *)gs_alloc_bytes(ctx->memory, size, "pdfi_obj_bool_str(data)"); if (buf == NULL) return_error(gs_error_VMerror); - if (bool->value) { + if (obj == PDF_TRUE_OBJ) { memcpy(buf, (byte *)"true", 4); *len = 4; } else { @@ -665,6 +709,8 @@ static int pdfi_obj_string_str(pdf_context *ctx, pdf_obj *obj, byte **data, int * can have special characters. So I will handle the minimum that seems needed for that. */ switch (*ptr) { + case 0x0a: + case 0x0d: case '(': case ')': case '\\': @@ -694,6 +740,16 @@ static int pdfi_obj_string_str(pdf_context *ctx, pdf_obj *obj, byte **data, int bufptr = buf + 1; for (i=0,ptr=string->data;i<string_len;i++) { switch (*ptr) { + case 0x0d: + *bufptr++ = '\\'; + *bufptr++ = 'r'; + ptr++; + continue; + case 0x0a: + *bufptr++ = '\\'; + *bufptr++ = 'n'; + ptr++; + continue; case '(': case ')': case '\\': @@ -920,6 +976,28 @@ static int pdfi_obj_dict_str(pdf_context *ctx, pdf_obj *obj, byte **data, int *l return code; } +#define PARAM1(A) # A, +#define PARAM2(A,B) A, +static const char pdf_token_strings[][10] = { +#include "pdf_tokens.h" +}; + +static int pdfi_obj_fast_keyword_str(pdf_context *ctx, pdf_obj *obj, byte **data, int *len) +{ + int code = 0; + const char *s = pdf_token_strings[(uintptr_t)obj]; + int size = (int)strlen(s) + 1; + byte *buf; + + buf = gs_alloc_bytes(ctx->memory, size, "pdfi_obj_name_str(data)"); + if (buf == NULL) + return_error(gs_error_VMerror); + memcpy(buf, s, size); + *data = buf; + *len = size; + return code; +} + obj_str_dispatch_t obj_str_dispatch[] = { {PDF_NAME, pdfi_obj_name_str}, {PDF_ARRAY, pdfi_obj_array_str}, @@ -931,6 +1009,7 @@ obj_str_dispatch_t obj_str_dispatch[] = { {PDF_STREAM, pdfi_obj_stream_str}, {PDF_INDIRECT, pdfi_obj_indirect_str}, {PDF_NULL, pdfi_obj_null_str}, + {PDF_FAST_KEYWORD, pdfi_obj_fast_keyword_str}, {0, NULL} }; @@ -940,11 +1019,13 @@ int pdfi_obj_to_string(pdf_context *ctx, pdf_obj *obj, byte **data, int *len) { obj_str_dispatch_t *dispatch_ptr; int code = 0; + pdf_obj_type type; *data = NULL; *len = 0; + type = pdfi_type_of(obj); for (dispatch_ptr = obj_str_dispatch; dispatch_ptr->func; dispatch_ptr ++) { - if (obj->type == dispatch_ptr->type) { + if (type == dispatch_ptr->type) { code = dispatch_ptr->func(ctx, obj, data, len); goto exit; } |