summaryrefslogtreecommitdiff
path: root/source/pdf/pdf-xref.c
AgeCommit message (Collapse)Author
2016-01-20Various formatting cleanups.Tor Andersson
2015-12-28Drop 'jsimp' abstraction and use mujs directly.Tor Andersson
2015-12-18Remove fz_save_document and use pdf_save_document directly instead.Tor Andersson
In preparation of adding pdf_write_document that writes a document to a fz_output stream.
2015-12-15Rename fz_write_x to fz_save_pixmap_as_x or fz_save_bitmap_as_x.Tor Andersson
Separate naming of functions that save complete files to disk from functions that write data to streams.
2015-10-21Fix signatures for files created with pdf_create_document.Simon Reinhardt
See Bug 696284. Do not set disallow_new_increments in pdf_create_document, as this breaks following calls to pdf_sign_signature. See also the comments in bug 696251.
2015-10-14Fix pdf_create_document.Simon Reinhardt
In pdf_create_document set disallow_new_increments to 1. Without this, the calls to pdf_new_ref in pdf_create_document create an incremental xref section. The following call to pdf_set_populating_xref_trailer then does not set the trailer of the final xref section.
2015-10-02Bug 696131: Detect some overflow conditionsRobin Watts
When lexing a number, do NOT check for overflow. This causes loss of data in some files. The current implementation matches Acrobat. When lexing a startxref offset, check for overflow. If found, throw an error.
2015-10-02Bug 696129: Be more forgiving of broken files.Robin Watts
The PDF spec says that old format xrefs should start with: xref\n<start> <len> The example file in question has: xref <start> <len> which confuses our parsing code. Update the parse code to avoid using fz_read_line, and to instead work on a char level. Also, downgrade the error given when the first object is not free to be a warning. Now we do 'just in time' repair, we are probably better able to cope.
2015-10-01Bug 696146: Improve pdf_repair to find /Root in new style XRefs.Robin Watts
The current code never looks for /Root objects in dictionaries as it parses them. This means that 'New style' files end up without any Roots after repair. The new code therefore updates pdf_repair_obj to look for Root objects in the same way it looks for encrypt and id objects. These go into the list of found roots. The Root object almost certainly has indirections within it, so it is vital that the 'doc' pointer gets set. This means we have to make a slight adjustment to pdf_repair_obj so that the dict is parsed with a doc pointer. In turn this means we need to manually ensure that none of the other information read from the dict during the repair operation will cause indirections to be resolved. This is achieved by checking for !pdf_is_indirect at various points.
2015-08-27Support several levels of incremental xrefPaul Gardiner
This fixes bug #696123 by allowing multiple signatures each to be written to the document in a separate incemental update. Add count num_incremental_sections to keep track of the number of incremental sections. Add xref_base, which can be set between 0 and num_incremental_sections inclusive to access different versions of the document. Add disallow_new_increments flag that stops new incremental sections being provoked by the creation of an xref stream. Move the unsaved_sigs list from the document structure to the xref structure. With this commit in place, the lists will never grow beyond length one, but we've maintained the list structure in case other cases need supporting in the future. Add an end offset field to the xref structure, so that during completion of signatures the document length of the various incremental versions of the document are available. Factor out functions for storing unsaved signatures and for checking if an object is an unsaved signature. Do deep copy of objects that require the holding of several versions.
2015-07-28Reset xref object entry when repairing pdf objects.Sebastian Rasmussen
When attempting to load pdf objects and a valid pdf object is found but it has the wrong number, mark the xref object entry as being free before attempting to repair the xref. This ensures that if the wanted object cannot be found in the document then the missing object will be considered to be null. Previously it was still assumed to be around, but the object pointer was NULL triggering an assert in pdf_load_object().
2015-06-05Fix leak of doc->xref_index in mutool clean.Robin Watts
When replacing the xref_index, lose the old one.
2015-06-02Fix FZ_LARGEFILE operation for large files with old style xrefs.Robin Watts
I'd missed converting some int's to fz_off_t's.
2015-05-15Support pdf files larger than 2Gig.Robin Watts
If FZ_LARGEFILE is defined when building, MuPDF uses 64bit offsets for files; this allows us to open streams larger than 2Gig. The downsides to this are that: * The xref entries are larger. * All PDF ints are held as 64bit things rather than 32bit things (to cope with /Prev entries, hint stream offsets etc). * All file positions are stored as 64bits rather than 32. The implementation works by detecting FZ_LARGEFILE. Some #ifdeffery in fitz/system.h sets fz_off_t to either int or int64_t as appropriate, and sets defines for fz_fopen, fz_fseek, fz_ftell etc as required. These call the fseeko64 etc functions on linux (and so define _LARGEFILE64_SOURCE) and the explicit 64bit functions on windows.
2015-04-14Split fz_meta into separate querying functions.Tor Andersson
Add fz_has_permission function to fz_document. Add fz_lookup_metadata function to fz_document. Remove fz_meta function from fz_document.
2015-04-09Remove the _no_run functions.Tor Andersson
The new pdfclean sanitize functionality mean that mutool now needs the data files, so maintaining the split that was designed to keep data files out of mutool is no longer viable.
2015-04-01Bug 693719: Attempt #2. Broken trailer repair.Robin Watts
Calling pdf_is_dict causes the file to seek. This is a bad thing in a process that is running through the file. It's doubly bad, as the thing it seeks to read may not be there as it might not have been repaired yet. So, instead of just keeping the 'most recent root that is a dictionary', we change to keeping a list of the roots we have found while parsing the doc. At the end we then check for the most recent one that is a dictionary and use that.
2015-03-30Bug 695892: Fix incremental updates of documents with xref streams.Robin Watts
Simon Reinhardt points out that writexrefstream calls pdf_update_stream on an object, rather than on a reference. The code as written fails to do the update, and the updated file is broken. I fix this here by updating pdf_update_stream to be able to work with both objects and references. This is in contrast to his patch which would create a reference for the sole purpose of performing the update.
2015-03-24Rework handling of PDF names for speed and memory.Robin Watts
Currently, every PDF name is allocated in a pdf_obj structure, and comparisons are done using strcmp. Given that we can predict most of the PDF names we'll use in a given file, this seems wasteful. The pdf_obj type is opaque outside the pdf-object.c file, so we can abuse it slightly without anyone outside knowing. We collect a sorted list of names used in PDF (resources/pdf/names.txt), and we add a utility (namedump) that preprocesses this into 2 header files. The first (include/mupdf/pdf/pdf-names-table.h, included as part of include/mupdf/pdf/object.h), defines a set of "PDF_NAME_xxxx" entries. These are pdf_obj *'s that callers can use to mean "A PDF object that means literal name 'xxxx'" The second (source/pdf/pdf-name-impl.h) is a C array of names. We therefore update the code so that rather than passing "xxxx" to functions (such as pdf_dict_gets(...)) we now pass PDF_NAME_xxxx (to pdf_dict_get(...)). This is a fairly natural (if widespread) change. The pdf_dict_getp (and sibling) functions that take a path (e.g. "foo/bar/baz") are therefore supplemented with equivalents that take a list (pdf_dict_getl(... , PDF_NAME_foo, PDF_NAME_bar, PDF_NAME_baz, NULL)). The actual implementation of this relies on the fact that small pointer values are never valid values. For a given pdf_obj *p, if NULL < (intptr_t)p < PDF_NAME__LIMIT then p is a literal entry in the name table. This enables us to do fast pointer compares and to skip expensive strcmps. Also, bring "null", "true" and "false" into the same style as PDF names. Rather than using full pdf_obj structures for null/true/false, use special pointer values just above the PDF_NAME_ table. This saves memory and makes comparisons easier.
2015-03-20Automatically update /Length and /Filter in pdf_update_stream.Tor Andersson
2015-02-17Add ctx parameter and remove embedded contexts for API regularity.Tor Andersson
Purge several embedded contexts: Remove embedded context in fz_output. Remove embedded context in fz_stream. Remove embedded context in fz_device. Remove fz_rebind_stream (since it is no longer necessary). Remove embedded context in svg_device. Remove embedded context in XML parser. Add ctx argument to fz_document functions. Remove embedded context in fz_document. Remove embedded context in pdf_document. Remove embedded context in pdf_obj. Make fz_page independent of fz_document in the interface. We shouldn't need to pass the document to all functions handling a page. If a page is tied to the source document, it's redundant; otherwise it's just pointless. Fix reference counting oddity in fz_new_image_from_pixmap.
2015-02-17Rename fz_close_* and fz_free_* to fz_drop_*.Tor Andersson
Rename fz_close to fz_drop_stream. Rename fz_close_archive to fz_drop_archive. Rename fz_close_output to fz_drop_output. Rename fz_free_* to fz_drop_*. Rename pdf_free_* to pdf_drop_*. Rename xps_free_* to xps_drop_*.
2015-02-17Reference count fz_document.Tor Andersson
2015-01-20remove some lonely tabs and move some braces onto their own linesSimon Bünzli
2015-01-20fix crash caused by commit 90c560641d9b459a658029eefc4cbb02fdbca0b5Simon Bünzli
When loading e.g. the file from bug 694567, MuPDF uses an unitialized variable because pdf_document::xref_index contains values relative to the document's original multi-part xref while the actual xref is the repaired single-part one (and thus the cached value is too large). Properly resetting the xref_index before starting reparation fixes this crash.
2015-01-20fix memory leak introduced with commit 90c560641d9b459a658029eefc4cbb02fdbca0b5Simon Bünzli
2015-01-20Bug 695770: fix TODO in commit d7c0c0856b31be17823ae4745b2c542a9c71765fSimon Bünzli
pdf_xref_find_subsection does indeed solidify the wrong xref section: it should operate only on the oldest xref and not overwrite the most recent one with older entries.
2015-01-06Add xref_index to speed searching of sparse xrefs.Robin Watts
Add a new index that quickly maps object number to the first xref in which an object appears. This appears to get us the speed back that we lost when moving to sparse xrefs.
2015-01-05Another PDF Xref speedup from Malc.Robin Watts
Following the recent change to hold pdf xrefs in their native 'sparse' representation, searching the xref takes longer. Malc has investigated this slowdown and found that it can be largely avoided by not searching the xref lists first. A modified version of his first patch has gone in already (getting us from 10x slower to just 5x slower). This commit is a modified version of a second patch from him. Again it works by avoiding searching the xref list twice. The original version of this patch 1) appears broken to me, as it could return the wrong xref entry when object streams have more than one object in them, and 2) supposedly gets the speed back to the original 'pre-sparse change' speed. I have updated the patch to fix 1), and I hope this should not affect 2). I am slightly suspicious that removing a search can get us a 5x speed increase, but certainly this is an improvemnet. There is scope for us further reducing the search times, by us using a new table to map object number -> xref number, but unless we find a case where we are noticably slower than before, I think we can ignore this.
2014-12-29Remove unnecessary test.Robin Watts
We know i >= 0 as we've already thrown if i < 0 earlier. Credit to Malc for spotting this.
2014-12-29Performance optimisation with pdf_cache_object/pdf_get_xref_entryRobin Watts
The recent change to holding pdf xrefs in a sparse format has resulted in a significant decrease in speed (x10). Malc points out that some of this (2x) can be recovered simply by making pdf_cache_object return the entry which it found the object in. This saves us having to immediately call pdf_get_xref_entry again afterwards. I am still thinking about ways to try and get the remaining time back.
2014-12-12update pointer after ensure_solid_xref callSimon Bünzli
After calling ensure_solid_xref, the pdf_xref pointer must be updated in case ensure_solid_xref has reallocated the sections table or uses a different section table than originally used. Commit e767bd783d91ae88cd79da19e79afb2c36bcf32a fails to do so in one case. TODO: Why does pdf_xref_find_subsection solidify xref section 0 instead of xref section sub?
2014-11-26Change xref representation to cope better with sparse xrefs.Robin Watts
Currently each xref in the file results in an array from 0 to num_objects. If we have a file that has been updated many times this causes a huge waste of memory. Instead we now hold each xref as a list of non-overlapping subsections (exactly as the file holds them). Lookup is therefore potentially slower, but only on files where the xrefs are highly fragmented (i.e. where we would be saving in memory terms). Some parts of our code (notably the file writing code that does garbage collection etc) assumes that lookups of object entry pointers will not change previous object entry pointers that have been looked up. To cope with this, and to cope with the case where we are updating/creating new objects, we introduce the idea of a 'solid' xref. A solid xref is one where it has a single subsection record that spans the entire range of valid object numbers for a file. Once we have ensured that an xref is 'solid', we can safely work on the pointers within it without fear of them moving. We ensure that any 'incremental' xref is solid. We also ensure that any non-incremental write makes the xref solid.
2014-07-18properly decrypt strings in encrypted but broken documentsSimon Bünzli
If a PDF document is encrypted but broken, repairing caches all strings in encrypted form. Clearing the xref after repairing ensures that strings are returned to API callers as expected. Cf. https://code.google.com/p/sumatrapdf/issues/detail?id=2610
2014-06-09Fix 695300: don't throw exception on invalid reference number.Tor Andersson
Return the null object rather than throwing an exception when parsing indirect object references with negative object numbers. Do range check for object numbers (1 .. length) when object numbers are used instead. Object number 0 is not a valid object number. It must always be 'free'.
2014-05-29fix memory leaks during PDF document creationSimon Bünzli
pdf_create_document leaks the trailer and in pdf-device.c many objects are inserted into dictionaries using pdf_dict_puts and leaked instead of using pdf_dict_puts_drop.
2014-05-29Tolerate zero-sized xref sections...Tor Andersson
...like the one Microsoft Word generates.
2014-05-05Fix 695098: don't use atoi() on non-zero-terminated buffer.Tor Andersson
2014-03-25Break dependencies on pdf-form.c and pdf-js.cTor Andersson
Split functions out of pdf-form.c that shouldn't be there, and make javascript initialization explicit.
2014-03-17Don't drop objects if they have been modified.Robin Watts
This avoids leaks when pdf_clear_xref etc are used.
2014-03-04Bug 691691: Add way of clearing cached objects out of the xref.Robin Watts
We add various facilities here, intended to allow us to efficiently minimise the memory we use for holding cached pdf objects. Firstly, we add the ability to 'mark' all the currently loaded objects. Next we add the ability to 'clear the xref' - to drop all the currently loaded objects that have no other references except the ones held by the xref table itself. Finally, we add the ability to 'clear the xref to the last mark' - to drop all the currently loaded objects that have been created since the last 'mark' operation and have no other references except the ones held by the xref table. We expose this to the user by adding a new device hint 'FZ_NO_CACHE'. If set on the device, then the PDF interpreter will pdf_mark_xref before starting and pdf_clear_xref_to_mark afterwards. Thus no additional objects will be retained in memory after a given page is run, unless someone else picks them up and takes a reference to them as part of the run. We amend our simple example app to set this device hint when loading pages as part of a search.
2014-02-25Bug 695040: prevent integer overflow in pdf_xref_size_from_old_trailerSimon Bünzli
2014-02-11tolerate streamed xrefs where object 0 is missingSimon Bünzli
see https://code.google.com/p/sumatrapdf/issues/detail?id=2517 for a document which is broken to the point where it fails to load using reparation but loads successfully if object 0 is implicitly defined.
2014-01-17Bug 694896: Ensure that repairs don't lose trailer dict.Robin Watts
When we find certain classes of flaw in the file while attempting to read an object, we trigger an automatic repair of the file. This leaves almost all objects unchanged; the sole exception is that of the trailer object (and its sub objects) which can get dropped and recreated. To avoid leaving people holding handles to objects within the trailer dict high and dry, we introduce a 'pre_repair_trailer' object to each xref entry. On a repair, we copy the existing trailer object to this. As we only ever repair once, this is safe. The only known place where this is a problem is when setting up the pdf_crypt for a document; we adapt the code here to allow for potential problems. The example file that shows this up is: 048d14d2f5f0ae31e9a2cde0be66f16a_asan_heap-uaf_86d4ed_3961_3661.pdf Thanks to Mateusz Jurczyk and Gynvael Coldwind of the Google Security Team for providing the fuzzing files.
2014-01-17Bug 694897: Fix valgrind issues with versionsRobin Watts
If the /Version is a single character string (say "s") then the current code for converting this in pdf_init_document reads off the end of the string. Simple fix is to use fz_atof instead. Same fix for reading the PDF version normally. This solves: 53b830f849d028fb2d528520716e157a_asan_heap-oob_478692_5259_4534.pdf Thanks to Mateusz Jurczyk and Gynvael Coldwind of the Google Security Team for providing the example files.
2014-01-08prevent heap access violation in pdf_cache_objectSimon Bünzli
pdf_load_obj_stm may resize the xref if it finds further objects in the stream, that might however invalidate any pdf_xref_entry hold such as the one in pdf_cache_object. This can be seen e.g. with 7ac3ad9ddad98d10b947a43cf640062f_asan_heap-uaf_930b78_1007_1675.pdf Thanks to Mateusz Jurczyk and Gynvael Coldwind of the Google Security Team for providing the example files.
2014-01-07Introduce 'document handlers'.Robin Watts
We define a document handler for each file type (2 in the case of PDF, one to handle files with the ability to 'run' them, and one without). We then register these handlers with the context at startup, and then call fz_open_document... as usual. This enables people to select the document types they want at will (and even to extend the library with more document types should they wish).
2014-01-06fix MSVC warnings C4054 and C4152Simon Bünzli
These warnings are caused by casting function pointers to void* instead of proper function types.
2014-01-02Add rebinding for fz_devices and fz_documentsRobin Watts
The SVG device needs rebinding as it holds a file. The PDF device needs to rebind the underlying pdf document. All documents need to rebind their underlying streams.
2014-01-02Fix memory leak in pdf_xref_size_from_old_trailer.Robin Watts
Thanks to Simon for spotting the original problem. This is a slight tweak on the patch he supplied.