84 lines
3.6 KiB
Diff
84 lines
3.6 KiB
Diff
|
|
From ebabebad34a3811230b7bfe351eface7f5efc8a9 Mon Sep 17 00:00:00 2001
|
||
|
|
From: Ken Sharp <ken.sharp@artifex.com>
|
||
|
|
Date: Wed, 8 Apr 2020 16:06:44 +0100
|
||
|
|
Subject: [PATCH] PostScript interpreter - don't leave A85Decode pdf_rules
|
||
|
|
uninitialised
|
||
|
|
|
||
|
|
Bug #702319 "Read of uninitialized value according to valgrind..."
|
||
|
|
|
||
|
|
There are a number of other bugs which relate to this particular problem:
|
||
|
|
690976, 692983 and 693485. The problem has come about as a cumulative
|
||
|
|
result of working on these bugs.
|
||
|
|
|
||
|
|
Starting with commit :
|
||
|
|
http://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=e0ecca32ecd12dae3310fac4b65dc224031c85a2
|
||
|
|
for bug 690976 a new flag 'pdf_rules' was added to the Ascii85Decode
|
||
|
|
state. This is initialised from the dictionary operand in PostScript
|
||
|
|
by zA85D() in zfdecode.c. When this flag is true the ASCII85Decode
|
||
|
|
filter will silently accept just '~' as a valid termination for a string
|
||
|
|
(should be '~>').
|
||
|
|
|
||
|
|
However this is not the only way to initialise an Ascii85Decode filter,
|
||
|
|
the PostScript token scanner can also use s_A85D_init_inline() which
|
||
|
|
does not initialise the flag. From this point we have the potential
|
||
|
|
for testing an unitialised variable in s_A85D_process(), if we get an
|
||
|
|
encoded string which terminates with a '~' and the filter was
|
||
|
|
instantiated from PostScript.
|
||
|
|
|
||
|
|
When fixing bug 692983, this commit:
|
||
|
|
http://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=d561224d1495321d40012230abbcf835b298f557
|
||
|
|
|
||
|
|
Alex specifically added a comment that pdf_rules must not be initialised
|
||
|
|
in s_A85D_init_inline() but didn't say why! The reason is that the
|
||
|
|
regular stream initialisation code (s_A85D-init) also uses this inline
|
||
|
|
function, so if it altered pdf_rules it would overwrite the value
|
||
|
|
previously set by zA85D().
|
||
|
|
|
||
|
|
Since the initialisation is done in two places, the only way to fix this
|
||
|
|
is to initialise pdf_rules in gs_scan_token() which this commit duly
|
||
|
|
does. I've also added comments in s_A85D_init_inline to explain more
|
||
|
|
clearly *why* pdf_rules must not be initialised here.
|
||
|
|
---
|
||
|
|
base/sa85d.h | 9 ++++++++-
|
||
|
|
psi/iscan.c | 4 ++++
|
||
|
|
2 files changed, 12 insertions(+), 1 deletion(-)
|
||
|
|
|
||
|
|
diff --git a/base/sa85d.h b/base/sa85d.h
|
||
|
|
index 6e74622..8685af7 100644
|
||
|
|
--- a/base/sa85d.h
|
||
|
|
+++ b/base/sa85d.h
|
||
|
|
@@ -41,7 +41,14 @@ typedef struct stream_A85D_state_s {
|
||
|
|
(ss)->min_left = 1; \
|
||
|
|
(ss)->word = 0; \
|
||
|
|
(ss)->odd = 0; \
|
||
|
|
- /* pdf_rules should not be initialized here */ \
|
||
|
|
+ /* pdf_rules should not be initialized here. This flag is initialised in\
|
||
|
|
+ * zA85D to either true or false, and this inline function is called *after*\
|
||
|
|
+ * that in s_A85D_init to do the remaining initialisation. However, this\
|
||
|
|
+ * inline function is also called from gs_scan_token to handle inline\
|
||
|
|
+ * ASCII85 strings. These are not to be interpreted using PDF rules\
|
||
|
|
+ * and so we must not set the flag here, but in the relevant calling\
|
||
|
|
+ * functions.\
|
||
|
|
+ */ \
|
||
|
|
(ss)->require_eod=false; \
|
||
|
|
END
|
||
|
|
extern const stream_template s_A85D_template;
|
||
|
|
diff --git a/psi/iscan.c b/psi/iscan.c
|
||
|
|
index e5956e1..9b7151a 100644
|
||
|
|
--- a/psi/iscan.c
|
||
|
|
+++ b/psi/iscan.c
|
||
|
|
@@ -581,6 +581,10 @@ gs_scan_token(i_ctx_t *i_ctx_p, ref * pref, scanner_state * pstate)
|
||
|
|
s_A85D_init_inline(&sstate.s_ss.a85d);
|
||
|
|
sstate.s_ss.st.templat = &s_A85D_template;
|
||
|
|
sstate.s_ss.a85d.require_eod = true;
|
||
|
|
+ /* If this is an inline ASCII string, interpret it normally, throw an error
|
||
|
|
+ * if it fails rather than ignoring it as PDF (Acrobat) does.
|
||
|
|
+ */
|
||
|
|
+ sstate.s_ss.a85d.pdf_rules = false;
|
||
|
|
goto str;
|
||
|
|
}
|
||
|
|
sputback_inline(s, sptr, endptr);
|
||
|
|
--
|
||
|
|
1.8.3.1
|
||
|
|
|