shithub: pdffs

Download patch

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);