From ebd88fdd621f4dcc7af507fd1339470b96c70a2b Mon Sep 17 00:00:00 2001 From: Paul Clark Date: Tue, 4 Nov 2025 08:31:51 +0000 Subject: [PATCH] Replace strtok with strtok_r --- Firmware/RTK_Everywhere/Display.ino | 9 +++++---- Firmware/RTK_Everywhere/NVM.ino | 12 ++++++++++-- Firmware/RTK_Everywhere/Network.ino | 5 +++-- Firmware/RTK_Everywhere/NtripClient.ino | 5 +++-- Firmware/RTK_Everywhere/NtripServer.ino | 5 +++-- Firmware/RTK_Everywhere/System.ino | 24 ++++++++++++++---------- 6 files changed, 38 insertions(+), 22 deletions(-) diff --git a/Firmware/RTK_Everywhere/Display.ino b/Firmware/RTK_Everywhere/Display.ino index 5790490ea..8de0a1c5e 100644 --- a/Firmware/RTK_Everywhere/Display.ino +++ b/Firmware/RTK_Everywhere/Display.ino @@ -2813,11 +2813,12 @@ void displayMessage(const char *message, uint16_t displayTime) // Count words based on spaces uint8_t wordCount = 0; strncpy(temp, message, sizeof(temp) - 1); // strtok modifies the message so make copy - char *token = strtok(temp, " "); + char *preservedPointer; + char *token = strtok_r(temp, " ", &preservedPointer); while (token != nullptr) { wordCount++; - token = strtok(nullptr, " "); + token = strtok_r(nullptr, " ", &preservedPointer); } uint8_t yPos = (oled->getHeight() / 2) - (fontHeight / 2); @@ -2829,11 +2830,11 @@ void displayMessage(const char *message, uint16_t displayTime) // drawFrame(); strncpy(temp, message, sizeof(temp) - 1); - token = strtok(temp, " "); + token = strtok_r(temp, " ", &preservedPointer); while (token != nullptr) { printTextCenter(token, yPos, QW_FONT_8X16, 1, false); // text, y, font type, kerning, inverted - token = strtok(nullptr, " "); + token = strtok_r(nullptr, " ", &preservedPointer); yPos += fontHeight; } diff --git a/Firmware/RTK_Everywhere/NVM.ino b/Firmware/RTK_Everywhere/NVM.ino index cb819c9e3..c5d6fbc8b 100644 --- a/Firmware/RTK_Everywhere/NVM.ino +++ b/Firmware/RTK_Everywhere/NVM.ino @@ -990,8 +990,16 @@ bool parseLine(char *str) { char *ptr; + // A health warning about strtok: + // strtok will convert any delimiters it finds ("=" in our case) into NULL characters. + // Also, be very careful that you do not use strtok within an strtok while loop. + // The next call of strtok(NULL, ...) in the outer loop will use the pointer saved from the inner loop! + // The same is true for tasks! + // The solution is to use strtok_r - the reentrant version of strtok + // Set strtok start of line. - str = strtok(str, "="); + char *preservedPointer; + str = strtok_r(str, "=", &preservedPointer); if (!str) { log_d("Fail"); @@ -1006,7 +1014,7 @@ bool parseLine(char *str) char settingString[100] = ""; // Move pointer to end of line - str = strtok(nullptr, "\n"); + str = strtok_r(nullptr, "\n", &preservedPointer); if (!str) { // This line does not contain a \n or the settingString is zero length diff --git a/Firmware/RTK_Everywhere/Network.ino b/Firmware/RTK_Everywhere/Network.ino index 8e07b51c4..32a98faa1 100644 --- a/Firmware/RTK_Everywhere/Network.ino +++ b/Firmware/RTK_Everywhere/Network.ino @@ -262,10 +262,11 @@ void menuTcpUdp() // Remove any http:// or https:// prefix from host name // strtok modifies string to be parsed so we create a copy strncpy(hostname, settings.tcpClientHost, sizeof(hostname) - 1); - char *token = strtok(hostname, "//"); + char *preservedPointer; + char *token = strtok_r(hostname, "//", &preservedPointer); if (token != nullptr) { - token = strtok(nullptr, "//"); // Advance to data after // + token = strtok_r(nullptr, "//", &preservedPointer); // Advance to data after // if (token != nullptr) strcpy(settings.tcpClientHost, token); } diff --git a/Firmware/RTK_Everywhere/NtripClient.ino b/Firmware/RTK_Everywhere/NtripClient.ino index 8ef050044..0019f8614 100644 --- a/Firmware/RTK_Everywhere/NtripClient.ino +++ b/Firmware/RTK_Everywhere/NtripClient.ino @@ -216,10 +216,11 @@ bool ntripClientConnect() char hostname[51]; strncpy(hostname, settings.ntripClient_CasterHost, sizeof(hostname) - 1); // strtok modifies string to be parsed so we create a copy - char *token = strtok(hostname, "//"); + char *preservedPointer; + char *token = strtok_r(hostname, "//", &preservedPointer); if (token != nullptr) { - token = strtok(nullptr, "//"); // Advance to data after // + token = strtok_r(nullptr, "//", &preservedPointer); // Advance to data after // if (token != nullptr) strcpy(settings.ntripClient_CasterHost, token); } diff --git a/Firmware/RTK_Everywhere/NtripServer.ino b/Firmware/RTK_Everywhere/NtripServer.ino index 39ffc4ff9..3e30beb1f 100644 --- a/Firmware/RTK_Everywhere/NtripServer.ino +++ b/Firmware/RTK_Everywhere/NtripServer.ino @@ -192,10 +192,11 @@ bool ntripServerConnectCaster(int serverIndex) char hostname[51]; strncpy(hostname, settings.ntripServer_CasterHost[serverIndex], sizeof(hostname) - 1); // strtok modifies string to be parsed so we create a copy - char *token = strtok(hostname, "//"); + char *preservedPointer; + char *token = strtok_r(hostname, "//", &preservedPointer); if (token != nullptr) { - token = strtok(nullptr, "//"); // Advance to data after // + token = strtok_r(nullptr, "//", &preservedPointer); // Advance to data after // if (token != nullptr) strcpy(settings.ntripServer_CasterHost[serverIndex], token); } diff --git a/Firmware/RTK_Everywhere/System.ino b/Firmware/RTK_Everywhere/System.ino index 94f67353c..5a94befe1 100644 --- a/Firmware/RTK_Everywhere/System.ino +++ b/Firmware/RTK_Everywhere/System.ino @@ -585,10 +585,11 @@ CoordinateInputType coordinateIdentifyInputType(const char *userEntryOriginal, d { coordinateInputType = COORDINATE_INPUT_TYPE_DD_MM_DASH; - char *token = strtok(userEntry, "-"); // Modifies the given array + char *preservedPointer; + char *token = strtok_r(userEntry, "-", &preservedPointer); // Modifies the given array // We trust that token points at something because the dashCount is > 0 int decimal = atoi(token); // Get DD - token = strtok(nullptr, "-"); + token = strtok_r(nullptr, "-", &preservedPointer); double minutes = atof(token); // Get MM.mmmmmmm *coordinate = decimal + (minutes / 60.0); if (negativeSign) @@ -598,12 +599,13 @@ CoordinateInputType coordinateIdentifyInputType(const char *userEntryOriginal, d { coordinateInputType = COORDINATE_INPUT_TYPE_DD_MM_SS_DASH; - char *token = strtok(userEntry, "-"); // Modifies the given array + char *preservedPointer; + char *token = strtok_r(userEntry, "-", &preservedPointer); // Modifies the given array // We trust that token points at something because the spaceCount is > 0 int decimal = atoi(token); // Get DD - token = strtok(nullptr, "-"); + token = strtok_r(nullptr, "-", &preservedPointer); int minutes = atoi(token); // Get MM - token = strtok(nullptr, "-"); + token = strtok_r(nullptr, "-", &preservedPointer); // Find '.' char *decimalPtr = strchr(token, '.'); @@ -626,10 +628,11 @@ CoordinateInputType coordinateIdentifyInputType(const char *userEntryOriginal, d { coordinateInputType = COORDINATE_INPUT_TYPE_DD_MM; - char *token = strtok(userEntry, " "); // Modifies the given array + char *preservedPointer; + char *token = strtok_r(userEntry, " ", &preservedPointer); // Modifies the given array // We trust that token points at something because the spaceCount is > 0 int decimal = atoi(token); // Get DD - token = strtok(nullptr, " "); + token = strtok_r(nullptr, " ", &preservedPointer); double minutes = atof(token); // Get MM.mmmmmmm *coordinate = decimal + (minutes / 60.0); if (negativeSign) @@ -639,12 +642,13 @@ CoordinateInputType coordinateIdentifyInputType(const char *userEntryOriginal, d { coordinateInputType = COORDINATE_INPUT_TYPE_DD_MM_SS; - char *token = strtok(userEntry, " "); // Modifies the given array + char *preservedPointer; + char *token = strtok_r(userEntry, " ", &preservedPointer); // Modifies the given array // We trust that token points at something because the spaceCount is > 0 int decimal = atoi(token); // Get DD - token = strtok(nullptr, " "); + token = strtok_r(nullptr, " ", &preservedPointer); int minutes = atoi(token); // Get MM - token = strtok(nullptr, " "); + token = strtok_r(nullptr, " ", &preservedPointer); // Find '.' char *decimalPtr = strchr(token, '.');