1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-14 03:39:02 +00:00

Handle date formatting for Windows for years earlier than 1970. See #2136

This commit is contained in:
dmiller
2020-10-08 23:09:21 +00:00
parent e3262d33d6
commit 50bef20b92
3 changed files with 32 additions and 39 deletions

View File

@@ -41,6 +41,12 @@ function record_skew(host, timestamp, received)
host.registry.datetime_skew = skew_tab
end
-- Work around Windows error formatting time zones where 1970/1/1 UTC was 1969/12/31
system_time_at_epoch = (
time({year=1970, month=1, day=2, hour=0}) -- local time on 1970/1/2
- 86400 -- minus 1 day = local time at 1970/1/1
- time(date("!*t", 0)) -- minus UTC offset (Windows). On *nix this is 0.
)
-- Find the offset in seconds between local time and UTC. That is, if we
-- interpret a UTC date table as a local date table by passing it to os.time,
-- how much must be added to the resulting integer timestamp to make it
@@ -70,9 +76,14 @@ end
-- <code>
-- date_to_timestamp({year=1970,month=1,day=1,hour=4,min=0,sec=0}, 1*60*60) --> 10800
-- </code>
function date_to_timestamp(date, offset)
function date_to_timestamp(date_t, offset)
local status, tm = pcall(time, date_t)
if not status then
stdnse.debug1("Invalid date for this platform: %s", tm)
return nil
end
offset = offset or 0
return time(date) + utc_offset(time(date)) - offset
return tm + utc_offset(tm) - offset
end
local function format_tz(offset)
@@ -124,15 +135,21 @@ function format_timestamp(t, offset)
local status, result = pcall(date, "!%Y-%m-%dT%H:%M:%S", floor(t + offset))
if not status then
local tmp = floor(t + offset)
local extra_years
local seconds_in_year = 31556926
if tmp > 0xffffffff then
-- Maybe too far in the future?
local seconds_in_year = 31556926
local extra_years = (tmp - 0xffffffff) // seconds_in_year + 1
extra_years = (tmp - 0xffffffff) // seconds_in_year + 1
elseif tmp < system_time_at_epoch then
-- Windows can't display times before the epoch
extra_years = tmp // seconds_in_year
end
if extra_years then
tmp = tmp - extra_years * seconds_in_year
status, result = pcall(date, "!*t", tmp)
if status then
-- seconds_in_year is imprecise, so we truncate to date only
result = format("%d-%02d-%02d", result.year + extra_years, result.month, result.day)
result = format("%d-%02d-%02d?", result.year + extra_years, result.month, result.day)
end
end
end

View File

@@ -824,7 +824,9 @@ end
function convertADTimeStamp(timestamp)
local result = 0
local base_time = tonumber(os.time({year=1601, month=1, day=1, hour=0, minute=0, sec =0}))
-- Windows cannot represent this time, so we pre-calculated it:
-- os.time({year=1601, month=1, day=1, hour=0, minute=0, sec =0})
local base_time = -11644473600
timestamp = tonumber(timestamp)

View File

@@ -106,7 +106,7 @@
local math = require "math"
local match = require "match"
local nmap = require "nmap"
local os = require "os"
local datetime = require "datetime"
local shortport = require "shortport"
local smb = require "smb"
local smbauth = require "smbauth"
@@ -156,6 +156,8 @@ do
end
end
-- This constant is number of seconds from 1900-01-01 to 1970-01-01
local tds_offset_seconds = -2208988800 + datetime.system_time_at_epoch
-- *************************************
-- Informational Classes
@@ -1231,19 +1233,13 @@ ColumnData =
end,
[DataTypes.SYBDATETIME] = function( data, pos )
local hi, lo, result_seconds, result
local tds_epoch, system_epoch, tds_offset_seconds
local hi, lo
hi, lo, pos = string.unpack("<i4I4", data, pos)
tds_epoch = os.time( {year = 1900, month = 1, day = 1, hour = 00, min = 00, sec = 00, isdst = nil} )
-- determine the offset between the tds_epoch and the local system epoch
system_epoch = os.time( os.date("*t", 0))
tds_offset_seconds = os.difftime(tds_epoch,system_epoch)
local result_seconds = (hi*24*60*60) + (lo/300)
result_seconds = (hi*24*60*60) + (lo/300)
result = os.date("!%b %d, %Y %H:%M:%S", tds_offset_seconds + result_seconds )
local result = datetime.format_timestamp(tds_offset_seconds + result_seconds)
return pos, result
end,
@@ -1311,23 +1307,6 @@ ColumnData =
return ColumnData.Parse[DataTypes.DECIMALNTYPE]( precision, scale, data, pos )
end,
[DataTypes.SYBDATETIME] = function( data, pos )
local hi, lo, result_seconds, result
local tds_epoch, system_epoch, tds_offset_seconds
hi, lo, pos = string.unpack("<i4I4", data, pos)
tds_epoch = os.time( {year = 1900, month = 1, day = 1, hour = 00, min = 00, sec = 00, isdst = nil} )
-- determine the offset between the tds_epoch and the local system epoch
system_epoch = os.time( os.date("*t", 0))
tds_offset_seconds = os.difftime(tds_epoch,system_epoch)
result_seconds = (hi*24*60*60) + (lo/300)
result = os.date("!%b %d, %Y %H:%M:%S", tds_offset_seconds + result_seconds )
return pos, result
end,
[DataTypes.BITNTYPE] = function( data, pos )
return ColumnData.Parse[DataTypes.SYBINTN](data, pos)
end,
@@ -1406,13 +1385,8 @@ ColumnData =
local days, mins
days, mins, pos = string.unpack("<I2I2", data, pos)
local tds_epoch = os.time( {year = 1900, month = 1, day = 1, hour = 00, min = 00, sec = 00, isdst = nil} )
-- determine the offset between the tds_epoch and the local system epoch
local system_epoch = os.time( os.date("*t", 0))
local tds_offset_seconds = os.difftime(tds_epoch,system_epoch)
local result_seconds = (days*24*60*60) + (mins*60)
coldata = os.date("!%b %d, %Y %H:%M:%S", tds_offset_seconds + result_seconds )
coldata = datetime.format_timestamp(tds_offset_seconds + result_seconds)
return pos,coldata