Skip to content

Commit deab127

Browse files
committed
Fix crash with tiny Flash strings (issue #2170)
1 parent 96281de commit deab127

File tree

6 files changed

+27
-7
lines changed

6 files changed

+27
-7
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
ArduinoJson: change log
22
=======================
33

4+
HEAD
5+
----
6+
7+
* Fix crash with tiny Flash strings (issue #2170)
8+
49
v7.4.0 (2025-04-09)
510
------
611

extras/tests/JsonDocument/set.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,13 @@ TEST_CASE("JsonDocument::set()") {
8787
});
8888
}
8989

90+
SECTION("Flash tiny string") { // issue #2170
91+
doc.set(F("abc"));
92+
93+
REQUIRE(doc.as<const char*>() == "abc"_s);
94+
REQUIRE(spy.log() == AllocatorLog{});
95+
}
96+
9097
#ifdef HAS_VARIABLE_LENGTH_ARRAY
9198
SECTION("VLA") {
9299
size_t i = 16;

src/ArduinoJson/Memory/StringBuffer.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class StringBuffer {
4141
ARDUINOJSON_ASSERT(node_ != nullptr);
4242
const char* s = node_->data;
4343
if (isTinyString(s, size_))
44-
data->setTinyString(s, static_cast<uint8_t>(size_));
44+
data->setTinyString(adaptString(s, size_));
4545
else
4646
data->setOwnedString(commitStringNode());
4747
}

src/ArduinoJson/Memory/StringBuilder.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class StringBuilder {
3131

3232
char* p = node_->data;
3333
if (isTinyString(p, size_)) {
34-
variant->setTinyString(p, static_cast<uint8_t>(size_));
34+
variant->setTinyString(adaptString(p, size_));
3535
return;
3636
}
3737

src/ArduinoJson/Variant/VariantData.hpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -526,12 +526,20 @@ class VariantData {
526526
content_.asLinkedString = s;
527527
}
528528

529-
void setTinyString(const char* s, uint8_t n) {
529+
template <typename TAdaptedString>
530+
void setTinyString(const TAdaptedString& s) {
530531
ARDUINOJSON_ASSERT(type_ == VariantType::Null); // must call clear() first
531-
ARDUINOJSON_ASSERT(s);
532+
ARDUINOJSON_ASSERT(s.size() <= tinyStringMaxLength);
533+
532534
type_ = VariantType::TinyString;
533-
for (uint8_t i = 0; i < n; i++)
534-
content_.asTinyString[i] = s[i];
535+
536+
auto n = uint8_t(s.size());
537+
for (uint8_t i = 0; i < n; i++) {
538+
char c = s[i];
539+
ARDUINOJSON_ASSERT(c != 0); // no NUL in tiny string
540+
content_.asTinyString[i] = c;
541+
}
542+
535543
content_.asTinyString[n] = 0;
536544
}
537545

src/ArduinoJson/Variant/VariantImpl.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ inline bool VariantData::setString(TAdaptedString value,
3232
}
3333

3434
if (isTinyString(value, value.size())) {
35-
setTinyString(value.data(), uint8_t(value.size()));
35+
setTinyString(value);
3636
return true;
3737
}
3838

0 commit comments

Comments
 (0)