summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'pdf/pdf_obj.c')
-rw-r--r--pdf/pdf_obj.c135
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;
}