8188869: jdk9/10 reject zip/jar files where seconds value of timestamp is out of supported range 0 - 59

Reviewed-by: sherman, alanb
This commit is contained in:
Claes Redestad 2017-10-12 16:00:29 +02:00
parent 874060c138
commit 81b7f75837
4 changed files with 78 additions and 43 deletions

View file

@ -28,9 +28,11 @@ package java.util.zip;
import java.nio.file.attribute.FileTime;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.time.DateTimeException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import static java.util.zip.ZipConstants.ENDHDR;
@ -78,31 +80,39 @@ class ZipUtils {
}
/**
/*
* Converts DOS time to Java time (number of milliseconds since epoch).
*/
public static long dosToJavaTime(long dtime) {
int year;
int month;
int day;
int year = (int) (((dtime >> 25) & 0x7f) + 1980);
int month = (int) ((dtime >> 21) & 0x0f);
int day = (int) ((dtime >> 16) & 0x1f);
int hour = (int) ((dtime >> 11) & 0x1f);
int minute = (int) ((dtime >> 5) & 0x3f);
int second = (int) ((dtime << 1) & 0x3e);
if ((dtime >> 16) == 0) {
// Interpret the 0 DOS date as 1979-11-30 for compatibility with
// other implementations.
year = 1979;
month = 11;
day = 30;
} else {
year = (int) (((dtime >> 25) & 0x7f) + 1980);
month = (int) ((dtime >> 21) & 0x0f);
day = (int) ((dtime >> 16) & 0x1f);
if (month > 0 && month < 13 && day > 0 && hour < 24 && minute < 60 && second < 60) {
try {
LocalDateTime ldt = LocalDateTime.of(year, month, day, hour, minute, second);
return TimeUnit.MILLISECONDS.convert(ldt.toEpochSecond(
ZoneId.systemDefault().getRules().getOffset(ldt)), TimeUnit.SECONDS);
} catch (DateTimeException dte) {
// ignore
}
}
LocalDateTime ldt = LocalDateTime.of(year, month, day, hour, minute, second);
return TimeUnit.MILLISECONDS.convert(ldt.toEpochSecond(
ZoneId.systemDefault().getRules().getOffset(ldt)), TimeUnit.SECONDS);
return overflowDosToJavaTime(year, month, day, hour, minute, second);
}
/*
* Deal with corner cases where an arguably mal-formed DOS time is used
*/
@SuppressWarnings("deprecation") // Use of Date constructor
private static long overflowDosToJavaTime(int year, int month, int day,
int hour, int minute, int second) {
return new Date(year - 1900, month - 1, day, hour, minute, second).getTime();
}
/**
* Converts extended DOS time to Java time, where up to 1999 milliseconds
* might be encoded into the upper half of the returned long.