From ea52ba9fdc0e221dd758e8792b4ac424ac7f9874 Mon Sep 17 00:00:00 2001 From: Daniel Bertalan Date: Sat, 26 Feb 2022 12:53:02 +0100 Subject: [PATCH] LibC: Set `saved_str` to null in strtok_r if no tokens were found If we do not do this, the next call to strtok_r will start tokenizing (and possibly modifying!) the memory pointed to by `saved_ptr`. --- Tests/LibC/TestLibCString.cpp | 13 +++++++++++++ Userland/Libraries/LibC/string.cpp | 6 ++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/Tests/LibC/TestLibCString.cpp b/Tests/LibC/TestLibCString.cpp index 57ff7056574..a7edc7934dc 100644 --- a/Tests/LibC/TestLibCString.cpp +++ b/Tests/LibC/TestLibCString.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2021, Gunnar Beutner + * Copyright (c) 2022, Daniel Bertalan * * SPDX-License-Identifier: BSD-2-Clause */ @@ -16,3 +17,15 @@ TEST_CASE(strerror_r_basic) EXPECT_EQ(strerror_r(EFAULT, buf, sizeof(buf)), 0); EXPECT_EQ(strcmp(buf, "Bad address"), 0); } + +TEST_CASE(strtok_r_delimiters_only) +{ + char dummy[] = "a;"; + char input[] = ";;;;;;"; + char* saved_str = dummy; + + EXPECT_EQ(strtok_r(input, ";", &saved_str), nullptr); + EXPECT_EQ(strtok_r(nullptr, ";", &saved_str), nullptr); + // The string to which `saved_str` initially points to shouldn't be modified. + EXPECT_EQ(strcmp(dummy, "a;"), 0); +} diff --git a/Userland/Libraries/LibC/string.cpp b/Userland/Libraries/LibC/string.cpp index 20c6bc82942..25495a0a607 100644 --- a/Userland/Libraries/LibC/string.cpp +++ b/Userland/Libraries/LibC/string.cpp @@ -375,7 +375,7 @@ char* strpbrk(const char* s, const char* accept) char* strtok_r(char* str, const char* delim, char** saved_str) { if (!str) { - if (!saved_str) + if (!saved_str || *saved_str == nullptr) return nullptr; str = *saved_str; } @@ -407,8 +407,10 @@ char* strtok_r(char* str, const char* delim, char** saved_str) } } - if (str[token_start] == '\0') + if (str[token_start] == '\0') { + *saved_str = nullptr; return nullptr; + } if (token_end == 0) { *saved_str = nullptr;