Add error checking of object deserialization; ignore non-object initializationOptions

This commit is contained in:
Fangrui Song 2019-03-29 06:54:41 -07:00
parent 193eacc837
commit 539ca22e5e
3 changed files with 19 additions and 2 deletions

View File

@ -215,8 +215,8 @@ void Reflect(JsonReader &reader, InitializeParam::Trace &value) {
value = InitializeParam::Trace::Verbose;
}
REFLECT_STRUCT(InitializeParam, rootUri, initializationOptions, capabilities,
trace, workspaceFolders);
// initializationOptions is deserialized separately.
REFLECT_STRUCT(InitializeParam, rootUri, capabilities, trace, workspaceFolders);
struct InitializeResult {
ServerCap capabilities;
@ -384,6 +384,17 @@ void Initialize(MessageHandler *m, InitializeParam &param, ReplyOnce &reply) {
void MessageHandler::initialize(JsonReader &reader, ReplyOnce &reply) {
InitializeParam param;
Reflect(reader, param);
auto it = reader.m->FindMember("initializationOptions");
if (it != reader.m->MemberEnd() && it->value.IsObject()) {
JsonReader m1(&it->value);
try {
Reflect(m1, param.initializationOptions);
} catch (std::invalid_argument &) {
reader.path_.push_back("initializationOptions");
reader.path_.insert(reader.path_.end(), m1.path_.begin(), m1.path_.end());
throw;
}
}
if (!param.rootUri) {
reply.Error(ErrorCode::InvalidRequest, "expected rootUri");
return;

View File

@ -396,6 +396,11 @@ void Reflect(JsonWriter &vis, SerializeFormat &v) {
}
}
void ReflectMemberStart(JsonReader &vis) {
if (!vis.m->IsObject())
throw std::invalid_argument("object");
}
static BumpPtrAllocator Alloc;
static DenseSet<CachedHashStringRef> Strings;
static std::mutex AllocMutex;

View File

@ -367,6 +367,7 @@ template <typename T> void Reflect(BinaryWriter &vis, std::vector<T> &v) {
// ReflectMember
void ReflectMemberStart(JsonReader &);
template <typename T> void ReflectMemberStart(T &) {}
inline void ReflectMemberStart(JsonWriter &vis) { vis.StartObject(); }