diff options
-rw-r--r-- | include/mupdf/pdf/document.h | 4 | ||||
-rw-r--r-- | include/mupdf/pdf/object.h | 1 | ||||
-rw-r--r-- | source/pdf/pdf-object.c | 31 | ||||
-rw-r--r-- | source/pdf/pdf-repair.c | 28 | ||||
-rw-r--r-- | source/pdf/pdf-xref.c | 6 |
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); | |||
110 | pdf_obj *pdf_dict_getsa(fz_context *ctx, pdf_obj *dict, const char *key, const char *abbrev); | 110 | pdf_obj *pdf_dict_getsa(fz_context *ctx, pdf_obj *dict, const char *key, const char *abbrev); |
111 | void pdf_dict_put(fz_context *ctx, pdf_obj *dict, pdf_obj *key, pdf_obj *val); | 111 | void pdf_dict_put(fz_context *ctx, pdf_obj *dict, pdf_obj *key, pdf_obj *val); |
112 | void pdf_dict_put_drop(fz_context *ctx, pdf_obj *dict, pdf_obj *key, pdf_obj *val); | 112 | void pdf_dict_put_drop(fz_context *ctx, pdf_obj *dict, pdf_obj *key, pdf_obj *val); |
113 | void pdf_dict_get_put_drop(fz_context *ctx, pdf_obj *dict, pdf_obj *key, pdf_obj *val, pdf_obj **old_val); | ||
113 | void pdf_dict_puts(fz_context *ctx, pdf_obj *dict, const char *key, pdf_obj *val); | 114 | void pdf_dict_puts(fz_context *ctx, pdf_obj *dict, const char *key, pdf_obj *val); |
114 | void pdf_dict_puts_drop(fz_context *ctx, pdf_obj *dict, const char *key, pdf_obj *val); | 115 | void pdf_dict_puts_drop(fz_context *ctx, pdf_obj *dict, const char *key, pdf_obj *val); |
115 | void pdf_dict_putp(fz_context *ctx, pdf_obj *dict, const char *path, pdf_obj *val); | 116 | void 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 | ||
1268 | void | 1268 | static void |
1269 | pdf_dict_put(fz_context *ctx, pdf_obj *obj, pdf_obj *key, pdf_obj *val) | 1269 | pdf_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 | ||
1318 | void | 1324 | void |
1325 | pdf_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 | |||
1330 | void | ||
1319 | pdf_dict_put_drop(fz_context *ctx, pdf_obj *obj, pdf_obj *key, pdf_obj *val) | 1331 | pdf_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 | |||
1341 | void | ||
1342 | pdf_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 | ||
263 | static void | ||
264 | orphan_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 | |||
263 | void | 284 | void |
264 | pdf_repair_xref(fz_context *ctx, pdf_document *doc) | 285 | pdf_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) |