Skip to content

fix: parse day and fractional-second components in FromTimeSpan (cherry-pick of #435) - #452

Open
NickJosevski wants to merge 1 commit into
mainfrom
fix/timespan-parsing
Open

fix: parse day and fractional-second components in FromTimeSpan (cherry-pick of #435)#452
NickJosevski wants to merge 1 commit into
mainfrom
fix/timespan-parsing

Conversation

@NickJosevski

Copy link
Copy Markdown
Contributor

Cherry-pick of #435 by @Scott-Emberson, re-hosted on a branch in this repo solely so CI can run. Authorship is preserved on the commit — this is a mechanical move, not a rewrite, and the work and the analysis are entirely Scott's.

Fork PRs cannot satisfy the required test check: integration-tests.yml needs secrets.DB_IMAGE_SA_PASSWORD, OD_IMAGE_ADMIN_API_KEY and OCTOPUS_SERVER_BASE64_LICENSE, and GitHub withholds secrets from pull_request runs originating on a fork, so the job dies at Initialize containers before any Go executes. #435 is red for that reason and no other.

The bug

FromTimeSpan read the day component from timeSpan[0:0] — always the empty string — so every value carrying days parsed to zero. Fixed offsets also assumed a single-digit day, fractional seconds were dropped, and an empty string panicked on a slice bound. It is duplicated verbatim in pkg/machines and pkg/machinepolicies; this fixes both.

Running main's parser against this one on the same inputs:

input correct main today this PR
00:05:00 5m0s 5m0s 5m0s
01:30:00 1h30m0s 1h30m0s 1h30m0s
1.00:00:00 24h0m0s 0s 24h0m0s
7.12:30:00 180h30m0s 12h30m0s 180h30m0s
07.12:30:00 180h30m0s 0s 180h30m0s
10.00:00:00 240h0m0s 0s 240h0m0s
00:00:00.5000000 500ms 0s 500ms
1.02:03:04.5000000 26h3m4.5s 2h3m4s 26h3m4.5s
"" 0s panic 0s

Every day-bearing value was silently wrong rather than failing loudly. Plain hh:mm:ss is identical before and after, so nothing that works today regresses.

Blast radius

Read path only. ToTimeSpan, which produces what gets sent to the server, is untouched. All 14 in-repo callers of FromTimeSpan sit inside UnmarshalJSON on machine policy, cleanup policy and health check policy. It also closes a quiet data-loss path: today you can read a policy, write it back unchanged, and send a day-scale interval out as zero.

Two notes for the release

  1. Negative time spans remain wrong, in both directions — pre-existing, not touched here, and arguably never supported:
    FromTimeSpan("-1.02:03:04") = -21h56m56s   // .NET means -26h3m4s
    FromTimeSpan("-00:05:00")   = 5m0s         // sign dropped entirely
    ToTimeSpan(-26h3m4s)        = "-1.-2:-3:-4"
    
  2. This changes values consumers already read. Anyone getting 0s for these fields starts getting the true duration, which may surface as a one-off Terraform plan on machine policy timeouts. There is no CHANGELOG.md and goreleaser builds notes from commit subjects only, so this needs a note pasted onto the GitHub Release at tag time. Wording is in a comment on fix: parse day and fractional-second components in FromTimeSpan (changes parsed values) #435.

Once this merges

Close #435 pointing here, so Scott gets the credit and knows it wasn't rejected.

FromTimeSpan read the time span fields at fixed offsets and took the day
component from timeSpan[0:0], which is always the empty string. Every value
carrying a day component therefore parsed to zero, including "1.00:00:00" —
the interval on the default machine policy — and any fractional seconds were
dropped. An empty string panicked on a slice bound.

Parse the components by separator instead. The day and fractional-second
parts are both optional, and the server does not pad the day component to a
fixed width, so offsets cannot be assumed. Malformed input now yields a zero
duration rather than a panic.

The existing tests only logged their results and asserted nothing, which is
why this went unnoticed; they now assert, and every case they already covered
was returning zero.

Closes #434

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
(cherry picked from commit 5d7ef5e)
Co-authored-by: Scott Emberson <8268155+Scott-Emberson@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants