When iterating on the zip entries (and printing the time stamps) of an old jar/zip files the exception
"java.time.DateTimeException: Invalid value for SecondOfMinute (valid values 0 - 59): 60"
occured (issue has been seen on Windows).
Looks like the dosToJavaTime function in ZipUtils.java of jdk9/jdk10 is a bit more "sensitive"
about the input it gets, compared to jdk8.
In both implementations :
java.base/share/classes/java/util/zip/ZipUtils.java
jdk.zipfs/share/classes/jdk/nio/zipfs/ZipUtils.java
the computation of the "seconds" values is done by
public static long dosToJavaTime(long dtime) {
...
(int) ((dtime << 1) & 0x3e));
...
}
0x3e is binary 111110 or decimal 62, so larger values than the supported maximum 59 can occur
(maybe only with old/problematic archives but still we had such an example).
Example of an exception of the iteration on entries of such an archive :
C:\JVM\openjdk10\bin\java ZipIterate
name of ZipEntry:com/microsoft/sqlserver/jdbc/AppDTVImpl$SetValueOp.class
Exception in thread "main" java.time.DateTimeException: Invalid value for SecondOfMinute (valid values 0 - 59): 60
at java.base/java.time.temporal.ValueRange.checkValidValue(ValueRange.java:311)
at java.base/java.time.temporal.ChronoField.checkValidValue(ChronoField.java:714)
at java.base/java.time.LocalTime.of(LocalTime.java:322)
at java.base/java.time.LocalDateTime.of(LocalDateTime.java:337)
at java.base/java.util.zip.ZipUtils.dosToJavaTime(ZipUtils.java:101)
at java.base/java.util.zip.ZipUtils.extendedDosToJavaTime(ZipUtils.java:114)
at java.base/java.util.zip.ZipEntry.getTime(ZipEntry.java:198)
at ZipIterate.main(ZipIterate.java:37)
A similar problem (dealing with days/months not seconds out of supported range) is described here :
https://bugs.openjdk.java.net/browse/JDK-8184940
"JDK 9 rejects zip files where the modified day or month is 0"
Compared to jdk8, this is a regression so I think it would be good to have a better handling of problematic out of range seconds-values.
One suggestion was to go back to the previous implementation java.util.Date (current java.time based implementation is more strict).