Skip to content

fix(printf): validate numeric conversion arguments like bash - #683

Merged
brianjfox merged 1 commit into
mainfrom
fix/printf-numeric-validation
Aug 20, 2026
Merged

fix(printf): validate numeric conversion arguments like bash#683
brianjfox merged 1 commit into
mainfrom
fix/printf-numeric-validation

Conversation

@brianjfox

Copy link
Copy Markdown
Owner

Summary

Fixes #680. The %d/%i, %o/%u/%x/%X and float branches parsed arguments with bare strtol/strtod and ignored errors, silently accepting printf '%d' GNU. They now match bash's getintmax/getuintmax/getfloatmax:

  • unconverted/partial argument → S: invalid number, prints the converted prefix (12abc → 12, GNU/'' → 0), exit 1, processing continues (POSIX)
  • out-of-range → S: Result too large (strerror(ERANGE)), prints the clamped value
  • a missing argument stays a silent 0 — only a present-but-empty string diagnoses
  • signed conversions parse/format through long long (bash uses intmax_t), unsigned through unsigned long long (%u takes the full uintmax range; -1 wraps silently)
  • floats gain the leading '/" character-code form (printf '%.2f' "'s"115.00)

Verification

Byte-identical vs reference bash 5.3.15 on 26 cases (invalid/partial/empty/missing args, ±intmax overflow, uintmax wrap, hex/octal self-detection, char codes, float ERANGE→inf). printf.tests scoreboard 66 → 49; builtins/errors/varenv/arith hold at 0; smoke passes.

Closes #680

🤖 Generated with Claude Code

The %d/%i, %o/%u/%x/%X and float branches parsed their argument with a
bare strtol/strtod and printed whatever came back, silently accepting
`printf '%d' GNU' (issue #680).  Match bash's getintmax/getuintmax/
getfloatmax:

- a partially or wholly unconverted argument diagnoses `S: invalid
  number' but still prints the converted prefix (`12abc' is 12, `GNU'
  and `\'\'' are 0), status 1, processing continues (POSIX)
- a well-formed value out of range diagnoses `S: Result too large'
  (strerror(ERANGE)) and prints the clamped value
- a MISSING argument is a silent 0 -- only a present-but-empty string
  diagnoses
- signed conversions now parse and format through long long (bash uses
  intmax_t), unsigned through unsigned long long, so `%u' takes the
  full uintmax range and `-1' wraps with no error
- float conversions gain the leading '/" character-code form
  (`%.2f "'s"' is 115.00)

Verified byte-identical with bash 5.3.15 on 26 cases; printf.tests
scoreboard 66 -> 49, builtins/errors/varenv/arith hold at 0.

Closes #680
@brianjfox
brianjfox merged commit 7c2b9c6 into main Aug 20, 2026
1 check passed
@brianjfox
brianjfox deleted the fix/printf-numeric-validation branch August 20, 2026 07:48
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.

printf: numeric conversions accept any argument silently

1 participant