Merge pull request #4625 from QRMOE/fix-libc-strtok-exhausted-state

fix(libc): clear exhausted strtok continuation state
This commit is contained in:
Adrià 2026-10-13 16:59:43 +02:00 committed by GitHub
commit fffe7351ad
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 23 additions and 1 deletions

View File

@ -127,11 +127,12 @@ char* APS5_VABI strtok_r_nid_postfix(char* text, const char* delimiters, char**
if (text == nullptr) return nullptr;
text += std::strspn(text, delimiters);
if (*text == '\0') {
*state = text;
*state = nullptr;
return nullptr;
}
char* end = text + std::strcspn(text, delimiters);
if (*end != '\0') *end++ = '\0';
else end = nullptr;
*state = end;
return text;
}

View File

@ -342,11 +342,32 @@ int main() {
char* firstState = nullptr;
char* secondState = nullptr;
Require(std::strcmp(strtok_r_nid_postfix(first, ",", &firstState), "a") == 0);
Require(firstState == first + 3);
Require(std::strcmp(strtok_r_nid_postfix(second, ":", &secondState), "x") == 0);
Require(secondState == second + 2);
Require(std::strcmp(strtok_r_nid_postfix(nullptr, ",", &firstState), "b") == 0);
Require(firstState == first + 6);
Require(strtok_r_nid_postfix(nullptr, ",", &firstState) == nullptr);
if (firstState != nullptr) std::fputs("strtok_r retained the state after exhausting delimiters\n", stderr);
Require(firstState == nullptr);
Require(strtok_r_nid_postfix(nullptr, ",", &firstState) == nullptr);
Require(std::strcmp(strtok_r_nid_postfix(nullptr, "", &secondState), "y") == 0);
Require(secondState == nullptr);
char tokenEnd[8] = "last";
char* finishedState = first;
*__error_nid_postfix() = 77;
Require(strtok_r_nid_postfix(tokenEnd, ",", &finishedState) == tokenEnd && finishedState == nullptr);
tokenEnd[4] = 'x';
tokenEnd[5] = '\0';
Require(strtok_r_nid_postfix(nullptr, ",", &finishedState) == nullptr && finishedState == nullptr);
for (const char* input : {"", ",", ",,,"}) {
char noTokens[8];
std::strcpy(noTokens, input);
finishedState = first;
Require(strtok_r_nid_postfix(noTokens, ",", &finishedState) == nullptr && finishedState == nullptr);
Require(strtok_r_nid_postfix(nullptr, ",", &finishedState) == nullptr);
}
Require(*__error_nid_postfix() == 77);
char hostTokens[] = "host:next";
Require(std::strcmp(std::strtok(hostTokens, ":"), "host") == 0);
char guestTokens[] = ",one,,two:three";