Fixed null values that could be pass to strcmp() (closes #745)

This commit is contained in:
Benoit Blanchon
2018-06-01 09:08:38 +02:00
parent 3523296e3d
commit 7c0af91844
9 changed files with 75 additions and 16 deletions

View File

@ -286,15 +286,21 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
template <typename TStringRef, typename TValueRef>
bool set_impl(TStringRef key, TValueRef value) {
// ignore null key
if (Internals::StringTraits<TStringRef>::is_null(key)) return false;
// search a matching key
iterator it = findKey<TStringRef>(key);
if (it == end()) {
// add the key
it = Internals::List<JsonPair>::add();
if (it == end()) return false;
bool key_ok =
Internals::ValueSaver<TStringRef>::save(_buffer, it->key, key);
if (!key_ok) return false;
}
// save the value
return Internals::ValueSaver<TValueRef>::save(_buffer, it->value, value);
}
@ -318,5 +324,5 @@ struct JsonVariantDefault<JsonObject> {
return JsonObject::invalid();
}
};
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -129,10 +129,11 @@ class JsonVariantComparisons {
if (is<JsonObject>() && right.template is<JsonObject>())
return as<JsonObject>() == right.template as<JsonObject>();
if (is<char *>() && right.template is<char *>())
return strcmp(as<char *>(), right.template as<char *>()) == 0;
return StringTraits<const char *>::equals(as<char *>(),
right.template as<char *>());
return false;
}
};
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -30,7 +30,9 @@ struct CharPointerTraits {
};
static bool equals(const TChar* str, const char* expected) {
return strcmp(reinterpret_cast<const char*>(str), expected) == 0;
const char* actual = reinterpret_cast<const char*>(str);
if (!actual || !expected) return actual == expected;
return strcmp(actual, expected) == 0;
}
static bool is_null(const TChar* str) {
@ -58,5 +60,5 @@ struct CharPointerTraits {
template <typename TChar>
struct StringTraits<TChar*, typename EnableIf<IsChar<TChar>::value>::type>
: CharPointerTraits<TChar> {};
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -31,7 +31,9 @@ struct StringTraits<const __FlashStringHelper*, void> {
};
static bool equals(const __FlashStringHelper* str, const char* expected) {
return strcmp_P(expected, (const char*)str) == 0;
const char* actual = reinterpret_cast<const char*>(str);
if (!actual || !expected) return actual == expected;
return strcmp_P(expected, actual) == 0;
}
static bool is_null(const __FlashStringHelper* str) {
@ -53,7 +55,7 @@ struct StringTraits<const __FlashStringHelper*, void> {
static const bool has_equals = true;
static const bool should_duplicate = true;
};
}
}
} // namespace Internals
} // namespace ArduinoJson
#endif

View File

@ -40,7 +40,10 @@ struct StdStringTraits {
};
static bool equals(const TString& str, const char* expected) {
return 0 == strcmp(str.c_str(), expected);
// Arduino's String::c_str() can return NULL
const char* actual = str.c_str();
if (!actual || !expected) return actual == expected;
return 0 == strcmp(actual, expected);
}
static void append(TString& str, char c) {
@ -68,7 +71,7 @@ struct StringTraits<StringSumHelper, void> : StdStringTraits<StringSumHelper> {
template <>
struct StringTraits<std::string, void> : StdStringTraits<std::string> {};
#endif
}
}
} // namespace Internals
} // namespace ArduinoJson
#endif