[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


Please help review the change for #8184306.

issue: https://bugs.openjdk.java.net/browse/JDK-8184306
webrev: http://cr.openjdk.java.net/~sherman/8184306/


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 
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 
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 
should be reset to 0, its initial value as well, inside either 
or lm_init().

I have logged an issue at


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.


More information about the core-libs-dev mailing list