Skip to content

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

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

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

Conversation

@user01010111

Copy link
Copy Markdown

Summary

  • Preserve fallback integer formatting at LLONG width.
  • Prevent %p and %ll* values from being truncated through long on LLP64 systems.
  • Handle LLONG_MIN without signed overflow.
  • Add focused TEST_SNPRINTF comparisons for pointers, wide %lld values and LLONG_MIN.

Fixes #1602

Validation

  • Native Windows 11 x64, MSYS2 MinGW64 GCC 16.2.0, LLP64:
    • the upstream fallback fails under -std=c99 -Wall -Werror
    • the candidate compiles warning-clean
    • the old formatter fails exactly the three added %p, wide %lld and LLONG_MIN regression cases
    • the candidate passes all 191 TEST_SNPRINTF comparisons
  • Native Windows Autotools integration:
    • snprintf and vsnprintf were forced unavailable through configure
    • make -C common V=1 snprintf.lo passes under -Werror
  • Native GCC 16.2.1 and Clang 22.1.8: 191/191 comparisons passed.
  • GCC UBSan: 191/191 comparisons passed.
  • make stylecheck, the non-ASCII source check and git diff --check passed.

General C checklist

  • Integer widths and value ranges are handled explicitly rather than assuming long matches pointer or long-long width.
  • Direct printf and sprintf declarations remain isolated to the existing TEST_SNPRINTF harness; production logging behaviour is unchanged.
  • Coding style and whitespace follow common/snprintf.c and docs/developers.txt precedent.
  • No files were added, so no build or distribution lists need updating.

AI assistance

OpenAI Codex gpt-5.6-sol was used for repository analysis, implementation, review, drafting and native/local validation. The human contributor reviewed the complete diff and validation evidence and remains responsible for the change.

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 17548a3 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
if( value < 0 ) {
signvalue = '-';
uvalue = -value;
uvalue = -uvalue;

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.

This one change does not look right.

@user01010111 user01010111 Sep 1, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thanks, Jim. This is intentional unsigned arithmetic. After the negative LLONG value is converted to the corresponding unsigned type, C defines unary minus modulo 2^N, so this produces its magnitude without overflowing for LLONG_MIN. Using -value here would be undefined for LLONG_MIN. The added %lld comparison for LLONG_MIN exercises this path and passed against the system formatter.

Happy to add a short explanatory comment if that would make the intent clearer?

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 yes, to avoid same questions later on. "Bits magic, not maths magic" :)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thanks, Jim. Fair point: unsigned negation in shared formatting code is unusual enough to deserve scrutiny. I've added a short comment so future readers do not have to reconstruct the modulo arithmetic to see why it is intentional.

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
if (max < 0)
max = 0;

uvalue = value;

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.

Still, I wonder how many platforms actually build this fallback implementations.

From experience with annoying compiler warnings, I'd actually expect this one with neither range-checks nor explicit casting to raise questions from static analysis.

Wouldn't it be clearer somewhat like this?

if (flags & DP_F_UNSIGNED) {
    uvalue = (unsigned LLONG)value;
} else {
    if (value < 0) {
        signvalue = '-';
        uvalue = -value;
    } else {
        uvalue = value;
        if (flags & DP_F_PLUS)  /* Do a sign (+/i) */
            signvalue = '+';
        else
            if (flags & DP_F_SPACE)
                signvalue = ' ';
    }
}

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