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

Xueming Shen xueming.shen at oracle.com
Mon Oct 9 16:22:07 UTC 2017


+1,

for 8u/9u we will have to deal with it without any new apis from java.time.

i would assume exception-catch is now fast enough that will not add any
extra measurable burden here.

can some arithmetic calculations + if-else make the cost smaller? not sure
though.

jshell> ((month - 1) | (12- month) | (day - 1) | (31-day) | (24 - hr) | 
(59 - min) | (59 - sec)) < 0
$10 ==> false

-sherman

On 10/9/17, 8:26 AM, Claes Redestad wrote:
>
>>
>> Another option would be to add a method `ofLenient(...)` to
>> `LocalDate`, `LocalTime`, `LocalDateTime` etc, as the problem is a
>> generally applicable one.
>
> This might be the best option, long-term.
>
> I was fiddling a bit with the idea of outlining odd cases, but since
> the DOS format allows all manner of odd dates that a sane date
> library deals with exceptionally(!) then I guess the best we could
> do to maintain performance for the common cases now is
> something like:
>
>     /**
>      * Converts DOS time to Java time (number of milliseconds since 
> epoch).
>      */
>     public static long dosToJavaTime(long dtime) {
>         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);
>
>         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) {
>             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();
>     }
>
> /Claes



More information about the core-libs-dev mailing list