Bug 693398 - Running attached PostScript file crashes Ghostscipt
Summary: Running attached PostScript file crashes Ghostscipt
Status: RESOLVED FIXED
Alias: None
Product: Ghostscript
Classification: Unclassified
Component: PS Interpreter (show other bugs)
Version: 9.05
Hardware: PC Windows 7
: P4 normal
Assignee: Chris Liddell (chrisl)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-10-21 23:58 UTC by Peter Williams
Modified: 2013-01-30 13:58 UTC (History)
3 users (show)

See Also:
Customer:
Word Size: ---


Attachments
Zipped spool file (438.33 KB, application/octet-stream)
2012-10-21 23:58 UTC, Peter Williams
Details
PostScript file (624.72 KB, application/x-zip-compressed)
2012-10-22 05:42 UTC, Peter Williams
Details
PS file that causes a crash. (3.83 MB, application/postscript)
2012-10-27 02:58 UTC, William Bader
Details
result of running "bin/gs -dNOGC -sDEVICE=pdfwrite -sOutputFile=cpag.pdf /tmp/cpag.ps" under valgrind (68.78 KB, text/plain)
2012-10-27 03:16 UTC, William Bader
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Peter Williams 2012-10-21 23:58:48 UTC
Created attachment 9012 [details]
Zipped spool file

\gswin64c.exe" '\adobe_reader\pages=28 color_pages=20 - vmi20_manual.prn"

GPL Ghostscript 9.05 (2012-02-08)
Copyright (C) 2010 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
Loading NimbusMonL-Regu font from %rom%Resource/Font/NimbusMonL-Regu... 3589600 2107223 2937856 1645866 1 done.
>>showpage, press <return> to continue<<

%%[Page: 1]%%
>>showpage, press <return> to continue<<

%%[Page: 2]%%
>>showpage, press <return> to continue<<

%%[Page: 3]%%
>>showpage, press <return> to continue<<

%%[Page: 4]%%
>>showpage, press <return> to continue<<

%%[Page: 5]%%
>>showpage, press <return> to continue<<

%%[Page: 6]%%
>>showpage, press <return> to continue<<

<-------------------------------------------------------------------------------------- Crashes here

As far as I could tell it crashed in the garbage collector.
Comment 1 Alex Cherepanov 2012-10-22 05:14:19 UTC
The sample file is in PCL, rather then PostScript.
Please attach a correct sample file.
Comment 2 Peter Williams 2012-10-22 05:42:16 UTC
Created attachment 9014 [details]
PostScript file
Comment 3 Peter Williams 2012-10-22 05:44:26 UTC
Alex

I apologize for that. I also had the command line and Ghostscript version
wrong.

The correct command line was  

gswin64c.exe -dNOPAUSE -dBATCH -sDEVICE=png16m -r400 -dDownScaleFactor=4 
-sOutputFile=RASTER%04d.png "pages=28 color_pages=20 - vmi20_manual.prn"

GPL Ghostscript 9.05 (2012-02-08)

The correct file is now attached.
Comment 4 Ken Sharp 2012-10-22 07:13:24 UTC
(In reply to comment #3)

> The correct command line was  
> 
> gswin64c.exe -dNOPAUSE -dBATCH -sDEVICE=png16m -r400 -dDownScaleFactor=4 
> -sOutputFile=RASTER%04d.png "pages=28 color_pages=20 - vmi20_manual.prn"
> 
> GPL Ghostscript 9.05 (2012-02-08)
> 
> The correct file is now attached.

The attached file works correctly with current code, both release and debug versions. So I downloaded the 64-bit 9.05 release from our web site and installed it. That too works as expected.

In short, I am unable to reproduce the problem using the supplied file and command line.
Comment 5 Peter Williams 2012-10-22 07:54:20 UTC
Hi Ken,

I downloaded the 9.06 Windows 64 binary and the problem did not reproduce so we are good.

That made we wonder if the bug ever existed so I did some more testing. This is NOT a request for a bug fix. 

I reproduced the crash here with 9.05 Windows binary with the command line I sent you and another variation of it 

r72 -dNOPAUSE -dBATCH -sDEVICE=jpeg  "pages=28 color_pages=20 - vmi20_manual.prn"

I also built the source with version signature "GPL Ghostscript 9.06 (2012-08-08)" in Visual Studio 2010 in Win32 Debug mode, ran both command lines (previous report and above) and got the same crash in both cases.

It faults here 

                const chunk_head_t *chead = (const chunk_head_t *)
                ((const char *)pfree -
                 (pfree->o_back << obj_back_shift));
54FBAC9A  mov         edx,dword ptr [pfree]  
54FBAC9D  mov         eax,dword ptr [edx]   <==== Access violation

Call stack 

>	gsdll32.dll!igc_reloc_struct_ptr(const void * obj, gc_state_s * gcst)  Line 1301 + 0x3 bytes	C
 	gsdll32.dll!image_enum_reloc_ptrs(void * vptr, unsigned int size, const gs_memory_struct_type_s * pstype, gc_state_s * gcst)  Line 110 + 0x1b5 bytes	C
 	gsdll32.dll!gc_do_reloc(chunk_s * cp, gs_ref_memory_s * mem, gc_state_s * pstate)  Line 1243 + 0x19 bytes	C
 	gsdll32.dll!gs_gc_reclaim(vm_spaces_s * pspaces, int global)  Line 448 + 0x17 bytes	C
 	gsdll32.dll!context_reclaim(vm_spaces_s * pspaces, int global)  Line 280 + 0x10 bytes	C
 	gsdll32.dll!gs_vmreclaim(gs_dual_memory_s * dmem, int global)  Line 155 + 0x13 bytes	C
 	gsdll32.dll!ireclaim(gs_dual_memory_s * dmem, int space)  Line 77 + 0xd bytes	C
 	gsdll32.dll!interp_reclaim(gs_context_state_s * * pi_ctx_p, int space)  Line 432 + 0x13 bytes	C
 	gsdll32.dll!interp(gs_context_state_s * * pi_ctx_p, const ref_s * pref, ref_s * perror_object)  Line 1702 + 0xb bytes	C
 	gsdll32.dll!gs_call_interp(gs_context_state_s * * pi_ctx_p, ref_s * pref, int user_errors, int * pexit_code, ref_s * perror_object)  Line 501 + 0x11 bytes	C
 	gsdll32.dll!gs_interpret(gs_context_state_s * * pi_ctx_p, ref_s * pref, int user_errors, int * pexit_code, ref_s * perror_object)  Line 460 + 0x19 bytes	C
 	gsdll32.dll!gs_main_interpret(gs_main_instance_s * minst, ref_s * pref, int user_errors, int * pexit_code, ref_s * perror_object)  Line 242 + 0x1c bytes	C
 	gsdll32.dll!gs_main_run_string_end(gs_main_instance_s * minst, int user_errors, int * pexit_code, ref_s * perror_object)  Line 608 + 0x19 bytes	C
 	gsdll32.dll!gs_main_run_string_with_length(gs_main_instance_s * minst, const char * str, unsigned int length, int user_errors, int * pexit_code, ref_s * perror_object)  Line 566 + 0x15 bytes	C
 	gsdll32.dll!gs_main_run_string(gs_main_instance_s * minst, const char * str, int user_errors, int * pexit_code, ref_s * perror_object)  Line 549 + 0x26 bytes	C
 	gsdll32.dll!run_string(gs_main_instance_s * minst, const char * str, int options)  Line 835 + 0x1c bytes	C
 	gsdll32.dll!runarg(gs_main_instance_s * minst, const char * pre, const char * arg, const char * post, int options)  Line 824 + 0x11 bytes	C
 	gsdll32.dll!argproc(gs_main_instance_s * minst, const char * arg)  Line 757 + 0x19 bytes	C
 	gsdll32.dll!gs_main_init_with_args(gs_main_instance_s * minst, int argc, char * * argv)  Line 226 + 0x10 bytes	C
 	gsdll32.dll!gsapi_init_with_args(void * lib, int argc, char * * argv)  Line 174 + 0x1c bytes	C
 	gswin32c.exe!main(int argc, char * * argv)  Line 590 + 0x17 bytes	C
 	gswin32c.exe!__tmainCRTStartup()  Line 278 + 0x19 bytes	C
 	gswin32c.exe!mainCRTStartup()  Line 189	C
Comment 6 Ken Sharp 2012-10-22 08:08:05 UTC
(In reply to comment #5)

> I downloaded the 9.06 Windows 64 binary and the problem did not reproduce so we
> are good.

Sadly, I'm not sure I agree, see below....

 
> I reproduced the crash here with 9.05 Windows binary with the command line I
> sent you and another variation of it 

The 9.05 binary is the one I was using, and it doesn't crash for me using your command line (obviously paths are different).

 
> r72 -dNOPAUSE -dBATCH -sDEVICE=jpeg  "pages=28 color_pages=20 -
> vmi20_manual.prn"
> 
> I also built the source with version signature "GPL Ghostscript 9.06
> (2012-08-08)" in Visual Studio 2010 in Win32 Debug mode, ran both command lines
> (previous report and above) and got the same crash in both cases.
> 
> It faults here 
> 
>                 const chunk_head_t *chead = (const chunk_head_t *)
>                 ((const char *)pfree -
>                  (pfree->o_back << obj_back_shift));
> 54FBAC9A  mov         edx,dword ptr [pfree]  
> 54FBAC9D  mov         eax,dword ptr [edx]   <==== Access violation
> 
> Call stack 

Unfortunately this doesn't tell us much. The garbage collector's pointers have been confused, and when we try to relocate memory (or do other garbage collection tasks), the problem exhibits. This is not, however, the source of the problem. The problem occurs at the time the pointers were corrupted, which could be quite some significant time previously and is undoubtedly in a totally different area of the code.

These sorts of problems are extremely difficult to track down, as they are dependent on the memory layout, and can appear and disappear very easily. The fact that I can't reproduce it doesn't mean much, which is why I didn't close the bug report.

It also doesn't mean that the problem won't reproduce on some other computer, or with a slightly different command line. I'm leaving it open for Alex to have a go with Memento and see if he can find it, but this one might take a long time to resolve.
Comment 7 Alex Cherepanov 2012-10-23 15:08:16 UTC
I can easily reproduce the problem on AMD64, GNU/Linux.
The problem first appears in v. 9.00
Comment 8 Alex Cherepanov 2012-10-25 15:48:20 UTC
The first bad revision is a5fb547c5246c71cce68ba9032a685179befa1b1
The last good revision is 35aa0a548eebb3ef4528dc334aca9235820ece2e

There are about 60 revisions between, mostly committed by Michael,
that I cannot compile or run.
Comment 9 William Bader 2012-10-27 02:57:13 UTC
I am getting a core dump in ps2pdf that might be another instance of this bug.
I have 64 bit Fedora 17 with gcc 4.7.2, and it happens both with the gs9.06 that I built from source and with Fedora's gs9.05.
I can post the file if you want.  It is 4MB.
I have gdb and valgrind messages below.
The first valgrind warning is

static bool
ptr_struct_mark(enum_ptr_t *pep, gc_state_t * ignored)
{
    obj_header_t *ptr = (obj_header_t *)pep->ptr;

    if (ptr == 0)
        return false;
    ptr--;                      /* point to header */
    if (!o_is_unmarked(ptr))   <<<<------ here
        return false;
    o_mark(ptr);
    return true;
}

Something has probably gone bad to get an uninitialized variable there.

William

(gdb) set args -sDEVICE=pdfwrite -sOutputFile=cpag.pdf /tmp/cpag.ps
(gdb) r
Starting program: /tmp/gs9.06/bin/gs -sDEVICE=pdfwrite -sOutputFile=cpag.pdf /tmp/cpag.ps
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
GPL Ghostscript 9.06 (2012-08-08)
Copyright (C) 2012 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.

Program received signal SIGSEGV, Segmentation fault.
0x0000000000567afd in igc_reloc_struct_ptr (obj=0x19c49c8, gcst=0x7fffffffa3d0) at ./psi/igc.c:1301
1301                     (pfree->o_back << obj_back_shift));
(gdb) bt
#0  0x0000000000567afd in igc_reloc_struct_ptr (obj=0x19c49c8, gcst=0x7fffffffa3d0) at ./psi/igc.c:1301
#1  0x00000000009514f1 in basic_reloc_ptrs (vptr=0x19c4980, size=56, pstype=0xc5f0c0, gcst=0x7fffffffa3d0) at ./base/gsmemory.c:347
#2  0x0000000000567a5b in gc_do_reloc (cp=0x192cf80, mem=0x17b7dc8, pstate=0x7fffffffa3d0) at ./psi/igc.c:1243
#3  0x0000000000566016 in gs_gc_reclaim (pspaces=0x17f5138, global=0) at ./psi/igc.c:445
#4  0x000000000063542f in context_reclaim (pspaces=0x17f5138, global=0) at ./psi/zcontext.c:280
#5  0x0000000000524778 in gs_vmreclaim (dmem=0x17f5130, global=0) at ./psi/ireclaim.c:155
#6  0x00000000005244fa in ireclaim (dmem=0x17f5130, space=-1) at ./psi/ireclaim.c:77
#7  0x000000000051ea1e in interp_reclaim (pi_ctx_p=0x17b62e8, space=-1) at ./psi/interp.c:432
#8  0x0000000000521708 in interp (pi_ctx_p=0x17b62e8, pref=0x7fffffffb1c0, perror_object=0x7fffffffb290) at ./psi/interp.c:1702                                                  
#9  0x000000000051ec63 in gs_call_interp (pi_ctx_p=0x17b62e8, pref=0x7fffffffb1c0, user_errors=1, pexit_code=0x7fffffffb2a8, perror_object=0x7fffffffb290) at ./psi/interp.c:501
#10 0x000000000051eab7 in gs_interpret (pi_ctx_p=0x17b62e8, pref=0x7fffffffb1c0, user_errors=1, pexit_code=0x7fffffffb2a8, perror_object=0x7fffffffb290) at ./psi/interp.c:459
#11 0x000000000051366d in gs_main_interpret (minst=0x17b6250, pref=0x7fffffffb1c0, user_errors=1, pexit_code=0x7fffffffb2a8, perror_object=0x7fffffffb290) at ./psi/imain.c:241
#12 0x0000000000514365 in gs_main_run_string_end (minst=0x17b6250, user_errors=1, pexit_code=0x7fffffffb2a8, perror_object=0x7fffffffb290) at ./psi/imain.c:607
#13 0x0000000000514231 in gs_main_run_string_with_length (minst=0x17b6250, str=0x1ae2f80 "<2f746d702f637061672e7073>.runfile", length=34, user_errors=1,
    pexit_code=0x7fffffffb2a8, perror_object=0x7fffffffb290) at ./psi/imain.c:565
#14 0x00000000005141a3 in gs_main_run_string (minst=0x17b6250, str=0x1ae2f80 "<2f746d702f637061672e7073>.runfile", user_errors=1, pexit_code=0x7fffffffb2a8,
    perror_object=0x7fffffffb290) at ./psi/imain.c:547
#15 0x0000000000516f7d in run_string (minst=0x17b6250, str=0x1ae2f80 "<2f746d702f637061672e7073>.runfile", options=3) at ./psi/imainarg.c:834
#16 0x0000000000516f06 in runarg (minst=0x17b6250, pre=0x9fdc23 "", arg=0x7fffffffc842 "/tmp/cpag.ps", post=0x9fdd2d ".runfile", options=3) at ./psi/imainarg.c:824
#17 0x0000000000516c13 in argproc (minst=0x17b6250, arg=0x7fffffffc842 "/tmp/cpag.ps") at ./psi/imainarg.c:757
#18 0x00000000005155bc in gs_main_init_with_args (minst=0x17b6250, argc=4, argv=0x7fffffffbea8) at ./psi/imainarg.c:226
#19 0x000000000045b48b in main (argc=4, argv=0x7fffffffbea8) at ./psi/gs.c:96


valgrind
...
==8425== Conditional jump or move depends on uninitialised value(s)
==8425==    at 0x56753C: ptr_struct_mark (igc.c:1084)
==8425==    by 0x566E10: gc_trace (igc.c:874)
==8425==    by 0x565BAF: gs_gc_reclaim (igc.c:334)
==8425==    by 0x63542E: context_reclaim (zcontext.c:280)
==8425==    by 0x524777: gs_vmreclaim (ireclaim.c:155)
==8425==    by 0x5244F9: ireclaim (ireclaim.c:77)
==8425==    by 0x51EA1D: interp_reclaim (interp.c:432)
==8425==    by 0x521707: interp (interp.c:1702)
==8425==    by 0x51EC62: gs_call_interp (interp.c:501)
==8425==    by 0x51EAB6: gs_interpret (interp.c:459)
==8425==    by 0x51366C: gs_main_interpret (imain.c:241)
==8425==    by 0x514364: gs_main_run_string_end (imain.c:607)
==8425==
==8425== Conditional jump or move depends on uninitialised value(s)
==8425==    at 0x566ACD: gc_trace_chunk (igc.c:759)
==8425==    by 0x565C25: gs_gc_reclaim (igc.c:343)
==8425==    by 0x63542E: context_reclaim (zcontext.c:280)
==8425==    by 0x524777: gs_vmreclaim (ireclaim.c:155)
==8425==    by 0x5244F9: ireclaim (ireclaim.c:77)
==8425==    by 0x51EA1D: interp_reclaim (interp.c:432)
==8425==    by 0x521707: interp (interp.c:1702)
==8425==    by 0x51EC62: gs_call_interp (interp.c:501)
==8425==    by 0x51EAB6: gs_interpret (interp.c:459)
==8425==    by 0x51366C: gs_main_interpret (imain.c:241)
==8425==    by 0x514364: gs_main_run_string_end (imain.c:607)
==8425==    by 0x514230: gs_main_run_string_with_length (imain.c:565)
==8425==
==8425== Conditional jump or move depends on uninitialised value(s)
==8425==    at 0x566ADF: gc_trace_chunk (igc.c:760)
==8425==    by 0x565C25: gs_gc_reclaim (igc.c:343)
==8425==    by 0x63542E: context_reclaim (zcontext.c:280)
==8425==    by 0x524777: gs_vmreclaim (ireclaim.c:155)
==8425==    by 0x5244F9: ireclaim (ireclaim.c:77)
==8425==    by 0x51EA1D: interp_reclaim (interp.c:432)
==8425==    by 0x521707: interp (interp.c:1702)
==8425==    by 0x51EC62: gs_call_interp (interp.c:501)
==8425==    by 0x51EAB6: gs_interpret (interp.c:459)
==8425==    by 0x51366C: gs_main_interpret (imain.c:241)
==8425==    by 0x514364: gs_main_run_string_end (imain.c:607)
==8425==    by 0x514230: gs_main_run_string_with_length (imain.c:565)
==8425==
==8425== Conditional jump or move depends on uninitialised value(s)
==8425==    at 0x56753C: ptr_struct_mark (igc.c:1084)
==8425==    by 0x566E10: gc_trace (igc.c:874)
==8425==    by 0x566B5F: gc_trace_chunk (igc.c:770)
==8425==    by 0x565C25: gs_gc_reclaim (igc.c:343)
==8425==    by 0x63542E: context_reclaim (zcontext.c:280)
==8425==    by 0x524777: gs_vmreclaim (ireclaim.c:155)
==8425==    by 0x5244F9: ireclaim (ireclaim.c:77)
==8425==    by 0x51EA1D: interp_reclaim (interp.c:432)
==8425==    by 0x521707: interp (interp.c:1702)
==8425==    by 0x51EC62: gs_call_interp (interp.c:501)
==8425==    by 0x51EAB6: gs_interpret (interp.c:459)
==8425==    by 0x51366C: gs_main_interpret (imain.c:241)
==8425==
==8425== Conditional jump or move depends on uninitialised value(s)
==8425==    at 0x566E9E: gc_trace (igc.c:889)
==8425==    by 0x566B5F: gc_trace_chunk (igc.c:770)
==8425==    by 0x565C25: gs_gc_reclaim (igc.c:343)
==8425==    by 0x63542E: context_reclaim (zcontext.c:280)
==8425==    by 0x524777: gs_vmreclaim (ireclaim.c:155)
==8425==    by 0x5244F9: ireclaim (ireclaim.c:77)
==8425==    by 0x51EA1D: interp_reclaim (interp.c:432)
==8425==    by 0x521707: interp (interp.c:1702)
==8425==    by 0x51EC62: gs_call_interp (interp.c:501)
==8425==    by 0x51EAB6: gs_interpret (interp.c:459)
==8425==    by 0x51366C: gs_main_interpret (imain.c:241)
==8425==    by 0x514364: gs_main_run_string_end (imain.c:607)
...
==8425== Invalid read of size 4
==8425==    at 0x567AFD: igc_reloc_struct_ptr (igc.c:1301)  
==8425==    by 0x9514F0: basic_reloc_ptrs (gsmemory.c:347)
==8425==    by 0x567A5A: gc_do_reloc (igc.c:1243)   
==8425==    by 0x566015: gs_gc_reclaim (igc.c:445)
==8425==    by 0x63542E: context_reclaim (zcontext.c:280)
==8425==    by 0x524777: gs_vmreclaim (ireclaim.c:155)
==8425==    by 0x5244F9: ireclaim (ireclaim.c:77)
==8425==    by 0x51EA1D: interp_reclaim (interp.c:432)  
==8425==    by 0x521707: interp (interp.c:1702)
==8425==    by 0x51EC62: gs_call_interp (interp.c:501)
==8425==    by 0x51EAB6: gs_interpret (interp.c:459)
==8425==    by 0x51366C: gs_main_interpret (imain.c:241)
==8425==  Address 0xffffffff0caa7558 is not stack'd, malloc'd or (recently) free'd
==8425==
==8425==
==8425== Process terminating with default action of signal 11 (SIGSEGV)
==8425==  Access not within mapped region at address 0xFFFFFFFF0CAA7558
==8425==    at 0x567AFD: igc_reloc_struct_ptr (igc.c:1301)
==8425==    by 0x9514F0: basic_reloc_ptrs (gsmemory.c:347)
==8425==    by 0x567A5A: gc_do_reloc (igc.c:1243)
==8425==    by 0x566015: gs_gc_reclaim (igc.c:445)
==8425==    by 0x63542E: context_reclaim (zcontext.c:280)
==8425==    by 0x524777: gs_vmreclaim (ireclaim.c:155)
==8425==    by 0x5244F9: ireclaim (ireclaim.c:77)
==8425==    by 0x51EA1D: interp_reclaim (interp.c:432)
==8425==    by 0x521707: interp (interp.c:1702)
==8425==    by 0x51EC62: gs_call_interp (interp.c:501)
==8425==    by 0x51EAB6: gs_interpret (interp.c:459)
==8425==    by 0x51366C: gs_main_interpret (imain.c:241)
Comment 10 William Bader 2012-10-27 02:58:53 UTC
Created attachment 9033 [details]
PS file that causes a crash.
Comment 11 William Bader 2012-10-27 03:16:13 UTC
Created attachment 9034 [details]
result of running "bin/gs -dNOGC -sDEVICE=pdfwrite -sOutputFile=cpag.pdf /tmp/cpag.ps" under valgrind

The log is the result of running "bin/gs -dNOGC -sDEVICE=pdfwrite -sOutputFile=cpag.pdf /tmp/cpag.ps" under valgrind.
With -dNOGC, gs9.06 does not crash, but it still gets some warnings in gc-related code.
William
Comment 12 Alex Cherepanov 2013-01-14 15:22:21 UTC
William, your sample file demonstrates an unrelated problem, which is
now tracked as a bug 693561.
Comment 13 Ken Sharp 2013-01-29 17:26:39 UTC
Ooops wrong bug

reset to P4
Comment 14 Chris Liddell (chrisl) 2013-01-29 23:22:14 UTC
The problem is caused because whilst relocating the pointers in a gx_image_enum, one of the pointers we try to adjust is the gx_image_enum->cie_range pointer. *But* that pointer is not a pointer to an allocated block of memory, it's a pointer into the "middle" of an allocated block. As a result there is no "header" immediately preceding the pointer target for the relocating code to use, and it gets a crazy large offset to use.

I have a hacked up idea for a solution which seems to work, so tomorrow morning, I'll tidy it up, make it less hacky, and test it properly.

Frankly, I'm surprised this hasn't come up before - even though images in CIE color spaces are not exactly common.
Comment 15 Chris Liddell (chrisl) 2013-01-30 13:58:02 UTC
Fixed in:
http://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=508a79ca