Zip files created by juce assert when being extracted by juce

I think there’s a bug in ZipFile::Builder::Item::writeTimeAndDate in juce_ZipFile.cpp. The seconds value isn’t being divided by 2 before packing into the DOS time format.

The DOS time format stores seconds/2 in a 5-bit field (0-29), but the current code writes t.getSeconds() directly:

target.writeShort ((short) (t.getSeconds() + (t.getMinutes() << 5) + (t.getHours() << 11)));

Should be:

target.writeShort ((short) ((t.getSeconds() >> 1) + (t.getMinutes() << 5) + (t.getHours() << 11)));

Without the >> 1, any seconds value over 31 bleeds into the minutes bits, corrupting both fields. When you read the zip back with parseFileTime, you can end up with seconds of 60 or 62, and the minutes/hours can be wrong too.

The decode side in parseFileTime correctly does (time & 31) << 1, so it’s expecting the halved value — the encode just isn’t providing it.

Easy to reproduce: create a zip with a file whose timestamp has seconds >= 32, then read it back and check the time.

Thanks for reporting, fixed here:

1 Like

ah, amazing! this has been plaguing me since the zip assert stuff went in last year, i thought i was doing something wrong. i ended up adding code to re-read any zip file i made to confirm it wasn’t corrupt… thanks for fixing.