ref: 34238e0feb181a0c120561486d4c86b054d112bc
parent: 3c27f041321b91dbf2bfd0ab9e4865e03854cd68
author: Sigrid Haflínudóttir <ftrvxmtrx@gmail.com>
date: Fri Aug 28 14:02:18 EDT 2020
fix xref parsing and add pdfeval to resolve indirect objects
--- /dev/null
+++ b/eval.c
@@ -1,0 +1,23 @@
+#include <u.h>
+#include <libc.h>
+#include "pdf.h"
+
+int
+pdfeval(Pdf *pdf, Object *o)
+{
+ Xref *x;
+ int i;
+
+ if(o->type != Oindir)
+ return 0;
+
+ for(i = 0; i < pdf->nxref; i++){
+ x = &pdf->xref[i];
+ if(x->id == o->indir.id)
+ return 0;
+ }
+
+ werrstr("no object id %d in xref", o->indir.id);
+
+ return -1;
+}
--- a/mkfile
+++ b/mkfile
@@ -6,6 +6,7 @@
OFILES=\
array.$O\
dict.$O\
+ eval.$O\
filter.$O\
main.$O\
misc.$O\
--- a/object.c
+++ b/object.c
@@ -8,7 +8,7 @@
{
Object *o;
char *s, *p0;
- int sz;
+ int sz, gen;
o = nil;
for(; len > 0 && isws(*p); p++, len--);
@@ -60,7 +60,7 @@
default:
if(isdigit(*p)){
- if((o = malloc(sizeof(*o)+sz+1)) != nil){
+ if((o = malloc(sizeof(*o))) != nil){
o->type = Onum;
o->num = strtod(p, e);
sz = len - (*e - p);
@@ -68,16 +68,16 @@
s = p0;
for(; sz > 0 && isws(*s); s++, sz--);
if(sz > 0 && isdigit(*s)){
- strtod(s, &p);
+ gen = strtod(s, &p);
sz -= (p - s);
s = p;
for(; sz > 0 && isws(*s); s++, sz--);
if(sz > 0 && *s == 'R'){ /* indirect object */
- sz--;
s++;
o->type = Oindir;
+ o->indir.id = o->num;
+ o->indir.gen = gen;
p0 = s;
- len = sz;
}
}
*e = p0;
--- a/pdf.c
+++ b/pdf.c
@@ -37,7 +37,7 @@
werrstr("invalid xref line");
goto err;
}
- xref.id = xref0 + nxref;
+ xref.id = xref0 + i;
xref.off = strtoul(e, nil, 10);
/* search in already existing xrefs, update if found */
@@ -101,13 +101,13 @@
freeobject(o);
o = nil;
- /* root is required */
+ /* root is required, info is optional */
if(pdf->root == nil){
werrstr("no root");
goto err;
}
-
- /* info is optional */
+ if(pdfeval(pdf, pdf->root) != 0 || pdfeval(pdf, pdf->info) != 0)
+ goto err;
return 0;
err:
--- a/pdf.h
+++ b/pdf.h
@@ -24,8 +24,8 @@
char *name;
struct {
- int id;
- int gen;
+ u32int id;
+ u16int gen;
}indir;
struct {
@@ -57,12 +57,17 @@
struct Xref {
u32int id;
u32int off;
+ u16int gen;
};
Pdf *pdfopen(int fd);
void pdfclose(Pdf *pdf);
+/*
+ * General function to parse an object of any type.
+ */
Object *pdfobject(char *p, char **e, int len);
+
void freeobject(Object *o);
/*
@@ -91,6 +96,12 @@
* 7.3.7 Dictionary Objects
*/
Object *pdfdict(char *p, char **e, int len);
+
+/*
+ * If the object is indirect, resolve it. Operation is not recursive, ie
+ * values of a dictionary won't be resolved automatically.
+ */
+int pdfeval(Pdf *pdf, Object *o);
int isws(char c);
int isdelim(char c);