diff options
author | Ken Sharp <ken.sharp@artifex.com> | 2022-12-02 15:58:55 +0000 |
---|---|---|
committer | Ken Sharp <ken.sharp@artifex.com> | 2022-12-02 15:58:55 +0000 |
commit | 62e7fc78f254af7119da2c0e2dc110cc19df404b (patch) | |
tree | 0e04e2387c94de6a28cbaa6dd7fc99627618dd26 /devices | |
parent | 1f83782cb28b1fbbe9330d242f16f4eda837660b (diff) | |
download | ghostpdl-62e7fc78f254af7119da2c0e2dc110cc19df404b.tar.gz |
pdfwrite - fix error in Linearizing output files
Bug #706116 "Segmentation fault when processing PDF with many vectors"
There are two problems here; first we should not crash, crashing is bad.
Fix that by initialising the PageHints and SharedHints to NULL and not
freeing the individual hints in the PageHints array if the array is
NULL.
The crash occurred because we got an ioerror from rewrite_object() and
that shouldn't happen either. This turns out to be because of an
optimisation. We expand the scratch buffer size as needed, and we use
that same buffer when writing out the modified object. But we were
always decreasing the amount left to write by the original size of the
buffer (16KB) even though we were writing > 512KB at a time.
Obviously this only happens with insanely large Form XObjects, 16KB is
normally enough to write any reasonable Form dictionary, and we only
expand the size if we need to write a larger dictionary.
Diffstat (limited to 'devices')
-rw-r--r-- | devices/vector/gdevpdf.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/devices/vector/gdevpdf.c b/devices/vector/gdevpdf.c index bdcd74f23..0adefbf68 100644 --- a/devices/vector/gdevpdf.c +++ b/devices/vector/gdevpdf.c @@ -1730,7 +1730,7 @@ rewrite_object(gx_device_pdf *const pdev, pdf_linearisation_t *linear_params, in if (code != 1) return_error(gs_error_ioerror); gp_fwrite(Scratch, ScratchSize, 1, linear_params->Lin_File.file); - Size -= 16384; + Size -= ScratchSize; } else { code = gp_fread(Scratch, Size, 1, linear_params->sfile); if (code != 1) @@ -1817,6 +1817,10 @@ static int pdf_linearise(gx_device_pdf *pdev, pdf_linearisation_t *linear_params sflush(pdev->strm); linear_params->sfile = pdev->file; linear_params->MainFileEnd = gp_ftell(pdev->file); + + linear_params->PageHints = NULL; + linear_params->SharedHints = NULL; + #ifdef LINEAR_DEBUGGING code = gx_device_open_output_file((gx_device *)pdev, "/temp/linear.pdf", true, true, &linear_params->Lin_File.file); @@ -2502,11 +2506,13 @@ error: #endif /* FIXME free all the linearisation records */ - for (i=0;i<pdev->next_page;i++) { - page_hint_stream_t *pagehint = &linear_params->PageHints[i]; + if (linear_params->PageHints != NULL) { + for (i=0;i<pdev->next_page;i++) { + page_hint_stream_t *pagehint = &linear_params->PageHints[i]; - if (pagehint && pagehint->SharedObjectRef) - gs_free_object(pdev->pdf_memory, pagehint->SharedObjectRef, "Free Shared object references"); + if (pagehint && pagehint->SharedObjectRef) + gs_free_object(pdev->pdf_memory, pagehint->SharedObjectRef, "Free Shared object references"); + } } gs_free_object(pdev->pdf_memory, linear_params->PageHints, "Free Page Hint data"); |