#include #include #include #include #include #include #include #include "cpdf.h" #include "parse.h" #include "utils.h" /* function compute number of locations of char c from buffer to character c */ int strlenc(char *buffer, char c, char to) { int i = 0; while (*buffer && *buffer != to) { if (*buffer == c) i++; buffer++; } return i; } /* function compute lenght of string to char to */ int strlento(char *buffer, char to) { int i = 0; while (*buffer && *buffer != to) { i++; buffer++; } return i; } /* convert hex to bin */ char *hex(char *buffer) { char *hex_array, *end; char num[5] = { '0', 'x', '\0', '\0', '\0' }; int i; if (*buffer != '<') return NULL; if ((i = strlento(buffer + 1, '>') >> 1) == 0) return NULL; end = hex_array = (char *) xmalloc(i); for (buffer++; *buffer != '>'; hex_array++) { num[2] = *buffer; if (*(buffer + 1) == '>') { num[3] = '0'; buffer++; } else { num[3] = *(buffer + 1); buffer += 2; } *hex_array = (char) strtoul((char *) &num, NULL, 16); } return end; } /* interpreter for special characters in name string */ char *name(char *buffer) { char *ret, *end; char num[5] = { '0', 'x', '\0', '\0', '\0' }; if (*buffer != '/') return NULL; if (memchr(buffer, '#', MAXNAMELEN) == NULL) return buffer; end = ret = (char *) xmalloc(MAXNAMELEN); while (*buffer && *buffer != ' ') { if (*buffer == '#') { num[2] = *(buffer + 1); num[3] = *(buffer + 2); *ret = (char) strtoul((char *) &num, NULL, 16); ret++; buffer += 3; } *ret = *buffer; ret++; buffer++; } return end; } /* parse arrays */ char **array(char *buffer) { char **ret = NULL; int end = 1, len, index = 0; if (*buffer != '[') return NULL; ret[index] = (char *) xmalloc(1); *ret[index] = '['; index++; buffer += 2; do { if (*buffer == ']') end--; if (*buffer == '[') end++; len = strlento(buffer, ' '); ret[index] = (char *) xmalloc(len); strncpy(ret[index], buffer, len); buffer += len + 1; index++; } while (end > 0); return ret; } #define BUFLEN 255 void read_obj(long offset) { char buffer[BUFLEN]; int obj_num, size = 0; struct object *obj = (struct object *) xcalloc(sizeof(struct object), 1); fseek(fp, offset, SEEK_SET); fget(buffer, BUFLEN, fp); sscanf(buffer, "%d ", &obj_num); fget(buffer, BUFLEN, fp); while (!strstr(buffer, "endobj")) { size += strlen(buffer) + 1; obj->unparsed = resize(obj->unparsed, size); strcat(obj->unparsed, buffer); fget(buffer, BUFLEN, fp); } object[obj_num] = obj; return; } /* obj->type = UNKNOWN; obj->obj = NULL; if(!strstr(&buffer[0],"<<")) { obj->type = NOTYPE; obj->obj = fill_data(); } while (buffer[0] != '>' && buffer[1] != '>' && obj->type == UNKNOWN) { if (!strncmp(&buffer[0], "/Type", 5)) { if (!strncmp(&buffer[7], "Page", 4)) { obj->type = PAGE; } if (!strncmp(&buffer[7], "Pages", 5)) { obj->type = PAGES; } if (!strncmp(&buffer[7], "Catalog", 7)) { obj->type = CATALOG; } if (!strncmp(&buffer[7], "Encoding", 8)) { obj->type = ENCODING; } if (!strncmp(&buffer[7], "XObject", 7)) { obj->type = XOBJECT; } } if (!strncmp(&buffer[0], "/Font", 5)) { obj->type = FONT; } if (!strncmp(&buffer[0], "stream", 7)) { obj->type = CONTENT; } fget(&buffer[0], BUFLEN, fp); }*/ void add_obj(char *s) { long offset, old_off; sscanf(s, "%ld ", &offset); old_off = ftell(fp); read_obj(offset); fseek(fp, old_off, SEEK_SET); } /* find objects */ void xref(void) { char xref[XREFLINE]; long offset = 0; int i = XREFLINE - 2; xref[XREFLINE - 1] = '\0'; fstat(fp->_fileno, &fpstat); offset = fpstat.st_size - 8; fseek(fp, offset, SEEK_SET); while (1) { xref[i] = fgetc(fp); if (xref[i] == '\r' || xref[i] == '\n') break; i--; offset--; fseek(fp, offset, SEEK_SET); } offset = strtoul(&xref[i + 1], NULL, 10); fseek(fp, offset, SEEK_SET); fget(&xref[0], XREFLINE, fp); if (strstr(&xref[0], "xref") == NULL) { /* error */ return; } fget(&xref[0], XREFLINE, fp); { int entry[2]; sscanf(&xref[0], "%d %d", &entry[0], &entry[1]); object = (struct object **) xmalloc(entry[0] + entry[1]); if (!entry[0]) fseek(fp, 20, SEEK_CUR); fget(&xref[0], XREFLINE, fp); while (strncmp(&xref[0], "trailer", 5)) { add_obj(&xref[0]); fget(&xref[0], XREFLINE, fp); } } return; } int parse_pdf(void) { xref(); return 0; }