diff --git a/core/libs/prx/libc/src/Strings.cpp b/core/libs/prx/libc/src/Strings.cpp index 564458ace..4b8732386 100644 --- a/core/libs/prx/libc/src/Strings.cpp +++ b/core/libs/prx/libc/src/Strings.cpp @@ -221,24 +221,21 @@ char16_t* APS5_VABI wmemmove_nid_postfix(char16_t* dest, const char16_t* src, si extern "C" { int APS5_VABI strcasecmp_nid_postfix(const char* s1, const char* s2) { - while (*s1 && *s2) { - unsigned char a = static_cast(std::tolower(static_cast(*s1))); - unsigned char b = static_cast(std::tolower(static_cast(*s2))); - if (a != b) return a - b; - ++s1; ++s2; + for (;; ++s1, ++s2) { + const int a = std::tolower(static_cast(*s1)); + const int b = std::tolower(static_cast(*s2)); + if (a != b || *s1 == 0) return a - b; } - return static_cast(*s1) - static_cast(*s2); } int APS5_VABI strncasecmp_nid_postfix(const char* s1, const char* s2, size_t n) { - while (n && *s1 && *s2) { - unsigned char a = static_cast(std::tolower(static_cast(*s1))); - unsigned char b = static_cast(std::tolower(static_cast(*s2))); + for (; n != 0; ++s1, ++s2, --n) { + const int a = std::tolower(static_cast(*s1)); + const int b = std::tolower(static_cast(*s2)); if (a != b) return a - b; - ++s1; ++s2; --n; + if (*s1 == 0) break; } - if (!n) return 0; - return static_cast(*s1) - static_cast(*s2); + return 0; } int APS5_VABI bcmp_nid_postfix(const void* s1, const void* s2, size_t n) { diff --git a/core/libs/tests/GuestStrings.cpp b/core/libs/tests/GuestStrings.cpp index 4ae9225c7..ec0b4f01d 100644 --- a/core/libs/tests/GuestStrings.cpp +++ b/core/libs/tests/GuestStrings.cpp @@ -11,6 +11,8 @@ char* APS5_VABI basename_nid_postfix(const char*); char* APS5_VABI __inet_ntoa_nid_postfix(unsigned int); char* APS5_VABI dirname_nid_postfix(const char*); int* APS5_VABI __error_nid_postfix(); +int APS5_VABI strcasecmp_nid_postfix(const char*, const char*); +int APS5_VABI strncasecmp_nid_postfix(const char*, const char*, std::size_t); std::size_t APS5_VABI strnlen_nid_postfix(const char*, std::size_t); std::size_t APS5_VABI strnlen_s_nid_postfix(const char*, std::size_t); char* APS5_VABI strncat_nid_postfix(char*, const char*, std::size_t); @@ -98,6 +100,18 @@ static void CheckBoundsCheckedFunctions() { Require(snprintf_s_nid_postfix(formatted, sizeof(formatted), "%d-%s", 42, "x") == 4 && std::strcmp(formatted, "42-x") == 0); } +static void CheckCaseInsensitiveComparison() { + Require(strcasecmp_nid_postfix("", "") == 0 && strcasecmp_nid_postfix("AbC", "aBc") == 0); + Require(strcasecmp_nid_postfix("A", "b") == 'a' - 'b' && strcasecmp_nid_postfix("b", "A") == 'b' - 'a'); + Require(strcasecmp_nid_postfix("ab", "A") == 'b' && strcasecmp_nid_postfix("AB", "a") == 'b'); + Require(strcasecmp_nid_postfix("A", "aB") == -'b' && strcasecmp_nid_postfix("a", "AB") == -'b'); + Require(strcasecmp_nid_postfix("", "Z") == -'z' && strcasecmp_nid_postfix("Z", "") == 'z'); + Require(strncasecmp_nid_postfix("abc", "ABD", 2) == 0 && strncasecmp_nid_postfix("abc", "ABD", 3) == 'c' - 'd'); + Require(strncasecmp_nid_postfix("Ab", "a", 2) == 'b' && strncasecmp_nid_postfix("a", "AB", 5) == -'b'); + Require(strncasecmp_nid_postfix("Q", "", 1) == 'q' && strncasecmp_nid_postfix("", "Q", 1) == -'q'); + Require(strncasecmp_nid_postfix("x", "y", 0) == 0 && strncasecmp_nid_postfix("same", "SAME", 99) == 0); +} + static void CheckSscanfS() { #ifndef _WIN32 int number = 0; @@ -166,6 +180,7 @@ static bool CheckDirnameLengths() { int main() { if (!CheckDirnameLengths()) return 1; CheckBoundsCheckedFunctions(); + CheckCaseInsensitiveComparison(); CheckSscanfS(); Require(std::strcmp(dirname_nid_postfix(nullptr), ".") == 0); char emptyPath[] = "";