Skip to content

fix: parse signed hex and octal integers#2749

Open
StressTestor wants to merge 1 commit into
mikefarah:masterfrom
StressTestor:fix/2748-signed-hex-octal-parse
Open

fix: parse signed hex and octal integers#2749
StressTestor wants to merge 1 commit into
mikefarah:masterfrom
StressTestor:fix/2748-signed-hex-octal-parse

Conversation

@StressTestor

Copy link
Copy Markdown

Generated by an AI agent (Claude Code) acting on the user's behalf, not the user personally.

Fixes #2748.

the problem

a + or - sign before a hex or octal int makes yq error instead of producing the number:

$ yq -o=json <<<'+0x12'
Error: json: error calling MarshalJSON for type *yqlib.CandidateNode: strconv.ParseInt: parsing "+0x12": invalid syntax

the value is tagged !!int but parseInt64 (pkg/yqlib/lib.go) checks the 0x/0o prefix against the whole string. a leading sign means the prefix doesn't match, so it falls through to a base-10 ParseInt of "+0x12", which fails. it hits +0x12, -0x12, +0o22, -0o22.

the fix

peel an optional leading +/- off, detect the prefix on the remainder, and parse sign + digits with the right base. ParseInt accepts the sign for any base, so +0x12 becomes ParseInt("+12", 16, 64) = 18, -0x12 = -18. the base-10 fallback is unchanged (it already handled signs).

scope

format strings are left as-is (0x%X / 0o%o). switching to %#x would lowercase hex digits and regress the uppercase-hex output that operator_value_test.go and toml_test.go rely on (0x1A, 0xDEADBEEF). one consequence: a negative hex/octal value used in arithmetic still renders with the sign inside the prefix (-0x12 -> 0x-12), but that is pre-existing behaviour (yq '0x10 - 0x30' already yields 0x-20 on master) and the JSON path in this issue discards the format string, so the reported bug is fully fixed. tightening that render is a separate change.

tests

  • parseInt64Scenarios gains the signed-positive cases (+0x12 -> 18, +0o22 -> 18), which also round-trip cleanly through the format string.
  • four encode scenarios in json_test.go cover the issue's exact path (yaml in, json out) for both signs and both bases: +0x12/-0x12 -> 18/-18, +0o22/-0o22 -> 18/-18.

both fail on master and pass with the fix. go test ./..., go vet, gofmt -s, and scripts/spelling.sh are clean; the changed files are lint-clean under the CI-pinned golangci-lint.

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.

Backtrace error with hexadecimal value preceded by a sign

1 participant