[9] JDK-8184306: zlib 1.2.11 upgrade triggers j.u.zip.Deflater regression
Xueming Shen
xueming.shen at oracle.com
Wed Jul 12 23:06:02 UTC 2017
Hi,
Please help review the change for #8184306.
issue: https://bugs.openjdk.java.net/browse/JDK-8184306
webrev: http://cr.openjdk.java.net/~sherman/8184306/
Background:
It appears the basic compression functionality of j.u.Deflater is
broken when
(1) the deflater's compression level/strategy is changed (to new value) AND
(2) reset()
which is a normal combination/use scenario when the deflater is being cached
and reused.
My reading of the 1.2.11 changes suggests the root cause is that the
internal
state "deflate_state.high_water" is not being reset
correctly/appropriately (to 0?)
in deflateReset/deflateResetKeep/lm_init().
AND the change of one of the conditions in deflate.c/deflateParams(), from
"strm->total_in!=0" to "s->high_water" (in the "Flush last buffer"
branch) as showed
below, obvious triggers the regression from 1.2.8 to 1.2.11, in the
scenario that
the "strategy/levle is changed" AND a followup "reset()" is called (with the
assumption that everything should be reset back to initial state and we
start a
new compression circle, with the new level and strategy. This is how it
works
in 1.2.8 and early releases).
from (1.2.8's)
if ((strategy != s->strategy || func != configuration_table[level].func) &&
strm->total_in != 0) { <----------------
/* Flush the last buffer: */
err = deflate(strm, Z_BLOCK);
if (err == Z_BUF_ERROR && s->pending == 0)
err = Z_OK;
}
to (1.2.11's)
if ((strategy != s->strategy || func != configuration_table[level].func) &&
s->high_water) { <-----------------
/* Flush the last buffer: */
int err = deflate(strm, Z_BLOCK);
if (err == Z_STREAM_ERROR)
return err;
if (strm->avail_out == 0)
return Z_BUF_ERROR;
}
With this change (in 1.2.11), now if there is any compression operation that
leaves the "s->high_water" > 0, even after the "reset()" has been
called, the
next compression/deflateParam() will always "try to flush the last
buffer" with
the old state, which appears to be wrong.
Given the nature of "reset" it appears reasonable to assume the
"high_water"
should be reset to 0, its initial value as well, inside either
deflateResetKeep()
or lm_init().
I have logged an issue at
https://github.com/madler/zlib/issues/275
Jdk9 has been changed to use the system zlib for all platforms except the
windows, this one currently only fails on windows. But I would assume if the
underlying zlib is 1.2.11, the deflater/compression will be broken as well.
Have not verified this yet. Anyone has a zlib 1.2.11 installed and
trying jdk9
on it (on a non-Windows system) ?
Instead of backout the 1.2.11 completely and reset back to 1.2.8, here I'm
proposing to add the suggested one-line change to "fix" this issue for
now and
waiting for any official fix from zlib. The change seems easy and safe
for me.
It does fix the failure we are experiencing now.
Thanks,
Sherman
More information about the core-libs-dev
mailing list