Repository navigation
Conversation
The sscanf_s of titles' libc.prx (PPSA07923 and PPSA05916 agree) reads a %d, %i, %o, %u, %x or %X with no length, h or hh as a 64-bit value and keeps its low bits: %x of 61439ebdf stores 0x1439ebdf and leaves errno alone. ScanSource handed the directive to the host at the destination's width, which saturated to 0xffffffff and set ERANGE. It now scans those conversions into a 64-bit temporary and stores the low bytes, as the plain Windows sscanf path already does. Out of 64-bit range the host still saturates with ERANGE, as the titles do. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MarcZX10
left a comment
There was a problem hiding this comment.
Reviewed exact head 0b3eb0b3e53a8faa1f01fd01a6de4061247ab308. For unsuppressed integer conversions with no length, h, or hh, the change scans through a 64-bit temporary and copies only the destination-width low bytes, avoiding the host-width saturation observed for narrower destinations. The tests cover %x, %hx, %hhX, and preservation of the preexisting errno value; the PR also supplies paired title-libc comparisons across 200,000 conversions. Windows, conventions, policy, Ubuntu relinker/register-context and ASan checks pass. Linux is skipped and macOS jobs are pending; the PR description clearly records that host limitation and the remaining >64-bit overflow behavior.
|
Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.
|
|
Linux validation completed for exact clean head Arch Linux 7.2.9-arch1-1, c++ (GCC) 16.2.1 20260810, glibc 2.44. Built the actual patched A separate plain-glibc probe already truncates the three narrow-integer examples and preserves the existing errno. This establishes Linux compatibility; it does not reproduce the Windows host saturation bug. I did not rerun the Windows author's 200,000 title-libc comparisons. Build/test logs, JUnit, exact-source and patched-library hashes, and host probe (SHA-256 |
|
A Windows run with GCC 16: Windows 11 Pro 10.0.22631, i9-9900K, MSYS2 UCRT64 GCC 16.1.0, Release, this PR (
AI-assisted: yes (Claude Code) |
What
sscanf_s(and the other_sscanners that go throughScanSource:vsscanf_s,fscanf_s,vfscanf_s,scanf_s,vscanf_s) handed a narrow integer conversion to the host at the destination's width. On an out-of-range value the host saturates and setsERANGE. Titles' ownlibc.prx(PPSA07923 and PPSA05916 agree) instead reads the field as a 64-bit value and keeps its low bits, leavingerrnoalone:61439ebdf%x0x1439ebdf,errnounchanged0xffffffff,ERANGE9c747bca9c%x0x747bca9c0xffffffff,ERANGE-eb371ade9%hx0x52170xffff,ERANGE867259ccd%hhX0xcd0xff,ERANGEPlain
sscanfon Windows already does this:ScanWindowsArgumentsscans narrow integers aslland truncates.ScanSourcenow does the same for%d,%i,%o,%u,%xand%Xwith no length,horhh: it scans into a 64-bit temporary and stores the destination's low bytes. Past 64 bits the host still saturates withERANGE, as the titles do (%dof99999999999999999999setsERANGEin both).Tested
Windows 11 Enterprise 10.0.22621, Ryzen 9 5950X, WinLibs GCC 15.2.0 UCRT r7, Ninja, Release,
BUILD_TESTING=ON, onmain6793a72475.libc.prx: I loaded PPSA07923's and PPSA05916'slibc.prxnatively and called theirsscanf_s(24m4Z4bUaoY) side by side with this build. It covered 200,000 random numeric conversions:d i u o x X f e g a, every length, random widths, and inputs drawn from digits, hex letters, signs,.,x,e,p,inf/nanletters and spaces. I compared the result, the stored bytes,%nanderrno.main21 → 0, on both titles;0xwith no hex digit (78, where the titles fail the conversion);%f/hex%aerrno(37, where the titles leaveerrno);long doubleNaN's upper bytes.guest_formatting(three new rows),guest_stdio_variadic,guest_scan_count,guest_wide_stream_scanandguest_wide_formattingpass in each of 3 runs.main'sFormatting.cpp,guest_formattingfails.Not tested on Linux or macOS.
ScanSourceis the same code there, so Linuxsscanf_snow also scans these conversions as 64-bit and truncates. I haven't measured what glibc did with them before.Overlap:
tools/pr_overlap.pyfinds no shared lines: the 14 pull requests touching these files merge cleanly with this one. #5021, #7386, #10324 and #11332 conflict withmainand couldn't be compared.Independent Windows validation reported by bunbeans2-arch for topic
0b3eb0b3e53a8faa1f01fd01a6de4061247ab308merged into main409fe64199: Windows 11 Pro 22631, i9-9900K, MSYS2 UCRT64 GCC 16.1, Release.guest_formattingpasses 5/5; retaining this PR's tests while restoringFormatting.cppto main fails 5/5; plain main with its own source/tests passes 3/3. This is the contributor's run, not a new local Windows execution.Independent reports on this head (their runs, summarised here):
0b3eb0b3e5merged intomain409fe64199:guest_formattingpasses 5/5; withFormatting.cppfrommainit fails 5/5.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)🤖 Generated with Claude Code