Bug 707645 - /rangecheck after calling setpagedevice
Summary: /rangecheck after calling setpagedevice
Status: RESOLVED FIXED
Alias: None
Product: Ghostscript
Classification: Unclassified
Component: PS Interpreter (show other bugs)
Version: 10.02.1
Hardware: PC Windows 10
: P2 normal
Assignee: Default assignee
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2024-03-06 13:51 UTC by Martin Gieseking
Modified: 2024-03-06 18:23 UTC (History)
0 users

See Also:
Customer:
Word Size: ---


Attachments
example to reproduce the error (44.93 KB, application/x-zip-compressed)
2024-03-06 14:18 UTC, Martin Gieseking
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Gieseking 2024-03-06 13:51:35 UTC
After the removal of 'finddevice' and 'putdeviceprops', I have to find a proper replacement for these operators. Unfortunately, 'setpagedevice' behaves differently and I'm not sure if that's a bug.
In order to extract bitmap images from PS files I redefine the 'image' operator like this (-dNOSAFER applied):

/image {
  gsave	
  <<
    /OutputDevice /jpeg
    /OutputFile (test.jpg)
  >>
  setpagedevice
  systemdict /image get exec
  copypage  
  grestore
} def

When running a PS file with embedded bitmap data afterwards, I now get the following error:
%%[ Error handled by opdfread.ps : rangecheck; OffendingCommand: image ]%%

That didn't happen with 'finddevice'. Is this expected behavior or a GS issue? If it's not a bug, how can the original functionality of 'finddevice' and 'putdeviceprops' be reconstructed in this context?
Comment 1 Ken Sharp 2024-03-06 14:07:35 UTC
(In reply to Martin Gieseking from comment #0)

> After the removal of 'finddevice' and 'putdeviceprops', I have to find a
> proper replacement for these operators. Unfortunately, 'setpagedevice'
> behaves differently and I'm not sure if that's a bug.

It isn't a bug, the non-standard operators which have been removed did not behave the same as setpagedevice.

 
> When running a PS file with embedded bitmap data afterwards, I now get the
> following error:
> %%[ Error handled by opdfread.ps : rangecheck; OffendingCommand: image ]%%

That specific error is from a PostScript file produced by the ps2write device.

 
> That didn't happen with 'finddevice'. Is this expected behavior or a GS
> issue?

Quite likely neither. You were using non-standard PostScript operators which have proven to be a security problem and been removed. We can't tell how people are/were using non-standard operators so we can't say this was 'expected'. Nor is it likely to be a bug.


> If it's not a bug, how can the original functionality of 'finddevice'
> and 'putdeviceprops' be reconstructed in this context?

Basically you can't have the functionality of those devices 'reconstructed', because that would re-introduce the security vulnerability.

What you might be able to do is achieve the same result, but to be able to help you with that you will have to supply us enough to reproduce your problem. That's going to mean an example file and a command line we can use, at the least.
Comment 2 Martin Gieseking 2024-03-06 14:16:28 UTC
Thanks for the prompt reply. I'll attach a small example. The following call of GS leads to the mentioned error:

$ gs -dNOSAFER -dNODISPLAY image.ps

%%[ Error handled by opdfread.ps : rangecheck; OffendingCommand: image ]%%
%%[STACK:
--nostringval--
-mark-
-mark-
-mark-
%%]%
Comment 3 Martin Gieseking 2024-03-06 14:18:21 UTC
Created attachment 25436 [details]
example to reproduce the error
Comment 4 Ken Sharp 2024-03-06 15:12:59 UTC
(In reply to Martin Gieseking from comment #3)
> Created attachment 25436 [details]
> example to reproduce the error

Your code executes setpagedevice, which resets the graphics state. In particular it resets the colour space to the default.

Your problem occurs because the image is set up in a way which expects the current colour space to be DeviceRGB (a 3 component space) but it is actually DeviceGray (a 1 component space). Because the image has a /Decode array with 3 pairs of elements you get a rangecheck error.

You can resolve this particular problem by getting the current color space before you execute setpagedevice, and restoring it afterwards.

Eg:
/image {
  gsave	
  matrix currentmatrix
  currentcolorspace
  <<
    /OutputDevice /jpeg
    /OutputFile (test.jpg)
  >>
  setpagedevice
  setcolorspace
  setmatrix
  systemdict /image get exec
  copypage  
  grestore
} def

Note that any other graphics state, such as the current point, the scaling, etc will also be undone by setpagedevice and you'll need to preserve some portion of that, which is why the example above saves and restores the CTM.

You can't use gsave and grestore to do the work because the device is part of the graphics state and so would get restored by a grestore.
Comment 5 Martin Gieseking 2024-03-06 18:23:48 UTC
That's awesome. Thank you for taking the time to track down the issue and for the valuable information. It helped me to get everything working again.