Merge pull request #3966 from MarcZX100/codex/carry-strcasecmp-lowered

fix(libc): compare strcasecmp results after lowercasing bytes
This commit is contained in:
Dean 2026-10-13 01:56:24 +13:00 committed by GitHub
commit 4bf963d660
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 24 additions and 12 deletions

View File

@ -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<unsigned char>(std::tolower(static_cast<unsigned char>(*s1)));
unsigned char b = static_cast<unsigned char>(std::tolower(static_cast<unsigned char>(*s2)));
if (a != b) return a - b;
++s1; ++s2;
for (;; ++s1, ++s2) {
const int a = std::tolower(static_cast<unsigned char>(*s1));
const int b = std::tolower(static_cast<unsigned char>(*s2));
if (a != b || *s1 == 0) return a - b;
}
return static_cast<unsigned char>(*s1) - static_cast<unsigned char>(*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<unsigned char>(std::tolower(static_cast<unsigned char>(*s1)));
unsigned char b = static_cast<unsigned char>(std::tolower(static_cast<unsigned char>(*s2)));
for (; n != 0; ++s1, ++s2, --n) {
const int a = std::tolower(static_cast<unsigned char>(*s1));
const int b = std::tolower(static_cast<unsigned char>(*s2));
if (a != b) return a - b;
++s1; ++s2; --n;
if (*s1 == 0) break;
}
if (!n) return 0;
return static_cast<unsigned char>(*s1) - static_cast<unsigned char>(*s2);
return 0;
}
int APS5_VABI bcmp_nid_postfix(const void* s1, const void* s2, size_t n) {

View File

@ -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[] = "";