Try to avoid crashing when deserializing JSON

This commit is contained in:
Jacob Dufault 2017-11-18 09:27:37 -08:00
parent 544818bdd4
commit eea8a1b07a
5 changed files with 30 additions and 9 deletions

View File

@ -64,7 +64,8 @@ bool operator!=(const Id<T>& a, const Id<T>& b) {
template <typename T> template <typename T>
void Reflect(Reader& visitor, Id<T>& id) { void Reflect(Reader& visitor, Id<T>& id) {
id.id = visitor.GetUint64(); if (visitor.IsUint64())
id.id = visitor.GetUint64();
} }
template <typename T> template <typename T>
void Reflect(Writer& visitor, Id<T>& value) { void Reflect(Writer& visitor, Id<T>& value) {

View File

@ -303,6 +303,10 @@ const std::string& lsCompletionItem::InsertedContent() const {
} }
void Reflect(Reader& reader, lsInitializeParams::lsTrace& value) { void Reflect(Reader& reader, lsInitializeParams::lsTrace& value) {
if (!reader.IsString()) {
value = lsInitializeParams::lsTrace::Off;
return;
}
std::string v = reader.GetString(); std::string v = reader.GetString();
if (v == "off") if (v == "off")
value = lsInitializeParams::lsTrace::Off; value = lsInitializeParams::lsTrace::Off;

View File

@ -146,7 +146,10 @@ bool Range::operator<(const Range& that) const {
// Position // Position
void Reflect(Reader& visitor, Position& value) { void Reflect(Reader& visitor, Position& value) {
value = Position(visitor.GetString()); if (!visitor.IsString())
value = Position();
else
value = Position(visitor.GetString());
} }
void Reflect(Writer& visitor, Position& value) { void Reflect(Writer& visitor, Position& value) {
std::string output = value.ToString(); std::string output = value.ToString();
@ -155,7 +158,10 @@ void Reflect(Writer& visitor, Position& value) {
// Range // Range
void Reflect(Reader& visitor, Range& value) { void Reflect(Reader& visitor, Range& value) {
value = Range(visitor.GetString()); if (!visitor.IsString())
value = Range();
else
value = Range(visitor.GetString());
} }
void Reflect(Writer& visitor, Range& value) { void Reflect(Writer& visitor, Range& value) {
std::string output = value.ToString(); std::string output = value.ToString();

View File

@ -8,42 +8,48 @@ bool gTestOutputMode = false;
// int16_t // int16_t
void Reflect(Reader& visitor, int16_t& value) { void Reflect(Reader& visitor, int16_t& value) {
value = (int16_t)visitor.GetInt(); if (visitor.IsInt())
value = (int16_t)visitor.GetInt();
} }
void Reflect(Writer& visitor, int16_t& value) { void Reflect(Writer& visitor, int16_t& value) {
visitor.Int(value); visitor.Int(value);
} }
// int32_t // int32_t
void Reflect(Reader& visitor, int32_t& value) { void Reflect(Reader& visitor, int32_t& value) {
value = visitor.GetInt(); if (visitor.IsInt())
value = visitor.GetInt();
} }
void Reflect(Writer& visitor, int32_t& value) { void Reflect(Writer& visitor, int32_t& value) {
visitor.Int(value); visitor.Int(value);
} }
// int64_t // int64_t
void Reflect(Reader& visitor, int64_t& value) { void Reflect(Reader& visitor, int64_t& value) {
value = visitor.GetInt64(); if (visitor.IsInt64())
value = visitor.GetInt64();
} }
void Reflect(Writer& visitor, int64_t& value) { void Reflect(Writer& visitor, int64_t& value) {
visitor.Int64(value); visitor.Int64(value);
} }
// uint64_t // uint64_t
void Reflect(Reader& visitor, uint64_t& value) { void Reflect(Reader& visitor, uint64_t& value) {
value = visitor.GetUint64(); if (visitor.IsUint64())
value = visitor.GetUint64();
} }
void Reflect(Writer& visitor, uint64_t& value) { void Reflect(Writer& visitor, uint64_t& value) {
visitor.Uint64(value); visitor.Uint64(value);
} }
// bool // bool
void Reflect(Reader& visitor, bool& value) { void Reflect(Reader& visitor, bool& value) {
value = visitor.GetBool(); if (visitor.IsBool())
value = visitor.GetBool();
} }
void Reflect(Writer& visitor, bool& value) { void Reflect(Writer& visitor, bool& value) {
visitor.Bool(value); visitor.Bool(value);
} }
// std::string // std::string
void Reflect(Reader& visitor, std::string& value) { void Reflect(Reader& visitor, std::string& value) {
value = visitor.GetString(); if (visitor.IsString())
value = visitor.GetString();
} }
void Reflect(Writer& visitor, std::string& value) { void Reflect(Writer& visitor, std::string& value) {
visitor.String(value.c_str(), (rapidjson::SizeType)value.size()); visitor.String(value.c_str(), (rapidjson::SizeType)value.size());

View File

@ -168,6 +168,8 @@ void ReflectMember(Writer& visitor, const char* name, std::string& value);
// Reader: // Reader:
template <typename T> template <typename T>
void Reflect(Reader& visitor, std::vector<T>& values) { void Reflect(Reader& visitor, std::vector<T>& values) {
if (!visitor.IsArray())
return;
for (auto& entry : visitor.GetArray()) { for (auto& entry : visitor.GetArray()) {
T entry_value; T entry_value;
Reflect(entry, entry_value); Reflect(entry, entry_value);
@ -176,6 +178,8 @@ void Reflect(Reader& visitor, std::vector<T>& values) {
} }
template <typename T> template <typename T>
void Reflect(Reader& visitor, optional<T>& value) { void Reflect(Reader& visitor, optional<T>& value) {
if (visitor.IsNull())
return;
T real_value; T real_value;
Reflect(visitor, real_value); Reflect(visitor, real_value);
value = real_value; value = real_value;