diff options
| author | Danilo M. <danix@danix.xyz> | 2026-09-17 09:04:46 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-09-17 09:04:46 +0200 |
| commit | 53d39b7212ffe0753d2b10ea39348bc033f06bef (patch) | |
| tree | be756f5cf2e3d4e1b303b05637924e1224ff2d96 /lib | |
| parent | 752b58b3992d1a9cfb51c891deb77007286415ee (diff) | |
| download | conky-theme-udt-53d39b7212ffe0753d2b10ea39348bc033f06bef.tar.gz conky-theme-udt-53d39b7212ffe0753d2b10ea39348bc033f06bef.zip | |
fix: guard now, and clamp a negative age, in the staleness pair
is_stale and age_str were the only functions in the module doing
arithmetic on an unchecked argument: a nil `now` raised, and a raise in
this project is a blank dashboard with no message. Every caller passes
os.time(), which cannot be nil, so this was unreachable, but it is the
same bug already fixed once in icon() and the module header promises
nothing raises.
age_str also printed a negative age when the observation timestamp was
in the future, which a clock skew can produce. "stale -17m" on the card
reads as a broken widget, so the age now floors at zero and such a
reading counts as fresh: weather from the future is not old.
With this the whole module is raise-free, verified across every function
against nil, string, table, boolean, NaN, negative and zero arguments in
all three positions.
Both cases were found by the Task 5 implementer, which was asked to
probe beyond its given tests and reported them without changing the code.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/weather.lua | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/lib/weather.lua b/lib/weather.lua index b1fda4d..8ecd273 100644 --- a/lib/weather.lua +++ b/lib/weather.lua @@ -189,15 +189,25 @@ end -- Three missed fetches at the 15-minute interval. M.STALE_AFTER = 45 * 60 +-- `now` is guarded alongside `dt` although every caller passes os.time(), +-- which cannot be nil: these were the only two functions in the module that +-- did arithmetic on an unchecked argument, and the module's promise is that +-- nothing raises. A raise here is a blank dashboard. function M.is_stale(dt, now) - if type(dt) ~= 'number' then return true end + if type(dt) ~= 'number' or type(now) ~= 'number' then return true end return (now - dt) > M.STALE_AFTER end -- Short age for the marker beside the city: "12m", "3h", "2d". +-- +-- A negative age is clamped to zero rather than printed. An observation +-- timestamped in the future means a clock skew somewhere, and "stale -17m" on +-- the card reads as a broken widget; treating it as fresh is both tidier and +-- truer, since weather from the future is not old. function M.age_str(dt, now) - if type(dt) ~= 'number' then return '?' end + if type(dt) ~= 'number' or type(now) ~= 'number' then return '?' end local s = now - dt + if s < 0 then s = 0 end if s < 3600 then return math.floor(s / 60) .. 'm' end if s < 86400 then return math.floor(s / 3600) .. 'h' end return math.floor(s / 86400) .. 'd' |
