From eea8a1b07abc4c50d832525e7cee46099d725864 Mon Sep 17 00:00:00 2001 From: Jacob Dufault Date: Sat, 18 Nov 2017 09:27:37 -0800 Subject: [PATCH] Try to avoid crashing when deserializing JSON --- src/indexer.h | 3 ++- src/language_server_api.cc | 4 ++++ src/position.cc | 10 ++++++++-- src/serializer.cc | 18 ++++++++++++------ src/serializer.h | 4 ++++ 5 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/indexer.h b/src/indexer.h index aad78f8e..ed20c819 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -64,7 +64,8 @@ bool operator!=(const Id& a, const Id& b) { template void Reflect(Reader& visitor, Id& id) { - id.id = visitor.GetUint64(); + if (visitor.IsUint64()) + id.id = visitor.GetUint64(); } template void Reflect(Writer& visitor, Id& value) { diff --git a/src/language_server_api.cc b/src/language_server_api.cc index 9c1471c8..71d5bc3c 100644 --- a/src/language_server_api.cc +++ b/src/language_server_api.cc @@ -303,6 +303,10 @@ const std::string& lsCompletionItem::InsertedContent() const { } void Reflect(Reader& reader, lsInitializeParams::lsTrace& value) { + if (!reader.IsString()) { + value = lsInitializeParams::lsTrace::Off; + return; + } std::string v = reader.GetString(); if (v == "off") value = lsInitializeParams::lsTrace::Off; diff --git a/src/position.cc b/src/position.cc index 32c9e87f..07b90a06 100644 --- a/src/position.cc +++ b/src/position.cc @@ -146,7 +146,10 @@ bool Range::operator<(const Range& that) const { // Position 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) { std::string output = value.ToString(); @@ -155,7 +158,10 @@ void Reflect(Writer& visitor, Position& value) { // Range 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) { std::string output = value.ToString(); diff --git a/src/serializer.cc b/src/serializer.cc index b573cbcf..3a437831 100644 --- a/src/serializer.cc +++ b/src/serializer.cc @@ -8,42 +8,48 @@ bool gTestOutputMode = false; // int16_t 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) { visitor.Int(value); } // int32_t void Reflect(Reader& visitor, int32_t& value) { - value = visitor.GetInt(); + if (visitor.IsInt()) + value = visitor.GetInt(); } void Reflect(Writer& visitor, int32_t& value) { visitor.Int(value); } // int64_t void Reflect(Reader& visitor, int64_t& value) { - value = visitor.GetInt64(); + if (visitor.IsInt64()) + value = visitor.GetInt64(); } void Reflect(Writer& visitor, int64_t& value) { visitor.Int64(value); } // uint64_t void Reflect(Reader& visitor, uint64_t& value) { - value = visitor.GetUint64(); + if (visitor.IsUint64()) + value = visitor.GetUint64(); } void Reflect(Writer& visitor, uint64_t& value) { visitor.Uint64(value); } // bool void Reflect(Reader& visitor, bool& value) { - value = visitor.GetBool(); + if (visitor.IsBool()) + value = visitor.GetBool(); } void Reflect(Writer& visitor, bool& value) { visitor.Bool(value); } // std::string void Reflect(Reader& visitor, std::string& value) { - value = visitor.GetString(); + if (visitor.IsString()) + value = visitor.GetString(); } void Reflect(Writer& visitor, std::string& value) { visitor.String(value.c_str(), (rapidjson::SizeType)value.size()); diff --git a/src/serializer.h b/src/serializer.h index cd2699de..083a0d73 100644 --- a/src/serializer.h +++ b/src/serializer.h @@ -168,6 +168,8 @@ void ReflectMember(Writer& visitor, const char* name, std::string& value); // Reader: template void Reflect(Reader& visitor, std::vector& values) { + if (!visitor.IsArray()) + return; for (auto& entry : visitor.GetArray()) { T entry_value; Reflect(entry, entry_value); @@ -176,6 +178,8 @@ void Reflect(Reader& visitor, std::vector& values) { } template void Reflect(Reader& visitor, optional& value) { + if (visitor.IsNull()) + return; T real_value; Reflect(visitor, real_value); value = real_value;