summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ghostscript.com>2004-11-18 05:48:01 +0100
committerTor Andersson <tor@ghostscript.com>2004-11-18 05:48:01 +0100
commit2724ed5685e87dd6491df510de384ffe03223991 (patch)
tree679fa99f06fceef44bb6103f2ddb672c942e5e31
parent7f5094e6980bf3193eee2de2053f54ba64088d90 (diff)
downloadmupdf-2724ed5685e87dd6491df510de384ffe03223991.tar.xz
cleaned up filter/buffer refcounting and stream error handling
-rw-r--r--mupdf/cmap.c65
-rw-r--r--mupdf/crypt.c27
-rw-r--r--mupdf/doctor.c13
-rw-r--r--mupdf/lex.c4
-rw-r--r--mupdf/repair.c3
-rw-r--r--mupdf/save.c7
-rw-r--r--mupdf/stream.c279
-rw-r--r--mupdf/xref.c22
8 files changed, 310 insertions, 110 deletions
diff --git a/mupdf/cmap.c b/mupdf/cmap.c
index 33c3a4ab..a5768748 100644
--- a/mupdf/cmap.c
+++ b/mupdf/cmap.c
@@ -280,7 +280,6 @@ pdf_parsecmap(fz_cmap **cmapp, fz_file *file)
error = fz_newcmap(&cmap);
if (error)
return error;
- *cmapp = cmap;
strcpy(key, ".notdef");
@@ -362,14 +361,17 @@ pdf_parsecmap(fz_cmap **cmapp, fz_file *file)
if (error)
goto cleanup;
+ *cmapp = cmap;
return nil;
cleanup:
fz_dropcmap(cmap);
- *cmapp = nil;
return error;
}
+/*
+ * Load CMap stream in PDF file
+ */
fz_error *
pdf_loadembeddedcmap(fz_cmap **cmapp, pdf_xref *xref, fz_obj *stmref)
{
@@ -384,11 +386,6 @@ pdf_loadembeddedcmap(fz_cmap **cmapp, pdf_xref *xref, fz_obj *stmref)
if (error)
return error;
-printf(" embedded cmap: ");
-fz_debugobj(stmobj);
-printf("\n");
-fflush(stdout);
-
error = pdf_openstream(xref, fz_tonum(stmref), fz_togen(stmref));
if (error)
goto cleanup;
@@ -406,34 +403,36 @@ fflush(stdout);
obj = fz_dictgets(stmobj, "UseCMap");
if (fz_isname(obj))
{
- printf(" usecmap predefined: %s\n", fz_toname(obj));
error = pdf_loadsystemcmap(&usecmap, fz_toname(obj));
if (error)
goto cleanup;
fz_setusecmap(cmap, usecmap);
+ fz_dropcmap(usecmap);
}
else if (fz_isindirect(obj))
{
- printf(" usecmap recursive pdf obj\n");
error = pdf_loadembeddedcmap(&usecmap, xref, obj);
if (error)
goto cleanup;
fz_setusecmap(cmap, usecmap);
+ fz_dropcmap(usecmap);
}
- *cmapp = cmap;
-
fz_dropobj(stmobj);
+
+ *cmapp = cmap;
return nil;
cleanup:
if (cmap)
fz_dropcmap(cmap);
fz_dropobj(stmobj);
- *cmapp = nil;
return error;
}
+/*
+ * Load predefined CMap from system
+ */
fz_error *
pdf_loadsystemcmap(fz_cmap **cmapp, char *name)
{
@@ -442,10 +441,9 @@ pdf_loadsystemcmap(fz_cmap **cmapp, char *name)
char *cmapdir;
char *usecmapname;
fz_cmap *usecmap;
+ fz_cmap *cmap;
char path[1024];
- *cmapp = nil;
-
cmapdir = getenv("CMAPDIR");
if (!cmapdir)
return fz_throw("ioerror: CMAPDIR environment not set");
@@ -454,68 +452,71 @@ pdf_loadsystemcmap(fz_cmap **cmapp, char *name)
strlcat(path, "/", sizeof path);
strlcat(path, name, sizeof path);
-printf(" system cmap loading %s\n", path);
-
error = fz_openfile(&file, path, FZ_READ);
if (error)
goto cleanup;
- error = pdf_parsecmap(cmapp, file);
+ error = pdf_parsecmap(&cmap, file);
if (error)
goto cleanup;
fz_closefile(file);
- usecmapname = fz_getusecmapname(*cmapp);
+ usecmapname = fz_getusecmapname(cmap);
if (usecmapname)
{
-printf(" system cmap: usecmap %s\n", usecmapname);
error = pdf_loadsystemcmap(&usecmap, usecmapname);
if (error)
goto cleanup;
- fz_setusecmap(*cmapp, usecmap);
+ fz_setusecmap(cmap, usecmap);
+ fz_dropcmap(usecmap);
}
+ *cmapp = cmap;
return nil;
cleanup:
- if (*cmapp)
- fz_dropcmap(*cmapp);
+ if (cmap)
+ fz_dropcmap(cmap);
if (file)
fz_closefile(file);
- *cmapp = nil;
return error;
}
+/*
+ * Create an Identity-* CMap (for both 1 and 2-byte encodings)
+ */
fz_error *
pdf_makeidentitycmap(fz_cmap **cmapp, int wmode, int bytes)
{
- fz_error *error = nil;
+ fz_error *error;
+ fz_cmap *cmap;
- error = fz_newcmap(cmapp);
+ error = fz_newcmap(&cmap);
if (error)
return error;
- error = fz_addcodespacerange(*cmapp, 0x0000, 0xffff, bytes);
+ error = fz_addcodespacerange(cmap, 0x0000, 0xffff, bytes);
if (error) {
- fz_dropcmap(*cmapp);
+ fz_dropcmap(cmap);
return error;
}
- error = fz_addcidrange(*cmapp, 0x0000, 0xffff, 0);
+ error = fz_addcidrange(cmap, 0x0000, 0xffff, 0);
if (error) {
- fz_dropcmap(*cmapp);
+ fz_dropcmap(cmap);
return error;
}
- error = fz_endcidrange(*cmapp);
+ error = fz_endcidrange(cmap);
if (error) {
- fz_dropcmap(*cmapp);
+ fz_dropcmap(cmap);
return error;
}
- fz_setwmode(*cmapp, wmode);
+ fz_setwmode(cmap, wmode);
+ *cmapp = cmap;
return nil;
}
diff --git a/mupdf/crypt.c b/mupdf/crypt.c
index 93ff8959..03633c9e 100644
--- a/mupdf/crypt.c
+++ b/mupdf/crypt.c
@@ -44,6 +44,10 @@ static void padpassword(unsigned char *buf, char *pw)
memcpy(buf + len, padding, 32 - len);
}
+/*
+ * Create crypt object for decrypting given the
+ * Encoding dictionary and file ID
+ */
fz_error *
pdf_newdecrypt(pdf_crypt **cp, fz_obj *enc, fz_obj *id)
{
@@ -58,8 +62,9 @@ pdf_newdecrypt(pdf_crypt **cp, fz_obj *enc, fz_obj *id)
if (m != 1 && m != 2)
return fz_throw("unsupported encryption: %d", m);
- crypt = *cp = fz_malloc(sizeof(pdf_crypt));
- if (!crypt) return fz_outofmem;
+ crypt = fz_malloc(sizeof(pdf_crypt));
+ if (!crypt)
+ return fz_outofmem;
crypt->encrypt = fz_keepobj(enc);
crypt->id = nil;
@@ -109,10 +114,11 @@ pdf_newdecrypt(pdf_crypt **cp, fz_obj *enc, fz_obj *id)
memset(crypt->key, 0, 16);
+ *cp = crypt;
return nil;
cleanup:
- if (crypt) fz_free(crypt);
+ pdf_dropcrypt(crypt);
return fz_throw("corrupt encryption dictionary");
}
@@ -265,14 +271,17 @@ createuser(pdf_crypt *crypt, char *userpw)
}
}
+/*
+ * Create crypt object for encrypting, given passwords,
+ * permissions, and file ID
+ */
fz_error *
-pdf_newencrypt(pdf_crypt **cp,
- char *userpw, char *ownerpw, int p, int n, fz_obj *id)
+pdf_newencrypt(pdf_crypt **cp, char *userpw, char *ownerpw, int p, int n, fz_obj *id)
{
fz_error *error;
pdf_crypt *crypt;
- crypt = *cp = fz_malloc(sizeof(pdf_crypt));
+ crypt = fz_malloc(sizeof(pdf_crypt));
if (!crypt)
return fz_outofmem;
@@ -328,6 +337,9 @@ pdf_setpassword(pdf_crypt *crypt, char *userpw)
return nil;
}
+/*
+ * Recursively (and destructively!) de/encrypt all strings in obj
+ */
void
pdf_cryptobj(pdf_crypt *crypt, fz_obj *obj, int oid, int gid)
{
@@ -359,6 +371,9 @@ pdf_cryptobj(pdf_crypt *crypt, fz_obj *obj, int oid, int gid)
}
}
+/*
+ * Create filter suitable for de/encrypting a stream
+ */
fz_error *
pdf_cryptstream(fz_filter **fp, pdf_crypt *crypt, int oid, int gid)
{
diff --git a/mupdf/doctor.c b/mupdf/doctor.c
index 8596c7ba..ed50b768 100644
--- a/mupdf/doctor.c
+++ b/mupdf/doctor.c
@@ -1,6 +1,10 @@
#include <fitz.h>
#include <mupdf.h>
+/*
+ * Sweep and mark reachable objects
+ */
+
static fz_error *sweepref(pdf_xref *xref, fz_obj *ref);
static fz_error *
@@ -68,7 +72,8 @@ sweepref(pdf_xref *xref, fz_obj *ref)
}
/*
- * Garbage collection
+ * Garbage collect objects not reachable from
+ * the trailer dictionary
*/
fz_error *
@@ -172,6 +177,11 @@ cleanup:
return error;
}
+/*
+ * Recursively copy objects from src to dst xref.
+ * Start with root object in src xref.
+ * Put the dst copy of root into newp.
+ */
fz_error *
pdf_transplant(pdf_xref *dst, pdf_xref *src, fz_obj **newp, fz_obj *root)
{
@@ -227,6 +237,7 @@ pdf_transplant(pdf_xref *dst, pdf_xref *src, fz_obj **newp, fz_obj *root)
if (error)
goto cleanup;
pdf_updatestream(dst, map[i].doid, map[i].dgen, stm);
+ fz_dropbuffer(stm);
}
error = remaprefs(&new, old, map, n);
diff --git a/mupdf/lex.c b/mupdf/lex.c
index f7d6292b..36e7f50a 100644
--- a/mupdf/lex.c
+++ b/mupdf/lex.c
@@ -49,7 +49,7 @@ static inline int fromhex(int ch)
return 0;
}
-static void
+static inline void
lexwhite(fz_file *f)
{
int c;
@@ -62,7 +62,7 @@ lexwhite(fz_file *f)
}
}
-static void
+static inline void
lexcomment(fz_file *f)
{
int c;
diff --git a/mupdf/repair.c b/mupdf/repair.c
index cf9917ea..a41f10ed 100644
--- a/mupdf/repair.c
+++ b/mupdf/repair.c
@@ -283,8 +283,9 @@ pdf_repairpdf(pdf_xref **xrefp, char *filename)
}
}
- *xrefp = xref;
fz_free(list);
+
+ *xrefp = xref;
return nil;
cleanup:
diff --git a/mupdf/save.c b/mupdf/save.c
index 1fcc31da..2639c993 100644
--- a/mupdf/save.c
+++ b/mupdf/save.c
@@ -20,10 +20,9 @@ writestream(fz_file *out, pdf_xref *xref, pdf_crypt *encrypt, int oid, int gen)
return error;
error = fz_pushfilter(out, ef);
- if (error) {
- fz_dropfilter(ef);
+ fz_dropfilter(ef);
+ if (error)
return error;
- }
}
error = pdf_openrawstream(xref, oid, gen);
@@ -79,7 +78,7 @@ writeobject(fz_file *out, pdf_xref *xref, pdf_crypt *encrypt, int oid, int gen)
if (encrypt)
pdf_cryptobj(encrypt, x->obj, oid, gen);
- if (x->stmbuf || x->stmofs)
+ if (pdf_isstream(xref, oid, gen))
{
error = writestream(out, xref, encrypt, oid, gen);
if (error)
diff --git a/mupdf/stream.c b/mupdf/stream.c
index 13b79642..3ccb61b3 100644
--- a/mupdf/stream.c
+++ b/mupdf/stream.c
@@ -1,13 +1,35 @@
#include <fitz.h>
#include <mupdf.h>
-/* TODO: error cleanup */
+/*
+ * Check if an object is a stream or not.
+ */
+int
+pdf_isstream(pdf_xref *xref, int oid, int gen)
+{
+ fz_error *error;
+
+ if (oid < 0 || oid >= xref->len)
+ return 0;
+
+ error = pdf_cacheobject(xref, oid, gen);
+ if (error) {
+ fz_warn("%s", error->msg);
+ fz_droperror(error);
+ return 0;
+ }
+
+ return xref->table[oid].stmbuf || xref->table[oid].stmofs;
+}
+/*
+ * Create a filter given a name and param dictionary.
+ */
static fz_error *
buildonefilter(fz_filter **fp, fz_obj *f, fz_obj *p)
{
- fz_filter *predf;
- fz_filter *realf;
+ fz_filter *decompress;
+ fz_filter *predict;
fz_error *error;
char *s;
@@ -28,19 +50,28 @@ buildonefilter(fz_filter **fp, fz_obj *f, fz_obj *p)
if (!strcmp(s, "RunLengthDecode") || !strcmp(s, "RL"))
return fz_newrld(fp, p);
- if (!strcmp(s, "JPXDecode"))
- return fz_newjpxd(fp, p);
-
if (!strcmp(s, "FlateDecode") || !strcmp(s, "Fl"))
{
if (fz_isdict(p))
{
fz_obj *obj = fz_dictgets(p, "Predictor");
- if (obj) {
- error = fz_newflated(&realf, p);
- error = fz_newpredictd(&predf, p);
- error = fz_newpipeline(fp, realf, predf);
- return nil;
+ if (obj)
+ {
+ error = fz_newflated(&decompress, p);
+ if (error)
+ return error;
+
+ error = fz_newpredictd(&predict, p);
+ if (error)
+ {
+ fz_dropfilter(decompress);
+ return error;
+ }
+
+ error = fz_newpipeline(fp, decompress, predict);
+ fz_dropfilter(decompress);
+ fz_dropfilter(predict);
+ return error;
}
}
return fz_newflated(fp, p);
@@ -51,28 +82,54 @@ buildonefilter(fz_filter **fp, fz_obj *f, fz_obj *p)
if (fz_isdict(p))
{
fz_obj *obj = fz_dictgets(p, "Predictor");
- if (obj) {
- error = fz_newlzwd(&realf, p);
- error = fz_newpredictd(&predf, p);
- error = fz_newpipeline(fp, realf, predf);
- return nil;
+ if (obj)
+ {
+ error = fz_newlzwd(&decompress, p);
+ if (error)
+ return error;
+
+ error = fz_newpredictd(&predict, p);
+ if (error)
+ {
+ fz_dropfilter(decompress);
+ return error;
+ }
+
+ error = fz_newpipeline(fp, decompress, predict);
+ fz_dropfilter(decompress);
+ fz_dropfilter(predict);
+ return error;
}
}
return fz_newlzwd(fp, p);
}
- if (!strcmp(s, "JBIG2Decode")) {
+#ifdef HAVE_JBIG2
+ if (!strcmp(s, "JBIG2Decode"))
+ {
/* TODO: extract and feed JBIG2Global */
return fz_newjbig2d(fp, p);
}
+#endif
+
+#ifdef HAVE_JASPER
+ if (!strcmp(s, "JPXDecode"))
+ return fz_newjpxd(fp, p);
+#endif
return fz_throw("syntaxerror: unknown filter: %s", s);
}
+/*
+ * Build a chain of filters given filter names and param dicts.
+ * If head is given, start filter chain with it.
+ * Assume ownership of head.
+ */
static fz_error *
-buildfilters(fz_filter **filterp, fz_filter *head, fz_obj *fs, fz_obj *ps)
+buildfilterchain(fz_filter **filterp, fz_filter *head, fz_obj *fs, fz_obj *ps)
{
fz_error *error;
+ fz_filter *newhead;
fz_filter *tail;
fz_obj *f;
fz_obj *p;
@@ -87,8 +144,21 @@ buildfilters(fz_filter **filterp, fz_filter *head, fz_obj *fs, fz_obj *ps)
p = nil;
error = buildonefilter(&tail, f, p);
+ if (error)
+ return error;
+
if (head)
- error = fz_newpipeline(&head, head, tail);
+ {
+ error = fz_newpipeline(&newhead, head, tail);
+ fz_dropfilter(head);
+ fz_dropfilter(tail);
+ if (error)
+ {
+ fz_dropfilter(newhead);
+ return error;
+ }
+ head = newhead;
+ }
else
head = tail;
}
@@ -97,30 +167,62 @@ buildfilters(fz_filter **filterp, fz_filter *head, fz_obj *fs, fz_obj *ps)
return nil;
}
+/*
+ * Build a filter for reading raw stream data.
+ * This is a null filter to constrain reading to the
+ * stream length, followed by a decryption filter.
+ */
static fz_error *
makerawfilter(fz_filter **filterp, pdf_xref *xref, fz_obj *stmobj, int oid, int gen)
{
fz_error *error;
- fz_filter *pipe, *cf;
+ fz_filter *base;
fz_obj *stmlen;
+ int len;
stmlen = fz_dictgets(stmobj, "Length");
error = pdf_resolve(&stmlen, xref);
+ if (error)
+ return error;
+ len = fz_toint(stmlen);
+ fz_dropobj(stmlen);
- error = fz_newnullfilter(&pipe, fz_toint(stmlen));
+ error = fz_newnullfilter(&base, len);
+ if (error)
+ return error;
if (xref->crypt)
{
- error = pdf_cryptstream(&cf, xref->crypt, oid, gen);
- error = fz_newpipeline(&pipe, pipe, cf);
- }
+ fz_filter *crypt;
+ fz_filter *pipe;
- fz_dropobj(stmlen);
+ error = pdf_cryptstream(&crypt, xref->crypt, oid, gen);
+ if (error)
+ {
+ fz_dropfilter(base);
+ return error;
+ }
+
+ error = fz_newpipeline(&pipe, base, crypt);
+ fz_dropfilter(base);
+ fz_dropfilter(crypt);
+ if (error)
+ return error;
+
+ *filterp = pipe;
+ }
+ else
+ {
+ *filterp = base;
+ }
- *filterp = pipe;
return nil;
}
+/*
+ * Construct a filter to decode a stream, without
+ * constraining to stream length, and without decryption.
+ */
fz_error *
pdf_decodefilter(fz_filter **filterp, fz_obj *stmobj)
{
@@ -135,7 +237,7 @@ pdf_decodefilter(fz_filter **filterp, fz_obj *stmobj)
if (fz_isname(filters))
return buildonefilter(filterp, filters, params);
else
- return buildfilters(filterp, nil, filters, params);
+ return buildfilterchain(filterp, nil, filters, params);
}
else
return fz_newnullfilter(filterp, -1);
@@ -143,15 +245,21 @@ pdf_decodefilter(fz_filter **filterp, fz_obj *stmobj)
return nil;
}
+/*
+ * Construct a filter to decode a stream, constraining
+ * to stream length and decrypting.
+ */
static fz_error *
makedecodefilter(fz_filter **filterp, pdf_xref *xref, fz_obj *stmobj, int oid, int gen)
{
fz_error *error;
- fz_filter *pipe, *tmp;
+ fz_filter *base, *pipe, *tmp;
fz_obj *filters;
fz_obj *params;
- error = makerawfilter(&pipe, xref, stmobj, oid, gen);
+ error = makerawfilter(&base, xref, stmobj, oid, gen);
+ if (error)
+ return error;
filters = fz_dictgetsa(stmobj, "Filter", "F");
params = fz_dictgetsa(stmobj, "DecodeParms", "DP");
@@ -159,45 +267,58 @@ makedecodefilter(fz_filter **filterp, pdf_xref *xref, fz_obj *stmobj, int oid, i
if (filters)
{
error = pdf_resolve(&filters, xref);
+ if (error)
+ goto cleanup0;
+
if (params)
+ {
error = pdf_resolve(&params, xref);
+ if (error)
+ goto cleanup1;
+ }
if (fz_isname(filters))
{
error = buildonefilter(&tmp, filters, params);
- error = fz_newpipeline(&pipe, pipe, tmp);
+ if (error)
+ goto cleanup2;
+
+ error = fz_newpipeline(&pipe, base, tmp);
+ fz_dropfilter(tmp);
+ if (error)
+ goto cleanup2;
}
else
- error = buildfilters(&pipe, pipe, filters, params);
+ {
+ error = buildfilterchain(&pipe, base, filters, params);
+ if (error)
+ goto cleanup2;
+ }
if (params)
fz_dropobj(params);
+
fz_dropobj(filters);
}
*filterp = pipe;
-
return nil;
-}
-
-int
-pdf_isstream(pdf_xref *xref, int oid, int gen)
-{
- fz_error *error;
- if (oid < 0 || oid >= xref->len)
- return 0;
-
- error = pdf_cacheobject(xref, oid, gen);
- if (error) {
- fz_warn("%s", error);
- fz_droperror(error);
- return 0;
- }
-
- return xref->table[oid].stmbuf || xref->table[oid].stmofs;
+cleanup2:
+ if (params)
+ fz_dropobj(params);
+cleanup1:
+ fz_dropobj(filters);
+cleanup0:
+ fz_dropfilter(base);
+ return error;
}
+/*
+ * Open a stream for reading the raw (compressed but decrypted) data.
+ * Put the opened file in xref->stream. Using xref->file while this
+ * is open is a bad idea.
+ */
fz_error *
pdf_openrawstream(pdf_xref *xref, int oid, int gen)
{
@@ -212,6 +333,8 @@ pdf_openrawstream(pdf_xref *xref, int oid, int gen)
x = xref->table + oid;
error = pdf_cacheobject(xref, oid, gen);
+ if (error)
+ return error;
if (x->stmbuf)
{
@@ -221,8 +344,23 @@ pdf_openrawstream(pdf_xref *xref, int oid, int gen)
if (x->stmofs)
{
error = makerawfilter(&filter, xref, x->obj, oid, gen);
+ if (error)
+ return error;
+
n = fz_seek(xref->file, x->stmofs, 0);
+ if (n == -1)
+ {
+ fz_dropfilter(filter);
+ return fz_ferror(xref->file);
+ }
+
error = fz_pushfilter(xref->file, filter);
+ if (error)
+ {
+ fz_dropfilter(filter);
+ return error;
+ }
+
xref->stream = xref->file;
return nil;
}
@@ -230,6 +368,11 @@ pdf_openrawstream(pdf_xref *xref, int oid, int gen)
return fz_throw("syntaxerror: object is not a stream");
}
+/*
+ * Open a stream for reading uncompressed data.
+ * Put the opened file in xref->stream.
+ * Using xref->file while a stream is open is a Bad idea.
+ */
fz_error *
pdf_openstream(pdf_xref *xref, int oid, int gen)
{
@@ -244,20 +387,45 @@ pdf_openstream(pdf_xref *xref, int oid, int gen)
x = xref->table + oid;
error = pdf_cacheobject(xref, oid, gen);
+ if (error)
+ return error;
if (x->stmbuf)
{
error = makedecodefilter(&filter, xref, x->obj, oid, gen);
+ if (error)
+ return error;
+
error = fz_openbuffer(&xref->stream, x->stmbuf, FZ_READ);
+ if (error)
+ {
+ fz_dropfilter(filter);
+ return error;
+ }
+
error = fz_pushfilter(xref->stream, filter);
- return nil;
+ fz_dropfilter(filter);
+ return error;
}
if (x->stmofs)
{
error = makedecodefilter(&filter, xref, x->obj, oid, gen);
+ if (error)
+ return error;
+
n = fz_seek(xref->file, x->stmofs, 0);
+ if (n == -1)
+ {
+ fz_dropfilter(filter);
+ return fz_ferror(xref->file);
+ }
+
error = fz_pushfilter(xref->file, filter);
+ fz_dropfilter(filter);
+ if (error)
+ return error;
+
xref->stream = xref->file;
return nil;
}
@@ -265,6 +433,10 @@ pdf_openstream(pdf_xref *xref, int oid, int gen)
return fz_throw("syntaxerror: object is not a stream");
}
+/*
+ * Close the xref->stream file opened by either
+ * pdf_openrawstream or pdf_openstream.
+ */
void
pdf_closestream(pdf_xref *xref)
{
@@ -275,7 +447,9 @@ pdf_closestream(pdf_xref *xref)
xref->stream = nil;
}
-
+/*
+ * Load raw (compressed but decrypted) contents of a stream into buf.
+ */
fz_error *
pdf_loadrawstream(fz_buffer **bufp, pdf_xref *xref, int oid, int gen)
{
@@ -292,6 +466,9 @@ pdf_loadrawstream(fz_buffer **bufp, pdf_xref *xref, int oid, int gen)
return error;
}
+/*
+ * Load uncompressed contents of a stream into buf.
+ */
fz_error *
pdf_loadstream(fz_buffer **bufp, pdf_xref *xref, int oid, int gen)
{
diff --git a/mupdf/xref.c b/mupdf/xref.c
index 421eeb70..8a22b238 100644
--- a/mupdf/xref.c
+++ b/mupdf/xref.c
@@ -55,26 +55,22 @@ pdf_decryptpdf(pdf_xref *xref)
{
error = pdf_resolve(&encrypt, xref);
if (error)
- goto cleanup;
+ return error;
error = pdf_resolve(&id, xref);
if (error)
- goto cleanup;
+ {
+ fz_dropobj(encrypt);
+ return error;
+ }
error = pdf_newdecrypt(&xref->crypt, encrypt, id);
- if (error)
- goto cleanup;
-
fz_dropobj(encrypt);
fz_dropobj(id);
+ return error;
}
return nil;
-
-cleanup:
- if (encrypt) fz_dropobj(encrypt);
- if (id) fz_dropobj(id);
- return error;
}
void
@@ -110,12 +106,13 @@ pdf_debugpdf(pdf_xref *xref)
printf("xref\n0 %d\n", xref->len);
for (i = 0; i < xref->len; i++)
{
- printf("%010d %05d %c | %d %d\n",
+ printf("%010d %05d %c | %d %c%c\n",
xref->table[i].ofs,
xref->table[i].gen,
xref->table[i].type,
xref->table[i].obj ? xref->table[i].obj->refs : 0,
- xref->table[i].stmofs);
+ xref->table[i].stmofs ? 'f' : '-',
+ xref->table[i].stmbuf ? 'b' : '-');
}
}
@@ -253,7 +250,6 @@ pdf_updateobject(pdf_xref *xref, int oid, int gen, fz_obj *obj)
if (x->obj)
fz_dropobj(x->obj);
-
x->obj = fz_keepobj(obj);
if (x->type == 'f' || x->type == 'd')