Mark,

On 10/12/20 09:50, Mark Thomas wrote:
> On 12/10/2020 13:53, Mark Thomas wrote:
>> On 12/10/2020 12:49, Mark Thomas wrote:
>>> On 12/10/2020 12:19, Peter Henderson wrote:
>>>> Hello fellow tomcat users.
>>>>
>>>> My environment.
>>>> Tomcat: 9.0.39
>>>> Java: openjdk 11.0.8 2020-07-14
>>>> OS: Ubuntu 18.04.5 LTS
>>>>
>>>> Source code [0]
>>>>
>>>> When deploying this war [1], by copying it into the webapps directory,
>>>> I get this exception. [2]
>>>> java.lang.IllegalArgumentException: Negative time
>>>>
>>>>
>>>> I only started seeing this exception when I upgraded my projects build tool
>>>> version
>>>> from
>>>> sbt.version=1.3.10
>>>> to
>>>> sbt.version=1.4.0
>>>>
>>>>
>>>> Is this a tomcat bug, a build tool bug or most likely something I'm doing
>>>> wrong?
>>>
>>> Looks like an issue with the dates of files in the WAR.
>>>
>>> If you look at the dates of the files in the WAR nearly all of them are
>>> in the future (07 Feb 2106, 06:28).
>>>
>>> It looks like something is overflowing but a Java long shouldn't do that.
>>>
>>> Need to dig into exactly what is going on as this looks like it should
>>> work - even if the WAR contains files created almost a century in the
>>> future.
>>
>> Hmm. I see the 2106 date on the file system and with Java 8 but with
>> Java 11 I see 1969-dec-31 23:00 which gives -3600000 which triggers the
>> exception.
>>
>> The root cause appears to be in the JRE at this point. Whether it is in
>> the JRE used to create the WAR or the JRE reading the WAR is TBD.
>>
>> I think I am going to have to look at the raw bytes and the zip file
>> spec to figure out where the root cause is.
> 
> That was fun.
> 
> Per the zip spec, the last modified time on those files is:
> 
> 1969-Dec-31 23:00:00 UTC
> 
> i.e. 1 hour before the Epoch at 1970-Jan-01 00:00:00 UTC
> 
> It is stored as a signed 32-bit int (FFFFF1F0) which is -3600 (zip
> timestamps are in seconds since the Epoch).
> 
> Java 8 reads this incorrectly as an unsigned int (4294963696) which,
> when taken as seconds since Epoch, gives 2016-Feb-07 05:28:16 UTC.

Underflow! :(

> (Incidently the archiver that ships with Ubuntu appears to make the same
> error)
> 
> Java 11 reads this correctly but Java does not let you set times before
> the Epoch so the exception is triggered.
> 
> The short version is that the modification times of the files in the WAR
> are being set to "1969-Dec-31 23:00:00 UTC" which Java doesn't like.
> 
> Tomcat could handle this more gracefully but the end result will be the
> same - the WAR isn't going to deploy. I'm not convinced it is worth
> doing anything here.
> 
> It looks like the fix will be somewhere in the build system used to
> create the WAR.

There is already a check for -1 for the last-modified time for the file
in the ZIP archive. Also for 0 for some reason (sorry, Brian Kernighan,
you can't store your first file in a ZIP file!).

I think that any negative value should be ignored, so the expanded-file
on the disk should get "now" as its last-updated time. So just change
the comparison to:

  if(lastModified > 0) {
    expandedFile.setLastModified(lastModified);
  }

-chris

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to