The attached PDF files produce exceptions when read by Ghostscript 9.04 under Windows. The original customer file, 20588799.pdf, has the error on page 19. I tried simplifying the file by removing pages 20 through 229, see the attached 20588799c.pdf, and now the error occurs on page 8. I haven't been able to duplicate this with anything other than the Windows 9.04 release; the error does not occur on Linux nor Mac OS X and my Windows compiler installation appears to be broken. The command line I'm using: gswin32.exe -sDEVICE=tiffg4 -dPDFFitPage -dSAFER -r300 -o 20588799.tif 20588799.pdf Note that removing -dPDFFitPage or -dSafer or both causes the error to not occur.
This may be a regression, gs9.01 process the file correctly (I say 'may' since there appears to be an indeterminism in the error, I've had 9.04 fail on different pages with the same input file).
It looks like this may be fixed in master; I'm bisecting now.
Running valgrind on Linux produces some suspicious results: ==5556== Invalid read of size 1 ==5556== at 0x4C28E58: memcpy (mc_replace_strmem.c:497) ==5556== by 0x9D8D42: fill_threshhold_buffer (gxht_thresh.c:560) ==5556== by 0x9D91D5: gxht_thresh_plane (gxht_thresh.c:694) ==5556== by 0x9E3E2C: image_render_mono_ht (gximono.c:1120) ==5556== by 0x9DB936: gx_image1_plane_data (gxidata.c:209) ==5556== by 0x9DEC47: gx_image_plane_data_rows (gximage.c:181) ==5556== by 0x989F0C: gs_image_next_planes (gsimage.c:601) ==5556== by 0x58C50B: image_file_continue (zimage.c:546) ==5556== by 0x53DE6C: do_call_operator (interp.c:84) ==5556== by 0x5402F0: interp (interp.c:1163) ==5556== by 0x53E617: gs_call_interp (interp.c:490) ==5556== by 0x53E433: gs_interpret (interp.c:448) ==5556== Address 0x9f6e6de is 2 bytes before a block of size 112 alloc'd ==5556== at 0x4C274A8: malloc (vg_replace_malloc.c:236) ==5556== by 0x991C0F: gs_heap_alloc_bytes (gsmalloc.c:181) ==5556== by 0x991E85: gs_heap_alloc_byte_array (gsmalloc.c:240) ==5556== by 0x981E47: gx_ht_construct_threshold (gsht.c:1545) ==5556== by 0x9D8547: gxht_thresh_image_init (gxht_thresh.c:386) ==5556== by 0x9E0416: gs_image_class_3_mono (gximono.c:168) ==5556== by 0x9E7410: gx_image_enum_begin (gxipixel.c:676) ==5556== by 0x9DFC3E: gx_begin_image1 (gximage1.c:92) ==5556== by 0xA0F1F1: gx_default_begin_typed_image (gdevddrw.c:1029) ==5556== by 0xA0F08E: gx_default_begin_image (gdevddrw.c:994) ==5556== by 0xA0F197: gx_default_begin_typed_image (gdevddrw.c:1021) ==5556== by 0x988DAB: gs_image_begin_typed (gsimage.c:240) ==5556== ==5556== Invalid read of size 1 ==5556== at 0x4C28E61: memcpy (mc_replace_strmem.c:497) ==5556== by 0x9D8D42: fill_threshhold_buffer (gxht_thresh.c:560) ==5556== by 0x9D91D5: gxht_thresh_plane (gxht_thresh.c:694) ==5556== by 0x9E3E2C: image_render_mono_ht (gximono.c:1120) ==5556== by 0x9DB936: gx_image1_plane_data (gxidata.c:209) ==5556== by 0x9DEC47: gx_image_plane_data_rows (gximage.c:181) ==5556== by 0x989F0C: gs_image_next_planes (gsimage.c:601) ==5556== by 0x58C50B: image_file_continue (zimage.c:546) ==5556== by 0x53DE6C: do_call_operator (interp.c:84) ==5556== by 0x5402F0: interp (interp.c:1163) ==5556== by 0x53E617: gs_call_interp (interp.c:490) ==5556== by 0x53E433: gs_interpret (interp.c:448) ==5556== Address 0x9f6e6dd is 3 bytes before a block of size 112 alloc'd ==5556== at 0x4C274A8: malloc (vg_replace_malloc.c:236) ==5556== by 0x991C0F: gs_heap_alloc_bytes (gsmalloc.c:181) ==5556== by 0x991E85: gs_heap_alloc_byte_array (gsmalloc.c:240) ==5556== by 0x981E47: gx_ht_construct_threshold (gsht.c:1545) ==5556== by 0x9D8547: gxht_thresh_image_init (gxht_thresh.c:386) ==5556== by 0x9E0416: gs_image_class_3_mono (gximono.c:168) ==5556== by 0x9E7410: gx_image_enum_begin (gxipixel.c:676) ==5556== by 0x9DFC3E: gx_begin_image1 (gximage1.c:92) ==5556== by 0xA0F1F1: gx_default_begin_typed_image (gdevddrw.c:1029) ==5556== by 0xA0F08E: gx_default_begin_image (gdevddrw.c:994) ==5556== by 0xA0F197: gx_default_begin_typed_image (gdevddrw.c:1021) ==5556== by 0x988DAB: gs_image_begin_typed (gsimage.c:240) ==5556== ==5556== Invalid read of size 1 ==5556== at 0x4C28E6C: memcpy (mc_replace_strmem.c:497) ==5556== by 0x9D8D42: fill_threshhold_buffer (gxht_thresh.c:560) ==5556== by 0x9D91D5: gxht_thresh_plane (gxht_thresh.c:694) ==5556== by 0x9E3E2C: image_render_mono_ht (gximono.c:1120) ==5556== by 0x9DB936: gx_image1_plane_data (gxidata.c:209) ==5556== by 0x9DEC47: gx_image_plane_data_rows (gximage.c:181) ==5556== by 0x989F0C: gs_image_next_planes (gsimage.c:601) ==5556== by 0x58C50B: image_file_continue (zimage.c:546) ==5556== by 0x53DE6C: do_call_operator (interp.c:84) ==5556== by 0x5402F0: interp (interp.c:1163) ==5556== by 0x53E617: gs_call_interp (interp.c:490) ==5556== by 0x53E433: gs_interpret (interp.c:448) ==5556== Address 0x9f6e6dc is 4 bytes before a block of size 112 alloc'd ==5556== at 0x4C274A8: malloc (vg_replace_malloc.c:236) ==5556== by 0x991C0F: gs_heap_alloc_bytes (gsmalloc.c:181) ==5556== by 0x991E85: gs_heap_alloc_byte_array (gsmalloc.c:240) ==5556== by 0x981E47: gx_ht_construct_threshold (gsht.c:1545) ==5556== by 0x9D8547: gxht_thresh_image_init (gxht_thresh.c:386) ==5556== by 0x9E0416: gs_image_class_3_mono (gximono.c:168) ==5556== by 0x9E7410: gx_image_enum_begin (gxipixel.c:676) ==5556== by 0x9DFC3E: gx_begin_image1 (gximage1.c:92) ==5556== by 0xA0F1F1: gx_default_begin_typed_image (gdevddrw.c:1029) ==5556== by 0xA0F08E: gx_default_begin_image (gdevddrw.c:994) ==5556== by 0xA0F197: gx_default_begin_typed_image (gdevddrw.c:1021) ==5556== by 0x988DAB: gs_image_begin_typed (gsimage.c:240) ==5556== ==5556== Invalid read of size 1 ==5556== at 0x4C28E77: memcpy (mc_replace_strmem.c:497) ==5556== by 0x9D8D42: fill_threshhold_buffer (gxht_thresh.c:560) ==5556== by 0x9D91D5: gxht_thresh_plane (gxht_thresh.c:694) ==5556== by 0x9E3E2C: image_render_mono_ht (gximono.c:1120) ==5556== by 0x9DB936: gx_image1_plane_data (gxidata.c:209) ==5556== by 0x9DEC47: gx_image_plane_data_rows (gximage.c:181) ==5556== by 0x989F0C: gs_image_next_planes (gsimage.c:601) ==5556== by 0x58C50B: image_file_continue (zimage.c:546) ==5556== by 0x53DE6C: do_call_operator (interp.c:84) ==5556== by 0x5402F0: interp (interp.c:1163) ==5556== by 0x53E617: gs_call_interp (interp.c:490) ==5556== by 0x53E433: gs_interpret (interp.c:448) ==5556== Address 0x9f6e6db is 5 bytes before a block of size 112 alloc'd ==5556== at 0x4C274A8: malloc (vg_replace_malloc.c:236) ==5556== by 0x991C0F: gs_heap_alloc_bytes (gsmalloc.c:181) ==5556== by 0x991E85: gs_heap_alloc_byte_array (gsmalloc.c:240) ==5556== by 0x981E47: gx_ht_construct_threshold (gsht.c:1545) ==5556== by 0x9D8547: gxht_thresh_image_init (gxht_thresh.c:386) ==5556== by 0x9E0416: gs_image_class_3_mono (gximono.c:168) ==5556== by 0x9E7410: gx_image_enum_begin (gxipixel.c:676) ==5556== by 0x9DFC3E: gx_begin_image1 (gximage1.c:92) ==5556== by 0xA0F1F1: gx_default_begin_typed_image (gdevddrw.c:1029) ==5556== by 0xA0F08E: gx_default_begin_image (gdevddrw.c:994) ==5556== by 0xA0F197: gx_default_begin_typed_image (gdevddrw.c:1021) ==5556== by 0x988DAB: gs_image_begin_typed (gsimage.c:240) ==5556== ==5556== Invalid read of size 1 ==5556== at 0x4C28EB8: memcpy (mc_replace_strmem.c:497) ==5556== by 0x9D8D42: fill_threshhold_buffer (gxht_thresh.c:560) ==5556== by 0x9D91D5: gxht_thresh_plane (gxht_thresh.c:694) ==5556== by 0x9E3E2C: image_render_mono_ht (gximono.c:1120) ==5556== by 0x9DB936: gx_image1_plane_data (gxidata.c:209) ==5556== by 0x9DEC47: gx_image_plane_data_rows (gximage.c:181) ==5556== by 0x989F0C: gs_image_next_planes (gsimage.c:601) ==5556== by 0x58C50B: image_file_continue (zimage.c:546) ==5556== by 0x53DE6C: do_call_operator (interp.c:84) ==5556== by 0x5402F0: interp (interp.c:1163) ==5556== by 0x53E617: gs_call_interp (interp.c:490) ==5556== by 0x53E433: gs_interpret (interp.c:448) ==5556== Address 0x9f6e6da is 6 bytes before a block of size 112 alloc'd ==5556== at 0x4C274A8: malloc (vg_replace_malloc.c:236) ==5556== by 0x991C0F: gs_heap_alloc_bytes (gsmalloc.c:181) ==5556== by 0x991E85: gs_heap_alloc_byte_array (gsmalloc.c:240) ==5556== by 0x981E47: gx_ht_construct_threshold (gsht.c:1545) ==5556== by 0x9D8547: gxht_thresh_image_init (gxht_thresh.c:386) ==5556== by 0x9E0416: gs_image_class_3_mono (gximono.c:168) ==5556== by 0x9E7410: gx_image_enum_begin (gxipixel.c:676) ==5556== by 0x9DFC3E: gx_begin_image1 (gximage1.c:92) ==5556== by 0xA0F1F1: gx_default_begin_typed_image (gdevddrw.c:1029) ==5556== by 0xA0F08E: gx_default_begin_image (gdevddrw.c:994) ==5556== by 0xA0F197: gx_default_begin_typed_image (gdevddrw.c:1021) ==5556== by 0x988DAB: gs_image_begin_typed (gsimage.c:240) ==5556== ==5556== Invalid read of size 1 ==5556== at 0x4C28ECA: memcpy (mc_replace_strmem.c:497) ==5556== by 0x9D8D42: fill_threshhold_buffer (gxht_thresh.c:560) ==5556== by 0x9D91D5: gxht_thresh_plane (gxht_thresh.c:694) ==5556== by 0x9E3E2C: image_render_mono_ht (gximono.c:1120) ==5556== by 0x9DB936: gx_image1_plane_data (gxidata.c:209) ==5556== by 0x9DEC47: gx_image_plane_data_rows (gximage.c:181) ==5556== by 0x989F0C: gs_image_next_planes (gsimage.c:601) ==5556== by 0x58C50B: image_file_continue (zimage.c:546) ==5556== by 0x53DE6C: do_call_operator (interp.c:84) ==5556== by 0x5402F0: interp (interp.c:1163) ==5556== by 0x53E617: gs_call_interp (interp.c:490) ==5556== by 0x53E433: gs_interpret (interp.c:448) ==5556== Address 0x9f6e6d8 is 8 bytes before a block of size 112 alloc'd ==5556== at 0x4C274A8: malloc (vg_replace_malloc.c:236) ==5556== by 0x991C0F: gs_heap_alloc_bytes (gsmalloc.c:181) ==5556== by 0x991E85: gs_heap_alloc_byte_array (gsmalloc.c:240) ==5556== by 0x981E47: gx_ht_construct_threshold (gsht.c:1545) ==5556== by 0x9D8547: gxht_thresh_image_init (gxht_thresh.c:386) ==5556== by 0x9E0416: gs_image_class_3_mono (gximono.c:168) ==5556== by 0x9E7410: gx_image_enum_begin (gxipixel.c:676) ==5556== by 0x9DFC3E: gx_begin_image1 (gximage1.c:92) ==5556== by 0xA0F1F1: gx_default_begin_typed_image (gdevddrw.c:1029) ==5556== by 0xA0F08E: gx_default_begin_image (gdevddrw.c:994) ==5556== by 0xA0F197: gx_default_begin_typed_image (gdevddrw.c:1021) ==5556== by 0x988DAB: gs_image_begin_typed (gsimage.c:240) ==5556==
Running git bisect on Windows XP says that the issue first appeared in commit 8024d7db. I'm not 100% confident in this analysis, since the page number on which the error occurs moves around with later commits.
(In reply to comment #5) > It looks like this may be fixed in master; I'm bisecting now. This statement is not correct; master fails on page 60 for me.
I can reproduce the problem on 32bit windows XP, using HEAD but not in the debug configuration. Instead, build the 'release' or 'profile' configurations (profile being more useful as it retains at least some debugging information). image_render_mono_ht calls gxht_thresh_plane. At line 694 this calls fill_threshold_buffer. That immediately calls memcpy, and this crashes. The output from some debugging is as follows: Page 43 threshold=fb7020 d_order->threshold=fb7020 yci=-21 penum->dev->band_offset_y=0 thresh_height=8 dy=-5 k=0 vdi=3530 pos=0 thresh_tile=fb6ff8 dx=0 lw=8 nft=264 rtw=6 thresh_tile points to unreadable memory (8 bytes before a defined block) So, the problem appears to be in the calculation of dy - specifically I don't think the code ever expects to get -ve numbers.
@@ -686,6 +688,8 @@ gxht_thresh_plane(gx_image_enum *penum, gx_ht_order *d_order for (k = 0; k < vdi; k++) { /* Get a pointer to our tile row */ dy = (penum->yci + k + penum->dev->band_offset_y) % thresh_height; + if (dy < 0) + dy += thresh_height; thresh_tile = threshold + d_order->width * dy; /* Fill the buffer, can be multiple rows. Make sure to update with stride */ Should fix it (and indeed does seem to here). I'll leave this to Michael to commit in case I am patching a symptom rather than a cause.
Confirmed with Michael, and committed as: commit e776cc41b9da0a535adde126464d6af906b082ae Author: Robin Watts <Robin.Watts@artifex.com> Date: Mon Oct 3 17:15:53 2011 +0100 Fix for Bug 692553; SEGV in fast thresholding halftoning code. Stupid C got the % operation wrong. In this instance, it gives an unexpected negative value causing out of bounds offsets. Simple fix is to offset by the period if it's negative.