mirror of
				https://github.com/MaskRay/ccls.git
				synced 2025-11-04 14:17:07 +00:00 
			
		
		
		
	Throw std::invalid_argument for deserialization type error
This commit is contained in:
		
							parent
							
								
									b0bf107f71
								
							
						
					
					
						commit
						556f32ec1b
					
				@ -155,7 +155,13 @@ std::unique_ptr<BaseIpcMessage> MessageRegistry::Parse(Reader& visitor) {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Allocator& allocator = allocators[method];
 | 
					  Allocator& allocator = allocators[method];
 | 
				
			||||||
 | 
					  // FIXME Print error message for deserialization error
 | 
				
			||||||
 | 
					  try {
 | 
				
			||||||
    return allocator(visitor);
 | 
					    return allocator(visitor);
 | 
				
			||||||
 | 
					  } catch (std::invalid_argument& e) {
 | 
				
			||||||
 | 
					    LOG_S(ERROR) << "Unable to deserialize request '" << method << "'";
 | 
				
			||||||
 | 
					    return nullptr;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MessageRegistry* MessageRegistry::instance() {
 | 
					MessageRegistry* MessageRegistry::instance() {
 | 
				
			||||||
 | 
				
			|||||||
@ -10,7 +10,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <loguru.hpp>
 | 
					#include <loguru.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <iostream>
 | 
					#include <stdexcept>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TODO Cleanup global variables
 | 
					// TODO Cleanup global variables
 | 
				
			||||||
extern std::string g_init_options;
 | 
					extern std::string g_init_options;
 | 
				
			||||||
@ -71,7 +71,18 @@ struct InitializeHandler : BaseMessageHandler<Ipc_InitializeRequest> {
 | 
				
			|||||||
        reader.Parse(g_init_options.c_str());
 | 
					        reader.Parse(g_init_options.c_str());
 | 
				
			||||||
        if (!reader.HasParseError()) {
 | 
					        if (!reader.HasParseError()) {
 | 
				
			||||||
          JsonReader json_reader{&reader};
 | 
					          JsonReader json_reader{&reader};
 | 
				
			||||||
 | 
					          try {
 | 
				
			||||||
            Reflect(json_reader, *config);
 | 
					            Reflect(json_reader, *config);
 | 
				
			||||||
 | 
					          } catch (std::invalid_argument& ex) {
 | 
				
			||||||
 | 
					            // FIXME This is not triggered. Need to pass error from
 | 
				
			||||||
 | 
					            // MessageRegistry::Parse in language_server_api.cc
 | 
				
			||||||
 | 
					            Out_ShowLogMessage out;
 | 
				
			||||||
 | 
					            out.display_type = Out_ShowLogMessage::DisplayType::Show;
 | 
				
			||||||
 | 
					            out.params.type = lsMessageType::Error;
 | 
				
			||||||
 | 
					            out.params.message = "Failed to deserialize " +
 | 
				
			||||||
 | 
					                                 json_reader.GetPath() + " " + ex.what();
 | 
				
			||||||
 | 
					            out.Write(std::cout);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      g_enable_comments = config->enableComments;
 | 
					      g_enable_comments = config->enableComments;
 | 
				
			||||||
 | 
				
			|||||||
@ -8,6 +8,8 @@
 | 
				
			|||||||
#include <doctest/doctest.h>
 | 
					#include <doctest/doctest.h>
 | 
				
			||||||
#include <loguru.hpp>
 | 
					#include <loguru.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdexcept>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace {
 | 
					namespace {
 | 
				
			||||||
bool gTestOutputMode = false;
 | 
					bool gTestOutputMode = false;
 | 
				
			||||||
}  // namespace
 | 
					}  // namespace
 | 
				
			||||||
@ -15,6 +17,7 @@ bool gTestOutputMode = false;
 | 
				
			|||||||
//// Elementary types
 | 
					//// Elementary types
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Reflect(Reader& visitor, uint8_t& value) {
 | 
					void Reflect(Reader& visitor, uint8_t& value) {
 | 
				
			||||||
 | 
					  if (!visitor.IsInt()) throw std::invalid_argument("uint8_t");
 | 
				
			||||||
  value = (uint8_t)visitor.GetInt();
 | 
					  value = (uint8_t)visitor.GetInt();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
void Reflect(Writer& visitor, uint8_t& value) {
 | 
					void Reflect(Writer& visitor, uint8_t& value) {
 | 
				
			||||||
@ -22,6 +25,7 @@ void Reflect(Writer& visitor, uint8_t& value) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Reflect(Reader& visitor, int16_t& value) {
 | 
					void Reflect(Reader& visitor, int16_t& value) {
 | 
				
			||||||
 | 
					  if (!visitor.IsInt()) throw std::invalid_argument("int16_t");
 | 
				
			||||||
  value = (int16_t)visitor.GetInt();
 | 
					  value = (int16_t)visitor.GetInt();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
void Reflect(Writer& visitor, int16_t& value) {
 | 
					void Reflect(Writer& visitor, int16_t& value) {
 | 
				
			||||||
@ -29,6 +33,7 @@ void Reflect(Writer& visitor, int16_t& value) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Reflect(Reader& visitor, int& value) {
 | 
					void Reflect(Reader& visitor, int& value) {
 | 
				
			||||||
 | 
					  if (!visitor.IsInt()) throw std::invalid_argument("int");
 | 
				
			||||||
  value = visitor.GetInt();
 | 
					  value = visitor.GetInt();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
void Reflect(Writer& visitor, int& value) {
 | 
					void Reflect(Writer& visitor, int& value) {
 | 
				
			||||||
@ -36,6 +41,7 @@ void Reflect(Writer& visitor, int& value) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Reflect(Reader& visitor, unsigned& value) {
 | 
					void Reflect(Reader& visitor, unsigned& value) {
 | 
				
			||||||
 | 
					  if (!visitor.IsInt()) throw std::invalid_argument("unsigned");
 | 
				
			||||||
  value = visitor.GetUint32();
 | 
					  value = visitor.GetUint32();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
void Reflect(Writer& visitor, unsigned& value) {
 | 
					void Reflect(Writer& visitor, unsigned& value) {
 | 
				
			||||||
@ -43,6 +49,7 @@ void Reflect(Writer& visitor, unsigned& value) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Reflect(Reader& visitor, long& value) {
 | 
					void Reflect(Reader& visitor, long& value) {
 | 
				
			||||||
 | 
					  if (!visitor.IsInt64()) throw std::invalid_argument("long");
 | 
				
			||||||
  value = long(visitor.GetInt64());
 | 
					  value = long(visitor.GetInt64());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
void Reflect(Writer& visitor, long& value) {
 | 
					void Reflect(Writer& visitor, long& value) {
 | 
				
			||||||
@ -50,6 +57,7 @@ void Reflect(Writer& visitor, long& value) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Reflect(Reader& visitor, unsigned long& value) {
 | 
					void Reflect(Reader& visitor, unsigned long& value) {
 | 
				
			||||||
 | 
					  if (!visitor.IsUint64()) throw std::invalid_argument("unsigned long");
 | 
				
			||||||
  value = (unsigned long)visitor.GetUint64();
 | 
					  value = (unsigned long)visitor.GetUint64();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
void Reflect(Writer& visitor, unsigned long& value) {
 | 
					void Reflect(Writer& visitor, unsigned long& value) {
 | 
				
			||||||
@ -57,6 +65,7 @@ void Reflect(Writer& visitor, unsigned long& value) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Reflect(Reader& visitor, long long& value) {
 | 
					void Reflect(Reader& visitor, long long& value) {
 | 
				
			||||||
 | 
					  if (!visitor.IsInt64()) throw std::invalid_argument("long long");
 | 
				
			||||||
  value = visitor.GetInt64();
 | 
					  value = visitor.GetInt64();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
void Reflect(Writer& visitor, long long& value) {
 | 
					void Reflect(Writer& visitor, long long& value) {
 | 
				
			||||||
@ -64,6 +73,7 @@ void Reflect(Writer& visitor, long long& value) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Reflect(Reader& visitor, unsigned long long& value) {
 | 
					void Reflect(Reader& visitor, unsigned long long& value) {
 | 
				
			||||||
 | 
					  if (!visitor.IsUint64()) throw std::invalid_argument("unsigned long long");
 | 
				
			||||||
  value = visitor.GetUint64();
 | 
					  value = visitor.GetUint64();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
void Reflect(Writer& visitor, unsigned long long& value) {
 | 
					void Reflect(Writer& visitor, unsigned long long& value) {
 | 
				
			||||||
@ -71,6 +81,7 @@ void Reflect(Writer& visitor, unsigned long long& value) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Reflect(Reader& visitor, double& value) {
 | 
					void Reflect(Reader& visitor, double& value) {
 | 
				
			||||||
 | 
					  if (!visitor.IsDouble()) throw std::invalid_argument("double");
 | 
				
			||||||
  value = visitor.GetDouble();
 | 
					  value = visitor.GetDouble();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
void Reflect(Writer& visitor, double& value) {
 | 
					void Reflect(Writer& visitor, double& value) {
 | 
				
			||||||
@ -78,6 +89,7 @@ void Reflect(Writer& visitor, double& value) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Reflect(Reader& visitor, bool& value) {
 | 
					void Reflect(Reader& visitor, bool& value) {
 | 
				
			||||||
 | 
					  if (!visitor.IsBool()) throw std::invalid_argument("bool");
 | 
				
			||||||
  value = visitor.GetBool();
 | 
					  value = visitor.GetBool();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
void Reflect(Writer& visitor, bool& value) {
 | 
					void Reflect(Writer& visitor, bool& value) {
 | 
				
			||||||
@ -86,7 +98,7 @@ void Reflect(Writer& visitor, bool& value) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// std::string
 | 
					// std::string
 | 
				
			||||||
void Reflect(Reader& visitor, std::string& value) {
 | 
					void Reflect(Reader& visitor, std::string& value) {
 | 
				
			||||||
  if (visitor.IsString())
 | 
					  if (!visitor.IsString()) throw std::invalid_argument("std::string");
 | 
				
			||||||
  value = visitor.GetString();
 | 
					  value = visitor.GetString();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
void Reflect(Writer& visitor, std::string& value) {
 | 
					void Reflect(Writer& visitor, std::string& value) {
 | 
				
			||||||
@ -289,7 +301,14 @@ std::unique_ptr<IndexFile> Deserialize(SerializeFormat format,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      file = MakeUnique<IndexFile>(path, nullopt);
 | 
					      file = MakeUnique<IndexFile>(path, nullopt);
 | 
				
			||||||
      JsonReader json_reader{&reader};
 | 
					      JsonReader json_reader{&reader};
 | 
				
			||||||
 | 
					      try {
 | 
				
			||||||
        Reflect(json_reader, *file);
 | 
					        Reflect(json_reader, *file);
 | 
				
			||||||
 | 
					      } catch (std::invalid_argument& e) {
 | 
				
			||||||
 | 
					        LOG_S(ERROR) << "'" << path << "': failed to deserialize "
 | 
				
			||||||
 | 
					                     << json_reader.GetPath() << "."
 | 
				
			||||||
 | 
					                     << e.what();
 | 
				
			||||||
 | 
					        return nullptr;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -19,12 +19,13 @@ class Reader {
 | 
				
			|||||||
  virtual ~Reader() {}
 | 
					  virtual ~Reader() {}
 | 
				
			||||||
  virtual SerializeFormat Format() const = 0;
 | 
					  virtual SerializeFormat Format() const = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // virtual bool IsBool() = 0;
 | 
					  virtual bool IsBool() = 0;
 | 
				
			||||||
  virtual bool IsNull() = 0;
 | 
					  virtual bool IsNull() = 0;
 | 
				
			||||||
  virtual bool IsArray() = 0;
 | 
					  virtual bool IsArray() = 0;
 | 
				
			||||||
  virtual bool IsInt() = 0;
 | 
					  virtual bool IsInt() = 0;
 | 
				
			||||||
  virtual bool IsInt64() = 0;
 | 
					  virtual bool IsInt64() = 0;
 | 
				
			||||||
  // virtual bool IsUint64() = 0;
 | 
					  virtual bool IsUint64() = 0;
 | 
				
			||||||
 | 
					  virtual bool IsDouble() = 0;
 | 
				
			||||||
  virtual bool IsString() = 0;
 | 
					  virtual bool IsString() = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  virtual void GetNull() = 0;
 | 
					  virtual void GetNull() = 0;
 | 
				
			||||||
 | 
				
			|||||||
@ -7,17 +7,19 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class JsonReader : public Reader {
 | 
					class JsonReader : public Reader {
 | 
				
			||||||
  rapidjson::GenericValue<rapidjson::UTF8<>>* m_;
 | 
					  rapidjson::GenericValue<rapidjson::UTF8<>>* m_;
 | 
				
			||||||
 | 
					  std::vector<const char*> path_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 public:
 | 
					 public:
 | 
				
			||||||
  JsonReader(rapidjson::GenericValue<rapidjson::UTF8<>>* m) : m_(m) {}
 | 
					  JsonReader(rapidjson::GenericValue<rapidjson::UTF8<>>* m) : m_(m) {}
 | 
				
			||||||
  SerializeFormat Format() const override { return SerializeFormat::Json; }
 | 
					  SerializeFormat Format() const override { return SerializeFormat::Json; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // bool IsBool() override { return m_->IsBool(); }
 | 
					  bool IsBool() override { return m_->IsBool(); }
 | 
				
			||||||
  bool IsNull() override { return m_->IsNull(); }
 | 
					  bool IsNull() override { return m_->IsNull(); }
 | 
				
			||||||
  bool IsArray() override { return m_->IsArray(); }
 | 
					  bool IsArray() override { return m_->IsArray(); }
 | 
				
			||||||
  bool IsInt() override { return m_->IsInt(); }
 | 
					  bool IsInt() override { return m_->IsInt(); }
 | 
				
			||||||
  bool IsInt64() override { return m_->IsInt64(); }
 | 
					  bool IsInt64() override { return m_->IsInt64(); }
 | 
				
			||||||
  // bool IsUint64() override { return m_->IsUint64(); }
 | 
					  bool IsUint64() override { return m_->IsUint64(); }
 | 
				
			||||||
 | 
					  bool IsDouble() override { return m_->IsDouble(); }
 | 
				
			||||||
  bool IsString() override { return m_->IsString(); }
 | 
					  bool IsString() override { return m_->IsString(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void GetNull() override {}
 | 
					  void GetNull() override {}
 | 
				
			||||||
@ -36,22 +38,35 @@ class JsonReader : public Reader {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void IterArray(std::function<void(Reader&)> fn) override {
 | 
					  void IterArray(std::function<void(Reader&)> fn) override {
 | 
				
			||||||
 | 
					    if (!m_->IsArray())
 | 
				
			||||||
 | 
					      throw std::invalid_argument("array");
 | 
				
			||||||
 | 
					    // Use "0" to indicate any element for now.
 | 
				
			||||||
 | 
					    path_.push_back("0");
 | 
				
			||||||
    for (auto& entry : m_->GetArray()) {
 | 
					    for (auto& entry : m_->GetArray()) {
 | 
				
			||||||
      JsonReader sub(&entry);
 | 
					      JsonReader sub(&entry);
 | 
				
			||||||
      fn(sub);
 | 
					      fn(sub);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    path_.pop_back();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void DoMember(const char* name, std::function<void(Reader&)> fn) override {
 | 
					  void DoMember(const char* name, std::function<void(Reader&)> fn) override {
 | 
				
			||||||
    if (m_->GetType() != rapidjson::Type::kObjectType)
 | 
					    path_.push_back(name);
 | 
				
			||||||
      return;  // FIXME: signal an error that object was not deserialized
 | 
					 | 
				
			||||||
               // correctly?
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    auto it = m_->FindMember(name);
 | 
					    auto it = m_->FindMember(name);
 | 
				
			||||||
    if (it != m_->MemberEnd()) {
 | 
					    if (it != m_->MemberEnd()) {
 | 
				
			||||||
      JsonReader sub(&it->value);
 | 
					      JsonReader sub(&it->value);
 | 
				
			||||||
      fn(sub);
 | 
					      fn(sub);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    path_.pop_back();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::string GetPath() const {
 | 
				
			||||||
 | 
					    std::string ret;
 | 
				
			||||||
 | 
					    for (auto& t : path_) {
 | 
				
			||||||
 | 
					      ret += '/';
 | 
				
			||||||
 | 
					      ret += t;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    ret.pop_back();
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -21,6 +21,7 @@ class MessagePackReader : public Reader {
 | 
				
			|||||||
    return SerializeFormat::MessagePack;
 | 
					    return SerializeFormat::MessagePack;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool IsBool() override { return oh_.get().type == msgpack::type::BOOLEAN; }
 | 
				
			||||||
  bool IsNull() override { return oh_.get().is_nil(); }
 | 
					  bool IsNull() override { return oh_.get().is_nil(); }
 | 
				
			||||||
  bool IsArray() override { return oh_.get().type == msgpack::type::ARRAY; }
 | 
					  bool IsArray() override { return oh_.get().type == msgpack::type::ARRAY; }
 | 
				
			||||||
  bool IsInt() override {
 | 
					  bool IsInt() override {
 | 
				
			||||||
@ -28,6 +29,8 @@ class MessagePackReader : public Reader {
 | 
				
			|||||||
           oh_.get().type == msgpack::type::NEGATIVE_INTEGER;
 | 
					           oh_.get().type == msgpack::type::NEGATIVE_INTEGER;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  bool IsInt64() override { return IsInt(); }
 | 
					  bool IsInt64() override { return IsInt(); }
 | 
				
			||||||
 | 
					  bool IsUint64() override { return IsInt(); }
 | 
				
			||||||
 | 
					  bool IsDouble() override { return oh_.get().type == msgpack::type::FLOAT64; };
 | 
				
			||||||
  bool IsString() override { return oh_.get().type == msgpack::type::STR; }
 | 
					  bool IsString() override { return oh_.get().type == msgpack::type::STR; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void GetNull() override { pk_->next(oh_); }
 | 
					  void GetNull() override { pk_->next(oh_); }
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user