From d58e050c8f7f1b02fb982831cce0b39d56820db5 Mon Sep 17 00:00:00 2001 From: JJenkx Date: Fri, 23 Oct 2026 17:06:45 -0400 Subject: [PATCH] fix(libc): return the byte difference from strcoll as titles' libc.prx does strcoll called the host's strcmp, which returns -1, 0 or 1 on Windows. The libc.prx bundled with eleven titles returns, in the C locale, the difference of the unsigned bytes at the first mismatch, as its strcmp does; strcoll now computes that. Co-Authored-By: Claude Opus 5.5 --- core/libs/prx/libc/src/Strings.cpp | 6 +++++- core/libs/tests/GuestStrings.cpp | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/core/libs/prx/libc/src/Strings.cpp b/core/libs/prx/libc/src/Strings.cpp index 18d1df74bc..508da2aa04 100644 --- a/core/libs/prx/libc/src/Strings.cpp +++ b/core/libs/prx/libc/src/Strings.cpp @@ -487,7 +487,11 @@ size_t APS5_VABI strspn_nid_postfix(const char* s, const char* accept) { } int APS5_VABI strcoll_nid_postfix(const char* s1, const char* s2) { - return std::strcmp(s1, s2); + for (;; ++s1, ++s2) { + const int a = static_cast(*s1); + const int b = static_cast(*s2); + if (a != b || a == 0) return a - b; + } } int APS5_VABI strncpy_s_nid_postfix(char* dest, size_t destsz, const char* src, size_t count) { diff --git a/core/libs/tests/GuestStrings.cpp b/core/libs/tests/GuestStrings.cpp index 8debeb251f..257ccc7689 100644 --- a/core/libs/tests/GuestStrings.cpp +++ b/core/libs/tests/GuestStrings.cpp @@ -142,6 +142,8 @@ static void CheckSecureStringSizeLimits() { } static void CheckCaseInsensitiveComparison() { + Require(strcoll_nid_postfix("a", "z") == -25 && strcoll_nid_postfix("z", "a") == 25 && strcoll_nid_postfix("ab", "abc") == -99); + Require(strcoll_nid_postfix("A", "a") == -32 && strcoll_nid_postfix("same", "same") == 0 && strcoll_nid_postfix("\xff", "\x01") == 254); Require(strcasecmp_nid_postfix("", "") == 0 && strcasecmp_nid_postfix("AbC", "aBc") == 0); Require(strcasecmp_nid_postfix("A", "b") == -1 && strcasecmp_nid_postfix("b", "A") == 1); Require(strcasecmp_nid_postfix("ab", "A") == 1 && strcasecmp_nid_postfix("AB", "a") == 1);