summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mupdf/pdf/document.h4
-rw-r--r--include/mupdf/pdf/object.h1
-rw-r--r--source/pdf/pdf-object.c31
-rw-r--r--source/pdf/pdf-repair.c28
-rw-r--r--source/pdf/pdf-xref.c6
5 files changed, 63 insertions, 7 deletions
diff --git a/include/mupdf/pdf/document.h b/include/mupdf/pdf/document.h
index aabf05f98..0078c4a98 100644
--- a/include/mupdf/pdf/document.h
+++ b/include/mupdf/pdf/document.h
@@ -269,6 +269,10 @@ struct pdf_document_s
269 fz_hash_table *images; 269 fz_hash_table *images;
270 fz_hash_table *fonts; 270 fz_hash_table *fonts;
271 } resources; 271 } resources;
272
273 int orphans_max;
274 int orphans_count;
275 pdf_obj **orphans;
272}; 276};
273 277
274/* 278/*
diff --git a/include/mupdf/pdf/object.h b/include/mupdf/pdf/object.h
index 5bc3dcaf2..bf5745519 100644
--- a/include/mupdf/pdf/object.h
+++ b/include/mupdf/pdf/object.h
@@ -110,6 +110,7 @@ pdf_obj *pdf_dict_gets(fz_context *ctx, pdf_obj *dict, const char *key);
110pdf_obj *pdf_dict_getsa(fz_context *ctx, pdf_obj *dict, const char *key, const char *abbrev); 110pdf_obj *pdf_dict_getsa(fz_context *ctx, pdf_obj *dict, const char *key, const char *abbrev);
111void pdf_dict_put(fz_context *ctx, pdf_obj *dict, pdf_obj *key, pdf_obj *val); 111void pdf_dict_put(fz_context *ctx, pdf_obj *dict, pdf_obj *key, pdf_obj *val);
112void pdf_dict_put_drop(fz_context *ctx, pdf_obj *dict, pdf_obj *key, pdf_obj *val); 112void pdf_dict_put_drop(fz_context *ctx, pdf_obj *dict, pdf_obj *key, pdf_obj *val);
113void pdf_dict_get_put_drop(fz_context *ctx, pdf_obj *dict, pdf_obj *key, pdf_obj *val, pdf_obj **old_val);
113void pdf_dict_puts(fz_context *ctx, pdf_obj *dict, const char *key, pdf_obj *val); 114void pdf_dict_puts(fz_context *ctx, pdf_obj *dict, const char *key, pdf_obj *val);
114void pdf_dict_puts_drop(fz_context *ctx, pdf_obj *dict, const char *key, pdf_obj *val); 115void pdf_dict_puts_drop(fz_context *ctx, pdf_obj *dict, const char *key, pdf_obj *val);
115void pdf_dict_putp(fz_context *ctx, pdf_obj *dict, const char *path, pdf_obj *val); 116void pdf_dict_putp(fz_context *ctx, pdf_obj *dict, const char *path, pdf_obj *val);
diff --git a/source/pdf/pdf-object.c b/source/pdf/pdf-object.c
index b4e33f3c2..1c19ba4f3 100644
--- a/source/pdf/pdf-object.c
+++ b/source/pdf/pdf-object.c
@@ -1265,11 +1265,14 @@ pdf_dict_geta(fz_context *ctx, pdf_obj *obj, pdf_obj *key, pdf_obj *abbrev)
1265 return pdf_dict_get(ctx, obj, abbrev); 1265 return pdf_dict_get(ctx, obj, abbrev);
1266} 1266}
1267 1267
1268void 1268static void
1269pdf_dict_put(fz_context *ctx, pdf_obj *obj, pdf_obj *key, pdf_obj *val) 1269pdf_dict_get_put(fz_context *ctx, pdf_obj *obj, pdf_obj *key, pdf_obj *val, pdf_obj **old_val)
1270{ 1270{
1271 int i; 1271 int i;
1272 1272
1273 if (old_val)
1274 *old_val = NULL;
1275
1273 RESOLVE(obj); 1276 RESOLVE(obj);
1274 if (!OBJ_IS_DICT(obj)) 1277 if (!OBJ_IS_DICT(obj))
1275 fz_throw(ctx, FZ_ERROR_GENERIC, "not a dict (%s)", pdf_objkindstr(obj)); 1278 fz_throw(ctx, FZ_ERROR_GENERIC, "not a dict (%s)", pdf_objkindstr(obj));
@@ -1295,7 +1298,10 @@ pdf_dict_put(fz_context *ctx, pdf_obj *obj, pdf_obj *key, pdf_obj *val)
1295 { 1298 {
1296 pdf_obj *d = DICT(obj)->items[i].v; 1299 pdf_obj *d = DICT(obj)->items[i].v;
1297 DICT(obj)->items[i].v = pdf_keep_obj(ctx, val); 1300 DICT(obj)->items[i].v = pdf_keep_obj(ctx, val);
1298 pdf_drop_obj(ctx, d); 1301 if (old_val)
1302 *old_val = d;
1303 else
1304 pdf_drop_obj(ctx, d);
1299 } 1305 }
1300 } 1306 }
1301 else 1307 else
@@ -1316,10 +1322,27 @@ pdf_dict_put(fz_context *ctx, pdf_obj *obj, pdf_obj *key, pdf_obj *val)
1316} 1322}
1317 1323
1318void 1324void
1325pdf_dict_put(fz_context *ctx, pdf_obj *obj, pdf_obj *key, pdf_obj *val)
1326{
1327 pdf_dict_get_put(ctx, obj, key, val, NULL);
1328}
1329
1330void
1319pdf_dict_put_drop(fz_context *ctx, pdf_obj *obj, pdf_obj *key, pdf_obj *val) 1331pdf_dict_put_drop(fz_context *ctx, pdf_obj *obj, pdf_obj *key, pdf_obj *val)
1320{ 1332{
1321 fz_try(ctx) 1333 fz_try(ctx)
1322 pdf_dict_put(ctx, obj, key, val); 1334 pdf_dict_get_put(ctx, obj, key, val, NULL);
1335 fz_always(ctx)
1336 pdf_drop_obj(ctx, val);
1337 fz_catch(ctx)
1338 fz_rethrow(ctx);
1339}
1340
1341void
1342pdf_dict_get_put_drop(fz_context *ctx, pdf_obj *obj, pdf_obj *key, pdf_obj *val, pdf_obj **old_val)
1343{
1344 fz_try(ctx)
1345 pdf_dict_get_put(ctx, obj, key, val, old_val);
1323 fz_always(ctx) 1346 fz_always(ctx)
1324 pdf_drop_obj(ctx, val); 1347 pdf_drop_obj(ctx, val);
1325 fz_catch(ctx) 1348 fz_catch(ctx)
diff --git a/source/pdf/pdf-repair.c b/source/pdf/pdf-repair.c
index 690bf15ae..167f6097e 100644
--- a/source/pdf/pdf-repair.c
+++ b/source/pdf/pdf-repair.c
@@ -260,6 +260,27 @@ pdf_repair_obj_stm(fz_context *ctx, pdf_document *doc, int stm_num)
260 } 260 }
261} 261}
262 262
263static void
264orphan_object(fz_context *ctx, pdf_document *doc, pdf_obj *obj)
265{
266 if (doc->orphans_count == doc->orphans_max)
267 {
268 int new_max = (doc->orphans_max ? doc->orphans_max*2 : 32);
269
270 fz_try(ctx)
271 {
272 doc->orphans = fz_resize_array(ctx, doc->orphans, new_max, sizeof(*doc->orphans));
273 doc->orphans_max = new_max;
274 }
275 fz_catch(ctx)
276 {
277 pdf_drop_obj(ctx, obj);
278 fz_rethrow(ctx);
279 }
280 }
281 doc->orphans[doc->orphans_count++] = obj;
282}
283
263void 284void
264pdf_repair_xref(fz_context *ctx, pdf_document *doc) 285pdf_repair_xref(fz_context *ctx, pdf_document *doc)
265{ 286{
@@ -528,12 +549,13 @@ pdf_repair_xref(fz_context *ctx, pdf_document *doc)
528 /* correct stream length for unencrypted documents */ 549 /* correct stream length for unencrypted documents */
529 if (!encrypt && list[i].stm_len >= 0) 550 if (!encrypt && list[i].stm_len >= 0)
530 { 551 {
552 pdf_obj *old_obj = NULL;
531 dict = pdf_load_object(ctx, doc, list[i].num); 553 dict = pdf_load_object(ctx, doc, list[i].num);
532 554
533 length = pdf_new_int(ctx, doc, list[i].stm_len); 555 length = pdf_new_int(ctx, doc, list[i].stm_len);
534 pdf_dict_put(ctx, dict, PDF_NAME_Length, length); 556 pdf_dict_get_put_drop(ctx, dict, PDF_NAME_Length, length, &old_obj);
535 pdf_drop_obj(ctx, length); 557 if (old_obj)
536 558 orphan_object(ctx, doc, old_obj);
537 pdf_drop_obj(ctx, dict); 559 pdf_drop_obj(ctx, dict);
538 } 560 }
539 } 561 }
diff --git a/source/pdf/pdf-xref.c b/source/pdf/pdf-xref.c
index 7d21775a0..0cf20d4ce 100644
--- a/source/pdf/pdf-xref.c
+++ b/source/pdf/pdf-xref.c
@@ -1620,6 +1620,12 @@ pdf_drop_document_imp(fz_context *ctx, pdf_document *doc)
1620 1620
1621 pdf_drop_resource_tables(ctx, doc); 1621 pdf_drop_resource_tables(ctx, doc);
1622 1622
1623 for (i = 0; i < doc->orphans_count; i++)
1624 {
1625 pdf_drop_obj(ctx, doc->orphans[i]);
1626 }
1627 fz_free(ctx, doc->orphans);
1628
1623 fz_free(ctx, doc); 1629 fz_free(ctx, doc);
1624 } 1630 }
1625 fz_always(ctx) 1631 fz_always(ctx)