Decompress stream to account for different possible encodings (closes: #51)

Recompressing the image stream makes the comparison robust against output
preserving changes in the zlib compress output bitstream
(e.g. between different zlib implementations/versions/releases).
Without this, some img2pdf 0.3.2 tests fail on Fedora 29/aarch64.
See also:
#51
https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org/thread/R7GD4L5Z6HELCDAL2RDESWR2F3ZXHWVX/
This commit is contained in:
Georg Sauthoff 2018-12-24 18:09:43 +01:00 committed by Johannes 'josch' Schauer
parent 0639dbd47c
commit 2faeb2005d
Signed by: josch
GPG key ID: F2CBA5C78FBD83E1

View file

@ -17,6 +17,51 @@ if PY3:
else: else:
PdfReaderIO = BytesIO PdfReaderIO = BytesIO
# Recompressing the image stream makes the comparison robust against output
# preserving changes in the zlib compress output bitstream
# (e.g. between different zlib implementations/versions/releases).
# Without this, some img2pdf 0.3.2 tests fail on Fedora 29/aarch64.
# See also:
# https://gitlab.mister-muffin.de/josch/img2pdf/issues/51
# https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org/thread/R7GD4L5Z6HELCDAL2RDESWR2F3ZXHWVX/
def recompress_last_stream(bs):
length_pos = bs.rindex(b'/Length')
li = length_pos + 8
lj = bs.index(b' ', li)
n = int(bs[li:lj])
stream_pos = bs.index(b'\nstream\n', lj)
si = stream_pos + 8
sj = si + n
startx_pos = bs.rindex(b'\nstartxref\n')
xi = startx_pos + 11
xj = bs.index(b'\n', xi)
m = int(bs[xi:xj])
unc_t = zlib.decompress(bs[si:sj])
t = zlib.compress(unc_t)
new_len = str(len(t)).encode('ascii')
u = (lj-li) + n
v = len(new_len) + len(t)
off = v - u
rs = (bs[:li] + new_len + bs[lj:si] + t + bs[sj:xi]
+ str(m+off).encode('ascii') + bs[xj:])
return rs
def compare_pdf(outx, outy):
if b'/FlateDecode' in outx:
x = recompress_last_stream(outx)
y = recompress_last_stream(outy)
if x != y:
print('original outx:\n{}\nouty:\n{}\n'.format(outx, outy), file=sys.stderr)
print('recompressed outx:\n{}\nouty:\n{}\n'.format(x, y), file=sys.stderr)
return False
else:
if outx != outy:
print('original outx:\n{}\nouty:\n{}\n'.format(outx, outy), file=sys.stderr)
return True
# convert +set date:create +set date:modify -define png:exclude-chunk=time # convert +set date:create +set date:modify -define png:exclude-chunk=time
@ -669,7 +714,7 @@ def test_suite():
ywriter.trailer = y ywriter.trailer = y
xwriter.write(outx) xwriter.write(outx)
ywriter.write(outy) ywriter.write(outy)
self.assertEqual(outx.getvalue(), outy.getvalue()) self.assertEqual(compare_pdf(outx.getvalue(), outy.getvalue()), True)
# the python-pil version 2.3.0-1ubuntu3 in Ubuntu does not have the # the python-pil version 2.3.0-1ubuntu3 in Ubuntu does not have the
# close() method # close() method
try: try: