Bug 705506

Summary: gs returns exit status 0 instead of 1 when PDF decryption fails
Product: Ghostscript Reporter: alex0375+ghostscript
Component: PDF InterpreterAssignee: Default assignee <ghostpdl-bugs>
Status: RESOLVED WONTFIX    
Severity: normal    
Priority: P4    
Version: 9.56.1   
Hardware: PC   
OS: MacOS X   
Customer: Word Size: ---
Attachments: password-protected pdf (pass: password)

Description alex0375+ghostscript 2022-06-13 22:22:46 UTC
Created attachment 22721 [details]
password-protected pdf (pass: password)

Thanks for the great product.

I updated recently to gs v9.56.1 and noticed that the new PDF interpreter introduced a regression: if gs fails to decrypt a password-protected PDF file, it exits with status code 0 instead of 1.

Example:

$ gs -sDEVICE=pdfwrite -sOutputFile=output.pdf -dBATCH file_encrypted.pdf
$ echo $? # Returns 0

But

$ gs -sDEVICE=pdfwrite -sOutputFile=output.pdf -dBATCH -dNEWPDF=false file_encrypted.pdf
$ echo $? # Returns 1
Comment 1 Ken Sharp 2022-06-14 07:29:02 UTC
This isn't a regression, though it is a change in behaviour, and essentially due to a change in emphasis.

The new PDF interpreter runs in C not PostScript and, unlike the old interpreter,  was designed to ignore errors and continue processing the file under almost all possible conditions.

This is because that is the observed behaviour of Adobe Acrobat and that is what people expect us to match. Many error conditions in the old interpreter have had to be patched around because 'Acrobat can open it'. So the new interpreter will not return an error under most conditions. It will simply do its best and then exit.

You didn't quote any of the back channel output in your report but if you look at it you will see that the old interpreter throws a PostScript error (invalidfileaccess) and then exits. The new interpreter gives you a raft of warnings, and then returns to the interactive PostScript prompt.

Old:
------------------------------------------------------------------------------
GPL Ghostscript GIT PRERELEASE 9.57.0 (2022-03-29)
Copyright (C) 2022 Artifex Software, Inc.  All rights reserved.
This software is supplied under the GNU AGPLv3 and comes with NO WARRANTY:
see the file COPYING for details.
   **** This file requires a password for access.
Error: /invalidfileaccess in pdf_process_Encrypt
Operand stack:

Execution stack:
   %interp_exit   .runexec2   --nostringval--   runpdf   --nostringval--   2   %stopped_push   --nostringval--   runpdf   runpdf   false   1   %stopped_push   1990   1   3   %oparray_pop   1989   1   3   %oparray_pop   1977   1   3   %oparray_pop   1978   1   3   %oparray_pop   runpdf   runpdf   runpdf   runpdf   false   1   %stopped_push
Dictionary stack:
   --dict:764/1123(ro)(G)--   --dict:1/20(G)--   --dict:80/200(L)--   --dict:80/200(L)--   --dict:135/256(ro)(G)--   --dict:325/325(ro)(G)--   --dict:27/32(L)--
Current allocation mode is local
GPL Ghostscript GIT PRERELEASE 9.57.0: Unrecoverable error, exit code 1
------------------------------------------------------------------------------

New:
------------------------------------------------------------------------------
GPL Ghostscript 9.56.1 (2022-04-04)
Copyright (C) 2022 Artifex Software, Inc.  All rights reserved.
This software is supplied under the GNU AGPLv3 and comes with NO WARRANTY:
see the file COPYING for details.
GPL Ghostscript 9.56.1:
   **** This file requires a password for access.
   **** Error: Couldn't initialise file.
               Output may be incorrect.
   No pages will be processed (FirstPage > LastPage).

The following warnings were encountered at least once while processing this file:
        Invalid /Length supplied in Encryption dictionary.

   **** This file had errors that were repaired or ignored.
   **** Please notify the author of the software that produced this
   **** file that it does not conform to Adobe's published PDF
   **** specification.

GS>
------------------------------------------------------------------------------

If you want to be informed by the exit code when there is a problem, then you should set -dPDFSTOPONERROR which will do what it says; when there is an error the interpreter will stop and return that error code. This will result in the same behaviour as the old interpreter, the interpreter will exit with an error code of 1.