forked from bblanchon/ArduinoJson
Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
6ea2815341 | |||
3c145f1782 | |||
21b2c76524 | |||
4f6244eef4 | |||
973858b835 | |||
ee12155617 | |||
4b4c68df5f | |||
fcae33d574 | |||
896f50eeb9 |
@ -1,6 +1,12 @@
|
||||
ArduinoJson: change log
|
||||
=======================
|
||||
|
||||
v6.19.1 (2022-01-14)
|
||||
-------
|
||||
|
||||
* Fix crash when adding an object member in a too small `JsonDocument`
|
||||
* Fix filter not working in zero-copy mode (issue #1697)
|
||||
|
||||
v6.19.0 (2022-01-08)
|
||||
-------
|
||||
|
||||
@ -24,7 +30,6 @@ v6.19.0 (2022-01-08)
|
||||
* Avoid including `Arduino.h` when all its features are disabled (issue #1692, PR #1693 by @paulocsanz)
|
||||
* Assume `PROGMEM` is available as soon as `ARDUINO` is defined (consequence of #1693)
|
||||
|
||||
|
||||
v6.18.5 (2021-09-28)
|
||||
-------
|
||||
|
||||
|
@ -10,7 +10,7 @@ if(ESP_PLATFORM)
|
||||
return()
|
||||
endif()
|
||||
|
||||
project(ArduinoJson VERSION 6.19.0)
|
||||
project(ArduinoJson VERSION 6.19.1)
|
||||
|
||||
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
|
||||
include(CTest)
|
||||
|
@ -7,8 +7,8 @@
|
||||
[](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:arduinojson)
|
||||
[](https://lgtm.com/projects/g/bblanchon/ArduinoJson/)
|
||||
[](https://coveralls.io/github/bblanchon/ArduinoJson?branch=6.x)
|
||||
[](https://www.ardu-badge.com/ArduinoJson/6.19.0)
|
||||
[](https://registry.platformio.org/packages/libraries/bblanchon/ArduinoJson?version=6.19.0)
|
||||
[](https://www.ardu-badge.com/ArduinoJson/6.19.1)
|
||||
[](https://registry.platformio.org/packages/libraries/bblanchon/ArduinoJson?version=6.19.1)
|
||||
[](https://github.com/bblanchon/ArduinoJson/stargazers)
|
||||
[](https://github.com/sponsors/bblanchon)
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
version: 6.19.0.{build}
|
||||
version: 6.19.1.{build}
|
||||
environment:
|
||||
matrix:
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
|
||||
|
@ -8,7 +8,7 @@ CHANGELOG="$2"
|
||||
cat << END
|
||||
## Changes
|
||||
|
||||
$(awk '/\* /{ FOUND=1; print; next } { if (FOUND) exit}' "$CHANGELOG")
|
||||
$(awk '/\* /{ FOUND=1 } /^[[:space:]]*$/ { if(FOUND) exit } { if(FOUND) print }' "$CHANGELOG")
|
||||
|
||||
[View version history](https://github.com/bblanchon/ArduinoJson/blob/$TAG/CHANGELOG.md)
|
||||
END
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
set -eu
|
||||
|
||||
which awk sed jq 7z curl perl >/dev/null
|
||||
|
||||
cd "$(dirname "$0")/../.."
|
||||
|
||||
if ! git diff --quiet --exit-code; then
|
||||
|
@ -667,6 +667,20 @@ TEST_CASE("Filtering") {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Zero-copy mode") { // issue #1697
|
||||
char input[] = "{\"include\":42,\"exclude\":666}";
|
||||
|
||||
StaticJsonDocument<256> filter;
|
||||
filter["include"] = true;
|
||||
|
||||
StaticJsonDocument<256> doc;
|
||||
DeserializationError err =
|
||||
deserializeJson(doc, input, DeserializationOption::Filter(filter));
|
||||
|
||||
REQUIRE(err == DeserializationError::Ok);
|
||||
CHECK(doc.as<std::string>() == "{\"include\":42}");
|
||||
}
|
||||
|
||||
TEST_CASE("Overloads") {
|
||||
StaticJsonDocument<256> doc;
|
||||
StaticJsonDocument<256> filter;
|
||||
|
@ -279,6 +279,22 @@ TEST_CASE("deserialize JSON object") {
|
||||
REQUIRE(err == DeserializationError::Ok);
|
||||
REQUIRE(doc["a"] == 2);
|
||||
}
|
||||
|
||||
SECTION("Repeated key with zero copy mode") { // issue #1697
|
||||
char input[] = "{a:{b:{c:1}},a:2}";
|
||||
DeserializationError err = deserializeJson(doc, input);
|
||||
|
||||
REQUIRE(err == DeserializationError::Ok);
|
||||
REQUIRE(doc["a"] == 2);
|
||||
}
|
||||
|
||||
SECTION("NUL in keys") { // we don't support NULs in keys
|
||||
DeserializationError err =
|
||||
deserializeJson(doc, "{\"x\\u0000a\":1,\"x\\u0000b\":2}");
|
||||
|
||||
REQUIRE(err == DeserializationError::Ok);
|
||||
REQUIRE(doc.as<std::string>() == "{\"x\":2}");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Should clear the JsonObject") {
|
||||
|
@ -35,6 +35,12 @@ TEST_CASE("JsonDocument::overflowed()") {
|
||||
CHECK(doc.overflowed() == false);
|
||||
}
|
||||
|
||||
SECTION("returns true after a failed member add") {
|
||||
StaticJsonDocument<1> doc;
|
||||
doc["example"] = true;
|
||||
CHECK(doc.overflowed() == true);
|
||||
}
|
||||
|
||||
SECTION("returns true after a failed deserialization") {
|
||||
StaticJsonDocument<JSON_ARRAY_SIZE(1)> doc;
|
||||
deserializeJson(doc, "[\"example\"]");
|
||||
|
@ -18,7 +18,7 @@ TEST_CASE("StringCopier") {
|
||||
str.append("hello");
|
||||
|
||||
REQUIRE(str.isValid() == true);
|
||||
REQUIRE(std::string(str.str()) == "hello");
|
||||
REQUIRE(str.str() == "hello");
|
||||
REQUIRE(pool.overflowed() == false);
|
||||
}
|
||||
|
||||
|
@ -1027,6 +1027,20 @@ TEST_CASE("deserializeMsgPack() filter") {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Zero-copy mode") { // issue #1697
|
||||
char input[] = "\x82\xA7include\x01\xA6ignore\x02";
|
||||
|
||||
StaticJsonDocument<256> filter;
|
||||
filter["include"] = true;
|
||||
|
||||
StaticJsonDocument<256> doc;
|
||||
DeserializationError err =
|
||||
deserializeMsgPack(doc, input, 18, DeserializationOption::Filter(filter));
|
||||
|
||||
CHECK(err == DeserializationError::Ok);
|
||||
CHECK(doc.as<std::string>() == "{\"include\":1}");
|
||||
}
|
||||
|
||||
TEST_CASE("Overloads") {
|
||||
StaticJsonDocument<256> doc;
|
||||
StaticJsonDocument<256> filter;
|
||||
|
@ -7,7 +7,7 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/bblanchon/ArduinoJson.git"
|
||||
},
|
||||
"version": "6.19.0",
|
||||
"version": "6.19.1",
|
||||
"authors": {
|
||||
"name": "Benoit Blanchon",
|
||||
"url": "https://blog.benoitblanchon.fr"
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=ArduinoJson
|
||||
version=6.19.0
|
||||
version=6.19.1
|
||||
author=Benoit Blanchon <blog.benoitblanchon.fr>
|
||||
maintainer=Benoit Blanchon <blog.benoitblanchon.fr>
|
||||
sentence=A simple and efficient JSON library for embedded C++.
|
||||
|
@ -231,7 +231,7 @@ class JsonDeserializer {
|
||||
return false;
|
||||
}
|
||||
|
||||
typename TStringStorage::string_type key = _stringStorage.str();
|
||||
String key = _stringStorage.str();
|
||||
|
||||
TFilter memberFilter = filter[key.c_str()];
|
||||
|
||||
|
@ -62,12 +62,12 @@ class MemoryPool {
|
||||
template <typename TAdaptedString>
|
||||
const char* saveString(TAdaptedString str) {
|
||||
if (str.isNull())
|
||||
return CopiedString();
|
||||
return 0;
|
||||
|
||||
#if ARDUINOJSON_ENABLE_STRING_DEDUPLICATION
|
||||
const char* existingCopy = findString(str);
|
||||
if (existingCopy)
|
||||
return CopiedString(existingCopy, str.size());
|
||||
return existingCopy;
|
||||
#endif
|
||||
|
||||
size_t n = str.size();
|
||||
@ -77,7 +77,7 @@ class MemoryPool {
|
||||
stringGetChars(str, newCopy, n);
|
||||
newCopy[n] = 0; // force null-terminator
|
||||
}
|
||||
return CopiedString(newCopy, n);
|
||||
return newCopy;
|
||||
}
|
||||
|
||||
void getFreeZone(char** zoneStart, size_t* zoneSize) const {
|
||||
@ -89,14 +89,14 @@ class MemoryPool {
|
||||
#if ARDUINOJSON_ENABLE_STRING_DEDUPLICATION
|
||||
const char* dup = findString(adaptString(_left, len));
|
||||
if (dup)
|
||||
return CopiedString(dup, len);
|
||||
return dup;
|
||||
#endif
|
||||
|
||||
const char* str = _left;
|
||||
_left += len;
|
||||
*_left++ = 0;
|
||||
checkInvariants();
|
||||
return CopiedString(str, len);
|
||||
return str;
|
||||
}
|
||||
|
||||
void markAsOverflowed() {
|
||||
|
@ -48,6 +48,11 @@ class MsgPackDeserializer {
|
||||
|
||||
bool allowValue = filter.allowValue();
|
||||
|
||||
if (allowValue) {
|
||||
// callers pass a null pointer only when value must be ignored
|
||||
ARDUINOJSON_ASSERT(variant != 0);
|
||||
}
|
||||
|
||||
switch (code) {
|
||||
case 0xc0:
|
||||
// already null
|
||||
@ -417,11 +422,13 @@ class MsgPackDeserializer {
|
||||
if (!readKey())
|
||||
return false;
|
||||
|
||||
typename TStringStorage::string_type key = _stringStorage.str();
|
||||
String key = _stringStorage.str();
|
||||
TFilter memberFilter = filter[key.c_str()];
|
||||
VariantData *member;
|
||||
|
||||
if (memberFilter.allow()) {
|
||||
ARDUINOJSON_ASSERT(object);
|
||||
|
||||
// Save key in memory pool.
|
||||
// This MUST be done before adding the slot.
|
||||
key = _stringStorage.save();
|
||||
|
@ -10,8 +10,6 @@ namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
class StringCopier {
|
||||
public:
|
||||
typedef CopiedString string_type;
|
||||
|
||||
StringCopier(MemoryPool& pool) : _pool(&pool) {}
|
||||
|
||||
void startString() {
|
||||
@ -21,10 +19,10 @@ class StringCopier {
|
||||
_pool->markAsOverflowed();
|
||||
}
|
||||
|
||||
string_type save() {
|
||||
String save() {
|
||||
ARDUINOJSON_ASSERT(_ptr);
|
||||
ARDUINOJSON_ASSERT(_size < _capacity); // needs room for the terminator
|
||||
return string_type(_pool->saveStringFromFreeZone(_size), _size);
|
||||
return String(_pool->saveStringFromFreeZone(_size), _size, false);
|
||||
}
|
||||
|
||||
void append(const char* s) {
|
||||
@ -50,11 +48,11 @@ class StringCopier {
|
||||
return _size;
|
||||
}
|
||||
|
||||
string_type str() const {
|
||||
String str() const {
|
||||
ARDUINOJSON_ASSERT(_ptr);
|
||||
ARDUINOJSON_ASSERT(_size < _capacity);
|
||||
_ptr[_size] = 0;
|
||||
return string_type(_ptr, _size);
|
||||
return String(_ptr, _size, false);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -5,23 +5,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
#include <ArduinoJson/Strings/StoredString.hpp>
|
||||
#include <ArduinoJson/Strings/String.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
class StringMover {
|
||||
public:
|
||||
typedef LinkedString string_type;
|
||||
|
||||
StringMover(char* ptr) : _writePtr(ptr) {}
|
||||
|
||||
void startString() {
|
||||
_startPtr = _writePtr;
|
||||
}
|
||||
|
||||
FORCE_INLINE string_type save() {
|
||||
_writePtr[0] = 0; // terminator
|
||||
string_type s = str();
|
||||
FORCE_INLINE String save() {
|
||||
String s = str();
|
||||
_writePtr++;
|
||||
return s;
|
||||
}
|
||||
@ -34,8 +31,9 @@ class StringMover {
|
||||
return true;
|
||||
}
|
||||
|
||||
string_type str() const {
|
||||
return string_type(_startPtr, size());
|
||||
String str() const {
|
||||
_writePtr[0] = 0; // terminator
|
||||
return String(_startPtr, size(), true);
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
|
@ -5,7 +5,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Memory/MemoryPool.hpp>
|
||||
#include <ArduinoJson/Strings/StoredString.hpp>
|
||||
#include <ArduinoJson/Strings/String.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
@ -13,15 +12,13 @@ namespace ARDUINOJSON_NAMESPACE {
|
||||
struct LinkStringStoragePolicy {
|
||||
template <typename TAdaptedString, typename TCallback>
|
||||
bool store(TAdaptedString str, MemoryPool *, TCallback callback) {
|
||||
LinkedString storedString(str.data(), str.size());
|
||||
String storedString(str.data(), str.size(), true);
|
||||
callback(storedString);
|
||||
return !str.isNull();
|
||||
}
|
||||
};
|
||||
|
||||
struct CopyStringStoragePolicy {
|
||||
typedef CopiedString TResult;
|
||||
|
||||
template <typename TAdaptedString, typename TCallback>
|
||||
bool store(TAdaptedString str, MemoryPool *pool, TCallback callback);
|
||||
};
|
||||
|
@ -1,35 +0,0 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2022, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <bool linked>
|
||||
class StoredString {
|
||||
public:
|
||||
StoredString() : _data(0), _size(0) {}
|
||||
StoredString(const char* p, size_t n) : _data(p), _size(n) {}
|
||||
|
||||
operator const char*() const {
|
||||
return _data;
|
||||
}
|
||||
|
||||
const char* c_str() const {
|
||||
return _data;
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return _size;
|
||||
}
|
||||
|
||||
private:
|
||||
const char* _data;
|
||||
size_t _size;
|
||||
};
|
||||
|
||||
typedef StoredString<true> LinkedString;
|
||||
typedef StoredString<false> CopiedString;
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
@ -206,9 +206,9 @@ class MemoryPoolPrint : public Print {
|
||||
pool->getFreeZone(&_string, &_capacity);
|
||||
}
|
||||
|
||||
CopiedString str() {
|
||||
String str() {
|
||||
ARDUINOJSON_ASSERT(_size < _capacity);
|
||||
return CopiedString(_pool->saveStringFromFreeZone(_size), _size);
|
||||
return String(_pool->saveStringFromFreeZone(_size), _size, false);
|
||||
}
|
||||
|
||||
size_t write(uint8_t c) {
|
||||
|
@ -26,6 +26,8 @@ struct SlotKeySetter {
|
||||
template <typename TAdaptedString, typename TStoragePolicy>
|
||||
inline bool slotSetKey(VariantSlot* var, TAdaptedString key, MemoryPool* pool,
|
||||
TStoragePolicy storage) {
|
||||
if (!var)
|
||||
return false;
|
||||
return storage.store(key, pool, SlotKeySetter(var));
|
||||
}
|
||||
|
||||
|
@ -208,16 +208,12 @@ class VariantData {
|
||||
setType(VALUE_IS_NULL);
|
||||
}
|
||||
|
||||
void setString(CopiedString s) {
|
||||
void setString(String s) {
|
||||
ARDUINOJSON_ASSERT(s);
|
||||
setType(VALUE_IS_OWNED_STRING);
|
||||
_content.asString.data = s.c_str();
|
||||
_content.asString.size = s.size();
|
||||
}
|
||||
|
||||
void setString(LinkedString s) {
|
||||
ARDUINOJSON_ASSERT(s);
|
||||
setType(VALUE_IS_LINKED_STRING);
|
||||
if (s.isStatic())
|
||||
setType(VALUE_IS_LINKED_STRING);
|
||||
else
|
||||
setType(VALUE_IS_OWNED_STRING);
|
||||
_content.asString.data = s.c_str();
|
||||
_content.asString.size = s.size();
|
||||
}
|
||||
|
@ -174,7 +174,7 @@ template <typename TAdaptedString, typename TCallback>
|
||||
bool CopyStringStoragePolicy::store(TAdaptedString str, MemoryPool *pool,
|
||||
TCallback callback) {
|
||||
const char *copy = pool->saveString(str);
|
||||
CopiedString storedString(copy, str.size());
|
||||
String storedString(copy, str.size(), false);
|
||||
callback(storedString);
|
||||
return copy != 0;
|
||||
}
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include <ArduinoJson/Polyfills/integer.hpp>
|
||||
#include <ArduinoJson/Polyfills/limits.hpp>
|
||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||
#include <ArduinoJson/Strings/StoredString.hpp>
|
||||
#include <ArduinoJson/Variant/VariantContent.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
@ -77,15 +76,12 @@ class VariantSlot {
|
||||
_next = VariantSlotDiff(slot - this);
|
||||
}
|
||||
|
||||
void setKey(CopiedString k) {
|
||||
void setKey(String k) {
|
||||
ARDUINOJSON_ASSERT(k);
|
||||
_flags |= OWNED_KEY_BIT;
|
||||
_key = k.c_str();
|
||||
}
|
||||
|
||||
void setKey(LinkedString k) {
|
||||
ARDUINOJSON_ASSERT(k);
|
||||
_flags &= VALUE_MASK;
|
||||
if (k.isStatic())
|
||||
_flags &= VALUE_MASK;
|
||||
else
|
||||
_flags |= OWNED_KEY_BIT;
|
||||
_key = k.c_str();
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#define ARDUINOJSON_VERSION "6.19.0"
|
||||
#define ARDUINOJSON_VERSION "6.19.1"
|
||||
#define ARDUINOJSON_VERSION_MAJOR 6
|
||||
#define ARDUINOJSON_VERSION_MINOR 19
|
||||
#define ARDUINOJSON_VERSION_REVISION 0
|
||||
#define ARDUINOJSON_VERSION_REVISION 1
|
||||
|
Reference in New Issue
Block a user