Skip to content

fix(libc): follow measured wide printf behavior - #5303

Open
MarcZX10 wants to merge 7 commits into
boykopovar:mainfrom
MarcZX10:codex/wide-printf-extensions-5293
Open

MarcZX10 wants to merge 7 commits into
boykopovar:mainfrom
MarcZX10:codex/wide-printf-extensions-5293

Conversation

@MarcZX10

@MarcZX10 MarcZX10 commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

What

Updates non-secure guest wide printf formatting to match the measured literal-text behavior for %q, %D/%O/%U, unknown conversions, and width handling observed from libSceLibcInternal.sprx on firmware 12.70. The probe called swprintf from a payload process; it did not exercise a title or its bundled libc.prx, whose Dinkumware _Printf behavior remains unverified. The probe also showed that a trailing % read past the format terminator, so incomplete conversions continue to fail safely. The secure snwprintf_s path continues to reject these forms because its console behavior was not measured.

The original implementation commits retain Hussein Kadhim as author, and the original test commits retain MarcZX100. The review follow-up is authored by MarcZX10.

Tested

  • Rebased all six commits onto current upstream main at 661f8b71718083fbac1c45b44f5d67dc39cb4624, preserving their original authorship. The debt-file conflict was resolved by retaining unrelated current-main entries and the PR's measured-versus-extrapolated distinction.
  • On the rebased head, python3 tools/check_conventions.py --base upstream/main --head HEAD and git diff --check upstream/main...HEAD pass.
  • The prior head 06bd246798 built guest_wide_formatting_tests and passed ctest -R guest_wide_formatting --output-on-failure (1/1). That runtime test was not rerun after the current-main rebase.
  • No title libc.prx runtime test, Windows build or full test suite was run.

Checklist

  • Based on current main; no other open PR implements the same wide-format functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw; silent stubs are listed under technical debt
  • No notes, investigation .md files or images added to the repository
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • Unblocks: none
  • GPUs tested: n/a
  • AI-assisted: yes

@oneandonlydean

Copy link
Copy Markdown
Collaborator

Which title prints %q, %D/%O/%U, an unknown conversion or a trailing % through the wide printf family? The source here is FreeBSD 11.4, but the console's libc.prx formats through Dinkumware's _Printf, which can handle unknown conversions and q differently (same question as the review on #3987). Until a title reaches it, or _Printf in a title's libc.prx confirms these cases, main's throw is the safer behaviour.

@MarcZX10

Copy link
Copy Markdown
Contributor Author

I do not have title traces or Dinkumware _Printf evidence for these wide-format cases. The current evidence is FreeBSD 11.4 behavior and Linux-side tests, so I cannot claim console compatibility for %q, %D/%O/%U, unknown conversions, or a trailing %. I agree this leaves the added behavior unverified against the console; absent title or _Printf evidence, main’s throw is safer. I will avoid presenting these cases as title-required until we have that evidence.

@adriadam10 adriadam10 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for the fix. Blocking points:

  • The console's libc.prx formats through Dinkumware's _Printf, not FreeBSD's vfwprintf. As discussed above, neither a title nor _Printf evidence shows that %q, %D/%O/%U, unknown conversions (with width) or a trailing % behave as FreeBSD 11.4 does there; main's throw is the safe behaviour until then. Evidence that would unblock it: the relevant branches of _Printf disassembled from a title's libc.prx (same approach as in #3987), or a title that reaches these cases.
  • Once evidence exists, the branch conflicts with main in core/libs/tests/GuestWideFormatting.cpp; it needs a rebase.

@github-actions

github-actions Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.

Pull request Conflicting files (lines on main) Same exports Same new files
PR 7386 docs/dev/debt/libc.md L143-144
PR 9340 docs/dev/debt/libc.md L143-144
PR 9364 docs/dev/debt/libc.md L143

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.

Pull request Shared files not compared
PR 3965 docs/dev/debt/libc.md
PR 5021 docs/dev/debt/libc.md
PR 7544 docs/dev/debt/libc.md
PR 7715 docs/dev/debt/libc.md
PR 8150 docs/dev/debt/libc.md
PR 8417 docs/dev/debt/libc.md
PR 9133 docs/dev/debt/libc.md
PR 9170 docs/dev/debt/libc.md
PR 9371 docs/dev/debt/libc.md
PR 9447 docs/dev/debt/libc.md
PR 9526 docs/dev/debt/libc.md
PR 9527 core/libs/prx/libc/src/FormattingWide.cpp
docs/dev/debt/libc.md
PR 9552 docs/dev/debt/libc.md
PR 9669 docs/dev/debt/libc.md
PR 9863 docs/dev/debt/libc.md
PR 9873 docs/dev/debt/libc.md
PR 9929 docs/dev/debt/libc.md

@MarcZX10

Copy link
Copy Markdown
Contributor Author

Thanks for the firmware 12.70 payload report. The current PR head already follows the measured literal handling for the reported non-secure wide swprintf cases and explicitly limits its claim to libSceLibcInternal.sprx, not a title’s bundled libc.prx. Your trailing-percent probe shows an out-of-bounds read, so it does not support a deterministic output; the implementation continues to reject an incomplete conversion. I found no additional code change justified by this report. The open title _Printf evidence/rebase review point remains as stated in the latest review.

@MarcZX10
MarcZX10 force-pushed the codex/wide-printf-extensions-5293 branch from ca0fc05 to f52d991 Compare October 20, 2026 08:33
@MarcZX10

Copy link
Copy Markdown
Contributor Author

Rebased the six existing commits onto current upstream main 661f8b71718083fbac1c45b44f5d67dc39cb4624, preserving their original authors. The debt-file conflict retained current-main entries and the PR’s distinction between measured and extrapolated payload behavior. Conventions and git diff --check pass on new head f52d991a2d; the focused Linux 1/1 formatting test passed on the prior head 06bd246798 and has not been rerun after this rebase. No claim is made for title libc.prx behavior or Windows/full-suite validation.

@MarcZX10

Copy link
Copy Markdown
Contributor Author

Final hosted check update for head f52d991a2df498e341d0ccd7620c80588f97f73d: the Windows relinker CTest has completed successfully. All relinker, register-context, write-watch, ASan, conventions, labels, eligibility and report checks passed. Linux and Windows AGC jobs remain skipped by the PR workflow policy. The focused guest_wide_formatting test has still not been rerun after the rebase.

@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 20, 2026
@adriadam10
adriadam10 force-pushed the codex/wide-printf-extensions-5293 branch from f52d991 to f36936b Compare October 20, 2026 08:56
@MarcZX10

Copy link
Copy Markdown
Contributor Author

I compared the previously tested head 06bd246798 with the current PR head f36936b1edbcd1b660a998dfe08680faea458de1: FormattingWide.cpp and GuestWideFormatting.cpp are byte-for-byte unchanged. The only difference among those paths is the debt documentation. So the focused test result from 06bd246798 still covers the current implementation and test source; I did not rerun the executable after the rebase.

@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 21, 2026
@Felipebmaitan Felipebmaitan mentioned this pull request Oct 21, 2026
12 tasks done
husseinkad and others added 7 commits October 24, 2026 16:50
…t in the wide printf family

The wide printf family rejected the q length modifier, the D, O and U conversions, unknown conversion characters and a format ending in a percent sign, which FreeBSD 11.4 vfwprintf formats: q is long long, D, O and U are the long forms of d, o and u, an unknown conversion character prints itself with the width and the - flag, and the format ends at a trailing percent sign. swprintf, vswprintf and wprintf now do the same; snwprintf_s keeps rejecting them.
…te pair whole as an unknown conversion

snwprintf_s accepted the q length modifier through the shared parser and now rejects it again. An unknown conversion character that is a surrogate pair is printed as one character, so the width padding no longer splits the pair.
…he rebase re-added

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@MarcZX10
MarcZX10 force-pushed the codex/wide-printf-extensions-5293 branch from f36936b to 6d5d378 Compare October 24, 2026 16:53
@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 24, 2026

This branch has not been deployed

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants