Repository navigation
Conversation
…tf_s, vprintf_s, scanf_s, fscanf_s, vscanf_s, vfscanf_s
Progress report (a6dcea9 → 239dc9b)📈 System libraries: 42.39% (+0.06%, +11 implemented, +1 declared functions) ✅ 11 implemented
🆕 1 declared as stubs
|
MarcZX10
left a comment
There was a problem hiding this comment.
The changed scanner appears to preserve the existing string-scanner behavior while factoring it into the stream source, and the secure output/reopen cases have useful focused coverage. The author-reported Linux CTest filter passes; current eligibility, conventions, intake, labels, report, relinker matrix/ASan, register-context, and write-watch checks pass. Hosted full Linux and Windows product jobs were skipped, and I did not run a local build/test.
Please resolve the overlap order before merge. The live overlap scan reports shared scanner code with #9087 and #7386, the shared test file with #8593, and the debt insertion with #6565, #8872, #8880, #9001, #9087, #9133, #9170, #9447, and #9526; several older conflicted-base PR comparisons also require manual review. The body acknowledges #9087's same ScanGuest/FormatSecure hunk and says whichever lands second will rebase, but the checklist currently says Depends on: none. Please coordinate the shared-file order with the affected authors, record the agreed prerequisite(s) in Depends on, and rebase/resolve the overlap before merge. This request is for the repository's required overlap coordination, not a claim that the new functions duplicate another PR.
|
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.
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.
|
harisibrar1
left a comment
There was a problem hiding this comment.
Checked against main 4a17c71, C11 n1570 K.3.5.2.2 and the ps5-payload-dev/sdk libSceLibcInternal stubs:
- All twelve exports are in the sdk stub list, and the NIDs match. The SysV varargs entry points use
__builtin_sysv_va_*andAPS5_VA_BEGINon Windows, asfprintfandscanfdo. I traced the newfscanf_sstream cases by hand and the expected values hold. freopen_s(FileAndHeap.cpp:398) returnsEINVALfor a nullfilename. But K.3.5.2.2 lists onlynewstreamptr,modeandstreamas runtime constraints, and says that with a nullfilenamethe call "attempts to change the mode of the stream". Sofreopen_s(&r, NULL, "rb", f)should not fail as a constraint violation.- Plain
freopenon main already reports that case as unsupported (errno 45,FileAndHeap.cpp:312). Couldfreopen_spass the null name through tofreopen, so that the existing gap shows instead of a constraint failure? The test atGuestFopenErrors.cpp:105and the debt line (libc.md:139, "follows C11 K.3.5.2.2") would need the same change. If the console's Dinkumware does reject a null name, a citation in the debt entry would settle it.
Reviewed with AI assistance (Claude Code); the checks above were run locally on my machine.
What
Adds twelve C11 Annex K functions that libSceLibcInternal exports (PS5 3.20 inventory) and that exist nowhere on
main:fprintf_s,vfprintf_s,vprintf_s,fwprintf_s,wprintf_s,vfwprintf_s,vwprintf_s,scanf_s,fscanf_s,vscanf_s,vfscanf_sandfreopen_s. SDK headers steer code to the_sforms, so a title built with them imports these. No title is named here; the change is generic. They sit beside their siblings and reuse the formatting and scanning engines of the unchecked and_sfunctions already onmain.Printf side (
Formatting.cpp,FormattingWide.cpp):vfprintf_s,fprintf_sandvprintf_sformat withFormatWindows(..., secure = true), the enginesnprintf_suses, and write the finished text to the stream in onefwrite. A null stream, format or argument list, any%n, and a null%s,%lsor%Sargument return -1 and write nothing. A closed stream setsEBADFasfprintfdoes.vprintf_swrites to the guest standard output stream.vfwprintf_s,fwprintf_s,vwprintf_sandwprintf_sdo the same throughFormatWide(..., secure = true), the engine ofswprintf_sandsnwprintf_s, and return the number of wide characters likevfwprintf.Scanf side (
Formatting.cpp):ScanGuest, the scanner behindsscanf_s, read its input as a NUL-terminated string. It now takes its input through a smallStringSource/StreamSourcepair (peek, skip, advance, scan one directive) and the body is shared:ScanGuestkeeps its signature and behaviour for strings, andScanGuestStreamruns the same scanner over aFileStreamby reading each directive with the hostfscanfand one character of look-ahead pushed back. So the size rules ofsscanf_s(size after the pointer for%s,%c,%[, asunsigned int; an undersized destination gets a null first element and returns the count so far; a null destination returnsEOF) apply unchanged, and the stream stops after the last character a conversion used.vfscanf_sis the entry;fscanf_s,scanf_sandvscanf_scall it (scanf_sandvscanf_sread the guest standard input stream, asscanfandvscanfdo). A null stream or format returnsEOF; a closed stream setsEBADFand returnsEOF. The 16-bit wide conversions throw on Linux in the stream forms, exactly as infscanf.freopen_s(FileAndHeap.cpp) returnsEINVAL(22) for a null result, name, mode or stream (and sets*resultto null when it can); otherwise it callsfreopen, stores the stream in*resultand returns 0, or stores null and returns the errno of the failed reopen.Constraint handling is the one
mainhas for the siblings: a violation only returns, the installed constraint handler is not called (seesnprintf_s,fopen_s,sscanf_sand their debt entries). The result values for the stream forms were not measured on a PS5; they are recorded as such indocs/dev/debt/libc.md(three new entries).RSIZE_MAXis not touched (#9360, #8965).Relation to #9087 (open, "follow snprintf_s and sscanf_s constraints as measured on a PS5"): it rewrites
ScanGuestandFormatSecurein the same file (handler calls, the -23 result,size_tsizes). This PR is based onmainand does not depend on it; whichever lands second needs a mechanical rebase of theScanGuesthunk, after which the new stream functions should call the handler the way #9087 does for their siblings. The values #9087 measured are forsnprintf_sandsscanf_sonly, so I did not copy them to the stream functions.Tests extend
GuestStdioVariadic.cpp(registered asguest_stdio_variadic) andGuestFopenErrors.cpp(guest_fopen_errors); no new target.Tested
guest_stdio_variadic|guest_fopen_errors|guest_scan_count|guest_formatting|guest_strings|guest_wide_formatting|guest_wide_stream_scan|guest_bounds_checking|guest_standard_streams*|file_streams): 12 of 12 passed, among themguest_stdio_variadic,guest_fopen_errors,guest_scan_count,guest_formattingandguest_strings, the existing tests of the scanner I changed. Not run on Windows or macOS (the Windows paths use the same__builtin_sysv_va_listpattern asfprintfandscanf, and compile only there).guest_stdio_variadichas new cases with expected values worked out by hand:fprintf_sandvfprintf_swrite the same 16 bytes asfprintffor"%d|%s|%5.2f|%c|%ls"(42|ab| 3.14|z|é);fwprintf_sandvfwprintf_scount 10 wide characters for"%05d:%ls|"and write00042:été|;vprintf_sreturns 14,wprintf_s12,vwprintf_s13; every violation (%n, null%s/%ls, null format, null stream) returns -1 with nothing written and the%ntarget untouched, andsnprintf_sis called with the same arguments as the reference;fscanf_s/vfscanf_sread%d %s %cwith sizes 6 and 1, continue from the stream position, leave the character that ended a number in the stream (12abcthena), read%3[a-z]=%7s, handle%*f%n(count 5), return 0 for an undersized%swith a null first element likesscanf_s,EOFat the end of the file, andEOFfor a null destination, format and stream;scanf_sandvscanf_sread a tmpfile swapped in as the guest standard input. A closed stream makesfprintf_s,fwprintf_sandfscanf_ssetEBADF.guest_fopen_errorshas a newCheckedReopencase: null result returnsEINVAL; null name, mode and stream, and an invalid mode, returnEINVALwith*resultnull; a reopen ontoreopened.txtreturns 0 with*result == streamand creates the file;loopreturnsELOOP(62) andmissing.txtENOENT(2), each with*resultnull.errnoof the stream forms on a violation, and whether the console's default constraint handler runs for them. The three debt entries say so.python3 tools/check_conventions.py --base origin/mainpasses. Based on a6dcea9.tools/pr_overlap.pyreports no PR with the same exports. It lists fix(libc): follow snprintf_s and sscanf_s constraints as measured on a PS5 #9087 and feat(libc): scan 16-bit wide conversions on Linux #7386 (ScanGuest,Formatting.cpplines 121 to 167 onmain), feat(libc): implement _Vacopy #8593 (GuestStdioVariadic.cppline 18), and fix(libc): leave a range that a mutation waits for out of new leases #6565, feat(libc): implement siginterrupt through the sigaction libkernel registers #8872, feat(libc): export the num_get and time_get locale objects as data #8880, test(libc): cover siginterrupt state boundaries #9001, feat(libSceLibcInternal): implement posix_spawn process creation and reaping #9133, fix(libc): return the calling thread from _Thrd_id as the console's libc.prx does #9170 and feat(libc): add the std::__sce_v2 thread start, timed wait, clock and processor count calls #9447 (the append position at the end ofdocs/dev/debt/libc.md); it could not compare fix(libc): follow measured wide printf behavior #5303 (FormattingWide.cpp), fix(libs): share Sony CRT handler and lconv state between libc and libSceAmpr #7081 and Macos port #7201 (FileAndHeap.cpp), and fix(windows): enter guest startup on an arena-backed main stack #3965, feat(aot): consolidate native ARM64 compiler, runtime and consumers #5021, fix(memory): honor low guest mapping hints #6469, feat(wasm): run relinked titles in the browser with WebGPU #6879, feat(libc): implement std::_Throw_C_error #7648, fix(libc): provide ASOBI_ROOT environment variable for title path resolution #7715, fix(libc): support character reads from random device streams #8150 and fix(libc): use the Annex K size limit and codes of the PS5 libc, as measured on a PS5 #8965 (docs/dev/debt/libc.md) because they conflict withmain. Neighbours that touch the area without these names: docs(libc): correct the RSIZE_MAX that swprintf_s and vswprintf_s assume #9360, fix(libc): match reported wide scanf edge cases #9331, feat(libc): decode non-ASCII scanset members and non-BMP characters in the guest wide scanf #9340, fix(libc): use the Annex K size limit and codes of the PS5 libc, as measured on a PS5 #8965.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)