summaryrefslogtreecommitdiff
path: root/src/cos_parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cos_parse.c')
-rw-r--r--src/cos_parse.c142
1 files changed, 93 insertions, 49 deletions
diff --git a/src/cos_parse.c b/src/cos_parse.c
index 5ccd171..46282ca 100644
--- a/src/cos_parse.c
+++ b/src/cos_parse.c
@@ -1115,6 +1115,10 @@ parse_operator(struct cos_stream *stream,
offset = *offset_out;
+ if (offset >= stream->length) {
+ return NSPDFERROR_SYNTAX;
+ }
+
/* first char */
c = stream_byte(stream, offset);
if ((bclass[c] & (BC_WSPC | BC_CMNT) ) != 0) {
@@ -1125,13 +1129,15 @@ parse_operator(struct cos_stream *stream,
offset++;
/* possible second char */
c = stream_byte(stream, offset);
- if ((bclass[c] & (BC_WSPC | BC_CMNT) ) == 0) {
+ if ((offset < stream->length) &&
+ ((bclass[c] & (BC_WSPC | BC_CMNT) ) == 0)) {
lookup = (lookup << 8) | c;
offset++;
/* possible third char */
c = stream_byte(stream, offset);
- if ((bclass[c] & (BC_WSPC | BC_CMNT) ) == 0) {
+ if ((offset < stream->length) &&
+ ((bclass[c] & (BC_WSPC | BC_CMNT) ) == 0)) {
lookup = (lookup << 8) | c;
offset++;
@@ -1241,55 +1247,60 @@ parse_operator(struct cos_stream *stream,
#define MAX_OPERAND_COUNT 32
-static nspdferror
+static inline nspdferror
parse_content_operation(struct nspdf_doc *doc,
struct cos_stream *stream,
strmoff_t *offset_out,
+ struct cos_object **operands,
+ unsigned int *operand_idx,
struct content_operation *operation_out)
{
strmoff_t offset;
nspdferror res;
enum content_operator operator;
- struct cos_object *operands[MAX_OPERAND_COUNT];
- unsigned int operand_idx = 0;
offset = *offset_out;
res = parse_operator(stream, &offset, &operator);
while (res == NSPDFERROR_SYNTAX) {
/* was not an operator so check for what else it could have been */
- if (operand_idx >= MAX_OPERAND_COUNT) {
+ if (*operand_idx >= MAX_OPERAND_COUNT) {
/** \todo free any stacked operands */
printf("too many operands\n");
return NSPDFERROR_SYNTAX;
}
+ if (offset >= stream->length) {
+ *offset_out = offset;
+ return NSPDFERROR_INCOMPLETE;
+ }
+
switch (stream_byte(stream, offset)) {
case '-': case '+': case '.': case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7': case '8': case '9':
- res = cos_parse_number(stream, &offset, &operands[operand_idx]);
+ res = cos_parse_number(stream, &offset, &operands[*operand_idx]);
break;
case 't':
case 'f':
- res = cos_parse_boolean(stream, &offset, &operands[operand_idx]);
+ res = cos_parse_boolean(stream, &offset, &operands[*operand_idx]);
break;
case 'n':
- res = cos_parse_null(stream, &offset, &operands[operand_idx]);
+ res = cos_parse_null(stream, &offset, &operands[*operand_idx]);
break;
case '(':
- res = cos_parse_string(stream, &offset, &operands[operand_idx]);
+ res = cos_parse_string(stream, &offset, &operands[*operand_idx]);
break;
case '/':
- res = cos_parse_name(stream, &offset, &operands[operand_idx]);
+ res = cos_parse_name(stream, &offset, &operands[*operand_idx]);
break;
case '[':
- res = cos_parse_list(doc, stream, &offset, &operands[operand_idx]);
+ res = cos_parse_list(doc, stream, &offset, &operands[*operand_idx]);
break;
case '<':
@@ -1297,16 +1308,23 @@ parse_content_operation(struct nspdf_doc *doc,
res = cos_parse_dictionary(doc,
stream,
&offset,
- &operands[operand_idx]);
+ &operands[*operand_idx]);
} else {
res = cos_parse_hex_string(stream,
&offset,
- &operands[operand_idx]);
+ &operands[*operand_idx]);
}
break;
default:
- printf("unknown operand type\n");
+ printf("unknown operand with %d operands %d to %d of %d\n>>>%.*s<<<\n",
+ *operand_idx,
+ (*offset_out),
+ offset,
+ stream->length,
+ (offset + 1) - (*offset_out),
+ stream->data + (*offset_out));
+
res = NSPDFERROR_SYNTAX; /* syntax error */
}
@@ -1319,26 +1337,44 @@ parse_content_operation(struct nspdf_doc *doc,
}
/* move to next operand */
- operand_idx++;
+ (*operand_idx)++;
res = parse_operator(stream, &offset, &operator);
}
operation_out->operator = operator;
- //printf("returning operator %d with %d operands\n", operator, operand_idx);
+
+ /*
+ printf("returning operator %d with %d operands %d to %d of %d\n>>>%.*s<<<\n",
+ operator,
+ *operand_idx,
+ (*offset_out),
+ offset,
+ stream->length,
+ offset - (*offset_out),
+ stream->data + (*offset_out));
+ */
+
+ *operand_idx = 0;
*offset_out = offset;
+
return NSPDFERROR_OK;
}
nspdferror
-cos_parse_content_stream(struct nspdf_doc *doc,
- struct cos_stream *stream,
- struct cos_object **content_out)
+cos_parse_content_streams(struct nspdf_doc *doc,
+ struct cos_stream **streams,
+ unsigned int stream_count,
+ struct cos_object **content_out)
{
nspdferror res;
struct cos_object *cosobj;
strmoff_t offset;
+ struct cos_stream *stream;
+ unsigned int stream_index;
+ struct cos_object *operands[MAX_OPERAND_COUNT];
+ unsigned int operand_idx = 0;
//printf("%.*s", (int)stream->length, stream->data);
@@ -1354,42 +1390,50 @@ cos_parse_content_stream(struct nspdf_doc *doc,
goto cos_parse_content_stream_error;
}
- offset = 0;
+ for (stream_index = 0; stream_index < stream_count; stream_index++) {
+ stream = *(streams + stream_index);
+ offset = 0;
- /* skip any leading whitespace */
- res = nspdf__stream_skip_ws(stream, &offset);
- if (res != NSPDFERROR_OK) {
- goto cos_parse_content_stream_error;
- }
+ /* skip any leading whitespace */
+ res = nspdf__stream_skip_ws(stream, &offset);
+ if (res != NSPDFERROR_OK) {
+ goto cos_parse_content_stream_error;
+ }
+
+ while (offset < stream->length) {
+
+ /* ensure there is space in the operations array */
+ if (cosobj->u.content->alloc < (cosobj->u.content->length + 1)) {
+ struct content_operation *newops;
+ newops = realloc(cosobj->u.content->operations,
+ sizeof(struct content_operation) *
+ (cosobj->u.content->alloc + 32));
+ if (newops == NULL) {
+ res = NSPDFERROR_NOMEM;
+ goto cos_parse_content_stream_error;
+ }
+ cosobj->u.content->operations = newops;
+ cosobj->u.content->alloc += 32;
+ }
- while (offset < stream->length) {
- struct content_operation cop;
-
- /* ensure there is space in the operations array */
- if (cosobj->u.content->alloc < (cosobj->u.content->length + 1)) {
- struct content_operation *newops;
- newops = realloc(cosobj->u.content->operations,
- sizeof(struct content_operation) *
- (cosobj->u.content->alloc + 32));
- if (newops == NULL) {
- res = NSPDFERROR_NOMEM;
+ /* parse an operation out */
+ res = parse_content_operation(
+ doc,
+ stream,
+ &offset,
+ operands,
+ &operand_idx,
+ cosobj->u.content->operations + cosobj->u.content->length);
+ if (res== NSPDFERROR_OK) {
+ cosobj->u.content->length++;
+ } else if (res == NSPDFERROR_INCOMPLETE) {
+ //printf("Incomplete\n");
+ } else if (res != NSPDFERROR_OK) {
goto cos_parse_content_stream_error;
}
- cosobj->u.content->operations = newops;
- cosobj->u.content->alloc += 32;
- }
- res = parse_content_operation(
- doc,
- stream,
- &offset,
- cosobj->u.content->operations + cosobj->u.content->length);
- if (res != NSPDFERROR_OK) {
- goto cos_parse_content_stream_error;
}
- cosobj->u.content->length++;
}
-
*content_out = cosobj;
return NSPDFERROR_OK;