From 37f4ceff857b8f1e0d4e2fa69cb63ca5275947df Mon Sep 17 00:00:00 2001 From: Scott Powell Date: Sat, 22 Feb 2025 19:41:24 +1100 Subject: [PATCH] * strncpy() refactor/fix --- examples/simple_repeater/main.cpp | 13 +++++-------- examples/simple_room_server/main.cpp | 21 +++++++-------------- examples/simple_secure_chat/main.cpp | 3 +-- src/helpers/BaseChatMesh.cpp | 3 +-- src/helpers/TxtDataHelpers.cpp | 9 +++++++++ src/helpers/TxtDataHelpers.h | 5 +++++ 6 files changed, 28 insertions(+), 26 deletions(-) create mode 100644 src/helpers/TxtDataHelpers.cpp diff --git a/examples/simple_repeater/main.cpp b/examples/simple_repeater/main.cpp index ed3d9b25..a0497760 100644 --- a/examples/simple_repeater/main.cpp +++ b/examples/simple_repeater/main.cpp @@ -497,11 +497,11 @@ public: _prefs.airtime_factor = 1.0; // one half _prefs.rx_delay_base = 0.0f; // turn off by default, was 10.0; _prefs.tx_delay_factor = 0.5f; // was 0.25f - strncpy(_prefs.node_name, ADVERT_NAME, sizeof(_prefs.node_name)-1); + StrHelper::strncpy(_prefs.node_name, ADVERT_NAME, sizeof(_prefs.node_name)); _prefs.node_name[sizeof(_prefs.node_name)-1] = 0; // truncate if necessary _prefs.node_lat = ADVERT_LAT; _prefs.node_lon = ADVERT_LON; - strncpy(_prefs.password, ADMIN_PASSWORD, sizeof(_prefs.password)-1); + StrHelper::strncpy(_prefs.password, ADMIN_PASSWORD, sizeof(_prefs.password)); _prefs.password[sizeof(_prefs.password)-1] = 0; // truncate if necessary _prefs.freq = LORA_FREQ; _prefs.tx_power_dbm = LORA_TX_POWER; @@ -598,8 +598,7 @@ public: } } else if (memcmp(command, "password ", 9) == 0) { // change admin password - strncpy(_prefs.password, &command[9], sizeof(_prefs.password)-1); - _prefs.password[sizeof(_prefs.password)-1] = 0; // truncate if necesary + StrHelper::strncpy(_prefs.password, &command[9], sizeof(_prefs.password)); checkAdvertInterval(); savePrefs(); sprintf(reply, "password now: %s", _prefs.password); // echo back just to let admin know for sure!! @@ -622,13 +621,11 @@ public: strcpy(reply, "OK"); } } else if (memcmp(config, "guest.password ", 15) == 0) { - strncpy(_prefs.guest_password, &config[15], sizeof(_prefs.guest_password)-1); - _prefs.guest_password[sizeof(_prefs.guest_password)-1] = 0; // truncate if necessary + StrHelper::strncpy(_prefs.guest_password, &config[15], sizeof(_prefs.guest_password)); savePrefs(); strcpy(reply, "OK"); } else if (memcmp(config, "name ", 5) == 0) { - strncpy(_prefs.node_name, &config[5], sizeof(_prefs.node_name)-1); - _prefs.node_name[sizeof(_prefs.node_name)-1] = 0; // truncate if nec + StrHelper::strncpy(_prefs.node_name, &config[5], sizeof(_prefs.node_name)); checkAdvertInterval(); savePrefs(); strcpy(reply, "OK"); diff --git a/examples/simple_room_server/main.cpp b/examples/simple_room_server/main.cpp index 5e6c15cb..0010024a 100644 --- a/examples/simple_room_server/main.cpp +++ b/examples/simple_room_server/main.cpp @@ -197,8 +197,7 @@ class MyMesh : public mesh::Mesh { void addPost(ClientInfo* client, const char* postData) { // TODO: suggested postData format: /<descrption> posts[next_post_idx].author = client->id; // add to cyclic queue - strncpy(posts[next_post_idx].text, postData, MAX_POST_TEXT_LEN); - posts[next_post_idx].text[MAX_POST_TEXT_LEN] = 0; + StrHelper::strncpy(posts[next_post_idx].text, postData, MAX_POST_TEXT_LEN); posts[next_post_idx].post_timestamp = getRTCClock()->getCurrentTimeUnique(); next_post_idx = (next_post_idx + 1) % MAX_UNSYNCED_POSTS; @@ -540,19 +539,16 @@ public: _prefs.airtime_factor = 1.0; // one half _prefs.rx_delay_base = 0.0f; // off by default, was 10.0 _prefs.tx_delay_factor = 0.5f; // was 0.25f; - strncpy(_prefs.node_name, ADVERT_NAME, sizeof(_prefs.node_name)-1); - _prefs.node_name[sizeof(_prefs.node_name)-1] = 0; // truncate if necessary + StrHelper::strncpy(_prefs.node_name, ADVERT_NAME, sizeof(_prefs.node_name)); _prefs.node_lat = ADVERT_LAT; _prefs.node_lon = ADVERT_LON; - strncpy(_prefs.password, ADMIN_PASSWORD, sizeof(_prefs.password)-1); - _prefs.password[sizeof(_prefs.password)-1] = 0; // truncate if necessary + StrHelper::strncpy(_prefs.password, ADMIN_PASSWORD, sizeof(_prefs.password)); _prefs.freq = LORA_FREQ; _prefs.tx_power_dbm = LORA_TX_POWER; _prefs.disable_fwd = 1; _prefs.advert_interval = 2; // default to 2 minutes for NEW installs #ifdef ROOM_PASSWORD - strncpy(_prefs.guest_password, ROOM_PASSWORD, sizeof(_prefs.guest_password)-1); - _prefs.guest_password[sizeof(_prefs.guest_password)-1] = 0; // truncate if necessary + StrHelper::strncpy(_prefs.guest_password, ROOM_PASSWORD, sizeof(_prefs.guest_password)); #endif num_clients = 0; @@ -639,8 +635,7 @@ public: } } else if (memcmp(command, "password ", 9) == 0) { // change admin password - strncpy(_prefs.password, &command[9], sizeof(_prefs.password)-1); - _prefs.password[sizeof(_prefs.password)-1] = 0; // truncate if necesary + StrHelper::strncpy(_prefs.password, &command[9], sizeof(_prefs.password)); savePrefs(); sprintf(reply, "password now: %s", _prefs.password); // echo back just to let admin know for sure!! } else if (memcmp(command, "set ", 4) == 0) { @@ -662,13 +657,11 @@ public: strcpy(reply, "OK"); } } else if (memcmp(config, "guest.password ", 15) == 0) { - strncpy(_prefs.guest_password, &config[15], sizeof(_prefs.guest_password)-1); - _prefs.guest_password[sizeof(_prefs.guest_password)-1] = 0; // truncate if necessary + StrHelper::strncpy(_prefs.guest_password, &config[15], sizeof(_prefs.guest_password)); savePrefs(); strcpy(reply, "OK"); } else if (memcmp(config, "name ", 5) == 0) { - strncpy(_prefs.node_name, &config[5], sizeof(_prefs.node_name)-1); - _prefs.node_name[sizeof(_prefs.node_name)-1] = 0; // truncate if nec + StrHelper::strncpy(_prefs.node_name, &config[5], sizeof(_prefs.node_name)); savePrefs(); strcpy(reply, "OK"); } else if (memcmp(config, "repeat ", 7) == 0) { diff --git a/examples/simple_secure_chat/main.cpp b/examples/simple_secure_chat/main.cpp index 29945748..b48b7ab6 100644 --- a/examples/simple_secure_chat/main.cpp +++ b/examples/simple_secure_chat/main.cpp @@ -466,8 +466,7 @@ public: savePrefs(); Serial.println(" OK"); } else if (memcmp(config, "name ", 5) == 0) { - strncpy(_prefs.node_name, &config[5], sizeof(_prefs.node_name)-1); - _prefs.node_name[sizeof(_prefs.node_name)-1] = 0; // truncate if nec + StrHelper::strncpy(_prefs.node_name, &config[5], sizeof(_prefs.node_name)); savePrefs(); Serial.println(" OK"); } else if (memcmp(config, "lat ", 4) == 0) { diff --git a/src/helpers/BaseChatMesh.cpp b/src/helpers/BaseChatMesh.cpp index 7b7d9f7a..4d5cb168 100644 --- a/src/helpers/BaseChatMesh.cpp +++ b/src/helpers/BaseChatMesh.cpp @@ -55,8 +55,7 @@ void BaseChatMesh::onAdvertRecv(mesh::Packet* packet, const mesh::Identity& id, putBlobByKey(id.pub_key, PUB_KEY_SIZE, temp_buf, plen); // update - strncpy(from->name, parser.getName(), sizeof(from->name)-1); - from->name[sizeof(from->name)-1] = 0; + StrHelper::strncpy(from->name, parser.getName(), sizeof(from->name)); from->type = parser.getType(); if (parser.hasLatLon()) { from->gps_lat = parser.getIntLat(); diff --git a/src/helpers/TxtDataHelpers.cpp b/src/helpers/TxtDataHelpers.cpp new file mode 100644 index 00000000..bac3c28b --- /dev/null +++ b/src/helpers/TxtDataHelpers.cpp @@ -0,0 +1,9 @@ +#include "TxtDataHelpers.h" + +void StrHelper::strncpy(char* dest, const char* src, size_t buf_sz) { + while (buf_sz > 1 && *src) { + *dest++ = *src++; + buf_sz--; + } + *dest = 0; // truncates if needed +} diff --git a/src/helpers/TxtDataHelpers.h b/src/helpers/TxtDataHelpers.h index 667eb61a..14526075 100644 --- a/src/helpers/TxtDataHelpers.h +++ b/src/helpers/TxtDataHelpers.h @@ -6,3 +6,8 @@ #define TXT_TYPE_PLAIN 0 // a plain text message #define TXT_TYPE_CLI_DATA 1 // a CLI command #define TXT_TYPE_SIGNED_PLAIN 2 // plain text, signed by sender + +class StrHelper { +public: + static void strncpy(char* dest, const char* src, size_t buf_sz); +};