Skip to content

common/snprintf.c: preserve wide integer values - #3598

Open
user01010111 wants to merge 3 commits into
networkupstools:masterfrom
user01010111:fix/snprintf-llp64-width
Open

common/snprintf.c: preserve wide integer values#3598
user01010111 wants to merge 3 commits into
networkupstools:masterfrom
user01010111:fix/snprintf-llp64-width

Conversation

@user01010111

@user01010111 user01010111 commented Aug 31, 2026

Copy link
Copy Markdown

Summary

  • Carry integer magnitudes as unsigned LLONG through the fallback formatter, with signedness tracked separately.
  • Retrieve %o, %u, %x and %X arguments directly into unsigned storage instead of passing them through a possibly narrower signed long.
  • Convert %p through size_t before widening, avoiding pointer sign extension on conventional 32-bit and LLP64 targets.
  • Retain unsigned negation for negative signed values so LLONG_MIN is handled without signed overflow.
  • Extend TEST_SNPRINTF with focused UINT_MAX, ULONG_MAX, ULLONG_MAX, top-bit hexadecimal and full-width octal comparisons.

Fixes #1602

Review follow-up

Wider ABI testing prompted by review found that the previous PR head regressed the narrow unsigned conversions on systems where long is narrower than long long. On native Windows LLP64, %u with UINT_MAX was widened through negative long and printed as 18446744073709551615; the %o, %x, %X and corresponding unsigned long cases failed in the same way.

Casting later inside fmtint() cannot repair a value already changed by the earlier signed conversion. This revision instead keeps unsigned values unsigned from va_arg() through digit conversion. For signed decimal formats, the caller supplies the converted unsigned value and its sign separately; fmtint() negates only the unsigned value when producing the magnitude. Plain -value is not used because it overflows for LLONG_MIN.

Validation

  • Native Windows 11 x64, MSYS2 MinGW64 GCC 16.2.0 Rev3, LLP64:
    • exact PR head failed 8 of 13 focused integer/pointer comparisons;
    • the revised source passed all 13;
    • the expanded built-in comparison passed 196/196;
    • a native forced-fallback configure confirmed snprintf and vsnprintf unavailable and HAVE_LONG_LONG_INT=1;
    • make -C common V=1 snprintf.lo passed with GNU99, -pedantic and -Werror, producing a PE x86-64 object.
  • Native Linux ILP32 GCC:
    • exact PR head failed nine focused cases and emitted -Wpointer-to-int-cast;
    • the revised source passed 13/13 and the built-in comparison passed 196/196.
  • Native Linux LP64:
    • focused and built-in comparisons passed with GCC 16.2.1 and Clang 22.1.8;
    • GNU89 and strict C99/pedantic builds passed with warnings as errors;
    • Clang UBSan passed, including LLONG_MIN.
  • Forced-fallback project object builds passed with GCC and Clang.
  • make stylecheck, the non-ASCII source check and git diff --check passed.
  • -Wconversion -Wsign-conversion still reports 11 pre-existing diagnostics in this legacy file; this revision removes the additional signed-to-unsigned diagnostic introduced by the previous PR head and adds none.

No upstream CI result is claimed for this revision until it is published.

General C checklist

  • Integer widths and signedness are carried explicitly without assuming long matches pointers or long long.
  • The change follows the existing fallback implementation and in-file test placement; no new helper, dependency or file is introduced.
  • Coding style and whitespace follow common/snprintf.c and docs/developers.txt precedent.
  • No build, distribution or documentation list needs updating.

AI assistance

OpenAI Codex gpt-5.6-sol with xhigh reasoning was used for repository analysis, implementation, review, drafting and local/native validation. Anthropic Claude Fable 5 (claude-fable-5) with xhigh reasoning performed an independent adversarial review and produced a prototype used as design evidence. The human contributor reviewed the complete diff and validation evidence and remains responsible for the contribution.

Keep fallback integer formatting at LLONG width. This prevents pointers
and long-long values from being truncated through long on LLP64 systems.

Handle the signed minimum without overflow and extend TEST_SNPRINTF with
pointer and long-long regression comparisons.

Fixes networkupstools#1602

AI assistance: OpenAI Codex gpt-5.6-sol was used for repository analysis,
implementation, review, drafting and validation. The human contributor
reviewed the change and remains responsible for it.

Signed-off-by: user01010111 <lapses.50.booster@icloud.com>
@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown

A ZIP file with standard source tarball and another tarball with pre-built docs for commit 9d8e1f6 is temporarily available: NUT-tarballs-PR-3598.zip.

@user01010111

Copy link
Copy Markdown
Author

The CentOS 8/ppc64le OBS failure occurs during RPM database initialisation, before %prep or any source compilation:

BDB0091 DB_VERSION_MISMATCH: Database environment version mismatch

CentOS 9/ppc64le builds this commit successfully. Could the CentOS 8/ppc64le preinstall image (a0769ebbc600e42fa9742d61cacaedd7) be refreshed before rerunning the target?

@AppVeyorBot

Copy link
Copy Markdown

Build nut 2.8.5.5161-master completed (commit ee81f6e695 by @)

@AppVeyorBot

Copy link
Copy Markdown

Build nut 2.8.5.5161-master completed (commit ee81f6e695 by @)

@jimklimov

Copy link
Copy Markdown
Member

OBS scenarios are on Open Build System, following their dependency tree etc. - as often as they regenerate them. I gather there is a regular inability to start the (emulated?) builders for this platform, which is mostly worked around by persistent restarting of the build in their Web-UI...

@jimklimov jimklimov added Windows portability We want NUT to build and run everywhere possible C-str Issues and PRs about C/C++ methods, headers and data types dealing with strings and memory blocks AI For good or bad, machine tools are upon us. Humans are still the responsible ones. impacts-release-2.8.5 Issues reported against NUT release 2.8.5 (maybe vanilla or with minor packaging tweaks) labels Aug 31, 2026
@jimklimov jimklimov added this to the 2.8.6 milestone Aug 31, 2026

@jimklimov jimklimov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the signed number support got broken here, the rest seems OK, thanks.

Comment thread common/snprintf.c
Document why fmtint negates the unsigned magnitude when formatting
negative values, including LLONG_MIN.

AI assistance: OpenAI Codex gpt-5.6-sol was used for repository analysis,
implementation, review, drafting and validation. The human contributor
reviewed the change and remains responsible for it.

Signed-off-by: user01010111 <lapses.50.booster@icloud.com>
Comment thread common/snprintf.c Outdated
Carry unsigned format arguments in unsigned LLONG from dopr() through
fmtint(), rather than converting them through a possibly narrower signed
long. Track negativity separately for signed decimal values and keep the
magnitude negation in unsigned arithmetic so LLONG_MIN remains defined.

Convert pointers through size_t before widening, and extend the built-in
comparisons with narrow and wide unsigned extrema.

AI assistance: OpenAI Codex gpt-5.6-sol with xhigh reasoning was used for
repository analysis, implementation, review, drafting and validation.
Anthropic Claude Fable 5 (claude-fable-5) with xhigh reasoning performed
an independent adversarial review and produced a prototype used as design
evidence. The human contributor reviewed the change and remains responsible
for it.

Signed-off-by: user01010111 <lapses.50.booster@icloud.com>
@AppVeyorBot

Copy link
Copy Markdown

@AppVeyorBot

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI For good or bad, machine tools are upon us. Humans are still the responsible ones. C-str Issues and PRs about C/C++ methods, headers and data types dealing with strings and memory blocks impacts-release-2.8.5 Issues reported against NUT release 2.8.5 (maybe vanilla or with minor packaging tweaks) portability We want NUT to build and run everywhere possible Windows

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fallback snprintf.c emits a warning if built

3 participants