Commit 7b9f23a99a1ea3e97eaecf80ef29e2805e351b8f
1 parent
fa76d817
Ignore zlib data check errors (fixes #191)
Showing
3 changed files
with
17 additions
and
3 deletions
ChangeLog
| 1 | +2018-03-03 Jay Berkenbilt <ejb@ql.org> | ||
| 2 | + | ||
| 3 | + * Ignore zlib data check errors while uncompressing streams. This | ||
| 4 | + is consistent with behaviors of other readers and enables handling | ||
| 5 | + of some incorrectly written zlib strems. Fixes #191. | ||
| 6 | + | ||
| 1 | 2018-02-25 Jay Berkenbilt <ejb@ql.org> | 7 | 2018-02-25 Jay Berkenbilt <ejb@ql.org> |
| 2 | 8 | ||
| 3 | * 8.0.0: release | 9 | * 8.0.0: release |
libqpdf/Pl_Flate.cc
| 1 | #include <qpdf/Pl_Flate.hh> | 1 | #include <qpdf/Pl_Flate.hh> |
| 2 | #include <zlib.h> | 2 | #include <zlib.h> |
| 3 | +#include <string.h> | ||
| 3 | 4 | ||
| 4 | #include <qpdf/QUtil.hh> | 5 | #include <qpdf/QUtil.hh> |
| 5 | 6 | ||
| @@ -71,7 +72,8 @@ Pl_Flate::write(unsigned char* data, size_t len) | @@ -71,7 +72,8 @@ Pl_Flate::write(unsigned char* data, size_t len) | ||
| 71 | while (bytes_left > 0) | 72 | while (bytes_left > 0) |
| 72 | { | 73 | { |
| 73 | size_t bytes = (bytes_left >= max_bytes ? max_bytes : bytes_left); | 74 | size_t bytes = (bytes_left >= max_bytes ? max_bytes : bytes_left); |
| 74 | - handleData(buf, bytes, Z_NO_FLUSH); | 75 | + handleData(buf, bytes, |
| 76 | + (action == a_inflate ? Z_SYNC_FLUSH : Z_NO_FLUSH)); | ||
| 75 | bytes_left -= bytes; | 77 | bytes_left -= bytes; |
| 76 | buf += bytes; | 78 | buf += bytes; |
| 77 | } | 79 | } |
| @@ -125,6 +127,14 @@ Pl_Flate::handleData(unsigned char* data, int len, int flush) | @@ -125,6 +127,14 @@ Pl_Flate::handleData(unsigned char* data, int len, int flush) | ||
| 125 | { | 127 | { |
| 126 | err = inflate(&zstream, flush); | 128 | err = inflate(&zstream, flush); |
| 127 | } | 129 | } |
| 130 | + if ((action == a_inflate) && (err != Z_OK) && zstream.msg && | ||
| 131 | + (strcmp(zstream.msg, "incorrect data check") == 0)) | ||
| 132 | + { | ||
| 133 | + // Other PDF readers ignore this specific error. Combining | ||
| 134 | + // this with Z_SYNC_FLUSH enables qpdf to handle some | ||
| 135 | + // broken zlib streams without losing data. | ||
| 136 | + err = Z_STREAM_END; | ||
| 137 | + } | ||
| 128 | switch (err) | 138 | switch (err) |
| 129 | { | 139 | { |
| 130 | case Z_BUF_ERROR: | 140 | case Z_BUF_ERROR: |
qpdf/qtest/qpdf/issue-106.out
| 1 | WARNING: issue-106.pdf: file is damaged | 1 | WARNING: issue-106.pdf: file is damaged |
| 2 | WARNING: issue-106.pdf (offset 809): xref not found | 2 | WARNING: issue-106.pdf (offset 809): xref not found |
| 3 | WARNING: issue-106.pdf: Attempting to reconstruct cross-reference table | 3 | WARNING: issue-106.pdf: Attempting to reconstruct cross-reference table |
| 4 | -WARNING: issue-106.pdf (offset 965): error decoding stream data for object 8 0: stream inflate: inflate: data: incorrect data check | ||
| 5 | -WARNING: issue-106.pdf (offset 965): stream will be re-processed without filtering to avoid data loss | ||
| 6 | qpdf: operation succeeded with warnings; resulting file may have some problems | 4 | qpdf: operation succeeded with warnings; resulting file may have some problems |