Roll third_party/inspector_protocol to 8cb7a4f50ff7d5b1b7f2e5df0542dc577c88bdc3
This roll includes: - [inspector_protocol] fixed compatibility with latest jinja 2.9.6 - [inspector_protocol] removed unused variable - Follow up on alph's review comments. - Provide default escape implementation for latin and wide strings. - Allow escaping utf8 strings in embedders that operate std::string. - Upload inspector_protocol changes to Gerrit by default - [inspector_protocol] Fix building with non-ASCII paths - [inspector_protocol] added StringUtil::toDouble method as requirement - Add const char* overloads to ErrorSupport BUG=chromium:743313 R=dgozman@chromium.org Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel Change-Id: Ic81a62c638bf592ae65c84055d53d926e50715ac Reviewed-on: https://chromium-review.googlesource.com/713538 Reviewed-by: Dmitry Gozman <dgozman@chromium.org> Commit-Queue: Aleksey Kozyatinskiy <kozyatinskiy@chromium.org> Cr-Commit-Position: refs/heads/master@{#48477}
This commit is contained in:
parent
a445b97cfd
commit
744b49ef0d
@ -121,6 +121,18 @@ std::unique_ptr<protocol::Value> StringUtil::parseJSON(const String16& string) {
|
||||
static_cast<int>(string.length()));
|
||||
}
|
||||
|
||||
// static
|
||||
void StringUtil::builderAppendQuotedString(StringBuilder& builder,
|
||||
const String& str) {
|
||||
builder.append('"');
|
||||
if (!str.isEmpty()) {
|
||||
escapeWideStringForJSON(
|
||||
reinterpret_cast<const uint16_t*>(str.characters16()),
|
||||
static_cast<int>(str.length()), &builder);
|
||||
}
|
||||
builder.append('"');
|
||||
}
|
||||
|
||||
} // namespace protocol
|
||||
|
||||
// static
|
||||
|
@ -49,6 +49,7 @@ class StringUtil {
|
||||
static void builderAppend(StringBuilder& builder, const char* s, size_t len) {
|
||||
builder.append(s, len);
|
||||
}
|
||||
static void builderAppendQuotedString(StringBuilder&, const String&);
|
||||
static void builderReserve(StringBuilder& builder, size_t capacity) {
|
||||
builder.reserveCapacity(capacity);
|
||||
}
|
||||
|
13
third_party/inspector_protocol/CodeGenerator.py
vendored
13
third_party/inspector_protocol/CodeGenerator.py
vendored
@ -59,12 +59,15 @@ def read_config():
|
||||
jinja_dir = arg_options.jinja_dir
|
||||
if not jinja_dir:
|
||||
raise Exception("jinja directory must be specified")
|
||||
jinja_dir = jinja_dir.decode('utf8')
|
||||
output_base = arg_options.output_base
|
||||
if not output_base:
|
||||
raise Exception("Base output directory must be specified")
|
||||
output_base = output_base.decode('utf8')
|
||||
config_file = arg_options.config
|
||||
if not config_file:
|
||||
raise Exception("Config file name must be specified")
|
||||
config_file = config_file.decode('utf8')
|
||||
config_base = os.path.dirname(config_file)
|
||||
config_values = arg_options.config_value
|
||||
if not config_values:
|
||||
@ -440,6 +443,12 @@ class Protocol(object):
|
||||
return self.check_options(self.config.protocol.options, domain, event, "include_events", "exclude_events", True)
|
||||
|
||||
|
||||
def generate_type(self, domain, typename):
|
||||
if not self.config.protocol.options:
|
||||
return domain in self.generate_domains
|
||||
return self.check_options(self.config.protocol.options, domain, typename, "include_types", "exclude_types", True)
|
||||
|
||||
|
||||
def is_async_command(self, domain, command):
|
||||
if not self.config.protocol.options:
|
||||
return False
|
||||
@ -473,6 +482,10 @@ class Protocol(object):
|
||||
return True
|
||||
|
||||
|
||||
def is_imported_dependency(self, domain):
|
||||
return domain in self.generate_domains or domain in self.imported_domains
|
||||
|
||||
|
||||
def main():
|
||||
jinja_dir, config_file, config = read_config()
|
||||
|
||||
|
2
third_party/inspector_protocol/README.v8
vendored
2
third_party/inspector_protocol/README.v8
vendored
@ -2,7 +2,7 @@ Name: inspector protocol
|
||||
Short Name: inspector_protocol
|
||||
URL: https://chromium.googlesource.com/deps/inspector_protocol/
|
||||
Version: 0
|
||||
Revision: 1a7cbe8ba8fa0d622586f549a97c73d9b52efbea
|
||||
Revision: 8cb7a4f50ff7d5b1b7f2e5df0542dc577c88bdc3
|
||||
License: BSD
|
||||
License File: LICENSE
|
||||
Security Critical: no
|
||||
|
@ -248,7 +248,13 @@ void UberDispatcher::registerBackend(const String& name, std::unique_ptr<protoco
|
||||
m_dispatchers[name] = std::move(dispatcher);
|
||||
}
|
||||
|
||||
DispatchResponse::Status UberDispatcher::dispatch(std::unique_ptr<Value> parsedMessage)
|
||||
void UberDispatcher::setupRedirects(const HashMap<String, String>& redirects)
|
||||
{
|
||||
for (const auto& pair : redirects)
|
||||
m_redirects[pair.first] = pair.second;
|
||||
}
|
||||
|
||||
DispatchResponse::Status UberDispatcher::dispatch(std::unique_ptr<Value> parsedMessage, int* outCallId, String* outMethod)
|
||||
{
|
||||
if (!parsedMessage) {
|
||||
reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kParseError, "Message must be a valid JSON");
|
||||
@ -263,6 +269,8 @@ DispatchResponse::Status UberDispatcher::dispatch(std::unique_ptr<Value> parsedM
|
||||
int callId = 0;
|
||||
protocol::Value* callIdValue = messageObject->get("id");
|
||||
bool success = callIdValue && callIdValue->asInteger(&callId);
|
||||
if (outCallId)
|
||||
*outCallId = callId;
|
||||
if (!success) {
|
||||
reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kInvalidRequest, "Message must have integer 'id' porperty");
|
||||
return DispatchResponse::kError;
|
||||
@ -271,11 +279,17 @@ DispatchResponse::Status UberDispatcher::dispatch(std::unique_ptr<Value> parsedM
|
||||
protocol::Value* methodValue = messageObject->get("method");
|
||||
String method;
|
||||
success = methodValue && methodValue->asString(&method);
|
||||
if (outMethod)
|
||||
*outMethod = method;
|
||||
if (!success) {
|
||||
reportProtocolErrorTo(m_frontendChannel, callId, DispatchResponse::kInvalidRequest, "Message must have string 'method' porperty", nullptr);
|
||||
return DispatchResponse::kError;
|
||||
}
|
||||
|
||||
HashMap<String, String>::iterator redirectIt = m_redirects.find(method);
|
||||
if (redirectIt != m_redirects.end())
|
||||
method = redirectIt->second;
|
||||
|
||||
size_t dotIndex = StringUtil::find(method, ".");
|
||||
if (dotIndex == StringUtil::kNotFound) {
|
||||
if (m_fallThroughForNotFound)
|
||||
|
@ -113,7 +113,8 @@ class {{config.lib.export_macro}} UberDispatcher {
|
||||
public:
|
||||
explicit UberDispatcher(FrontendChannel*);
|
||||
void registerBackend(const String& name, std::unique_ptr<protocol::DispatcherBase>);
|
||||
DispatchResponse::Status dispatch(std::unique_ptr<Value> message);
|
||||
void setupRedirects(const HashMap<String, String>&);
|
||||
DispatchResponse::Status dispatch(std::unique_ptr<Value> message, int* callId = nullptr, String* method = nullptr);
|
||||
FrontendChannel* channel() { return m_frontendChannel; }
|
||||
bool fallThroughForNotFound() { return m_fallThroughForNotFound; }
|
||||
void setFallThroughForNotFound(bool);
|
||||
@ -122,6 +123,7 @@ public:
|
||||
private:
|
||||
FrontendChannel* m_frontendChannel;
|
||||
bool m_fallThroughForNotFound;
|
||||
HashMap<String, String> m_redirects;
|
||||
protocol::HashMap<String, std::unique_ptr<protocol::DispatcherBase>> m_dispatchers;
|
||||
};
|
||||
|
||||
|
@ -11,6 +11,11 @@ namespace {{namespace}} {
|
||||
ErrorSupport::ErrorSupport() { }
|
||||
ErrorSupport::~ErrorSupport() { }
|
||||
|
||||
void ErrorSupport::setName(const char* name)
|
||||
{
|
||||
setName(String(name));
|
||||
}
|
||||
|
||||
void ErrorSupport::setName(const String& name)
|
||||
{
|
||||
DCHECK(m_path.size());
|
||||
@ -27,6 +32,11 @@ void ErrorSupport::pop()
|
||||
m_path.pop_back();
|
||||
}
|
||||
|
||||
void ErrorSupport::addError(const char* error)
|
||||
{
|
||||
addError(String(error));
|
||||
}
|
||||
|
||||
void ErrorSupport::addError(const String& error)
|
||||
{
|
||||
StringBuilder builder;
|
||||
|
@ -17,8 +17,10 @@ public:
|
||||
~ErrorSupport();
|
||||
|
||||
void push();
|
||||
void setName(const char*);
|
||||
void setName(const String&);
|
||||
void pop();
|
||||
void addError(const char*);
|
||||
void addError(const String&);
|
||||
bool hasErrors();
|
||||
String errors();
|
||||
|
@ -42,30 +42,22 @@ void appendUnsignedAsHex(uint16_t number, StringBuilder* dst)
|
||||
}
|
||||
}
|
||||
|
||||
void escapeStringForJSON(const String& str, StringBuilder* dst)
|
||||
template <typename Char>
|
||||
void escapeStringForJSONInternal(const Char* str, unsigned len,
|
||||
StringBuilder* dst)
|
||||
{
|
||||
for (unsigned i = 0; i < str.length(); ++i) {
|
||||
uint16_t c = str[i];
|
||||
if (!escapeChar(c, dst)) {
|
||||
if (c < 32 || c > 126 || c == '<' || c == '>') {
|
||||
// 1. Escaping <, > to prevent script execution.
|
||||
// 2. Technically, we could also pass through c > 126 as UTF8, but this
|
||||
// is also optional. It would also be a pain to implement here.
|
||||
appendUnsignedAsHex(c, dst);
|
||||
} else {
|
||||
StringUtil::builderAppend(*dst, c);
|
||||
}
|
||||
for (unsigned i = 0; i < len; ++i) {
|
||||
Char c = str[i];
|
||||
if (escapeChar(c, dst))
|
||||
continue;
|
||||
if (c < 32 || c > 126) {
|
||||
appendUnsignedAsHex(c, dst);
|
||||
} else {
|
||||
StringUtil::builderAppend(*dst, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void doubleQuoteStringForJSON(const String& str, StringBuilder* dst)
|
||||
{
|
||||
StringUtil::builderAppend(*dst, '"');
|
||||
escapeStringForJSON(str, dst);
|
||||
StringUtil::builderAppend(*dst, '"');
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
bool Value::asBoolean(bool*) const
|
||||
@ -181,7 +173,7 @@ bool StringValue::asString(String* output) const
|
||||
void StringValue::writeJSON(StringBuilder* output) const
|
||||
{
|
||||
DCHECK(type() == TypeString);
|
||||
doubleQuoteStringForJSON(m_stringValue, output);
|
||||
StringUtil::builderAppendQuotedString(*output, m_stringValue);
|
||||
}
|
||||
|
||||
std::unique_ptr<Value> StringValue::clone() const
|
||||
@ -336,7 +328,7 @@ void DictionaryValue::writeJSON(StringBuilder* output) const
|
||||
CHECK(it != m_data.end());
|
||||
if (i)
|
||||
StringUtil::builderAppend(*output, ',');
|
||||
doubleQuoteStringForJSON(it->first, output);
|
||||
StringUtil::builderAppendQuotedString(*output, it->first);
|
||||
StringUtil::builderAppend(*output, ':');
|
||||
it->second->writeJSON(output);
|
||||
}
|
||||
@ -402,6 +394,16 @@ protocol::Value* ListValue::at(size_t index)
|
||||
return m_data[index].get();
|
||||
}
|
||||
|
||||
void escapeLatinStringForJSON(const uint8_t* str, unsigned len, StringBuilder* dst)
|
||||
{
|
||||
escapeStringForJSONInternal<uint8_t>(str, len, dst);
|
||||
}
|
||||
|
||||
void escapeWideStringForJSON(const uint16_t* str, unsigned len, StringBuilder* dst)
|
||||
{
|
||||
escapeStringForJSONInternal<uint16_t>(str, len, dst);
|
||||
}
|
||||
|
||||
{% for namespace in config.protocol.namespace %}
|
||||
} // namespace {{namespace}}
|
||||
{% endfor %}
|
||||
|
@ -239,6 +239,9 @@ private:
|
||||
std::vector<std::unique_ptr<Value>> m_data;
|
||||
};
|
||||
|
||||
void escapeLatinStringForJSON(const uint8_t* str, unsigned len, StringBuilder* dst);
|
||||
void escapeWideStringForJSON(const uint16_t* str, unsigned len, StringBuilder* dst);
|
||||
|
||||
{% for namespace in config.protocol.namespace %}
|
||||
} // namespace {{namespace}}
|
||||
{% endfor %}
|
||||
|
@ -19,6 +19,7 @@ const char Metainfo::domainName[] = "{{domain.domain}}";
|
||||
const char Metainfo::commandPrefix[] = "{{domain.domain}}.";
|
||||
const char Metainfo::version[] = "{{domain.version}}";
|
||||
{% for type in domain.types %}
|
||||
{% if not protocol.generate_type(domain.domain, type.id) %}{% continue %} {% endif %}
|
||||
{% if "enum" in type %}
|
||||
|
||||
namespace {{type.id}}Enum {
|
||||
@ -200,18 +201,23 @@ public:
|
||||
, m_backend(backend)
|
||||
, m_fallThroughForNotFound(fallThroughForNotFound) {
|
||||
{% for command in domain.commands %}
|
||||
{% if "redirect" in command %}{% continue %}{% endif %}
|
||||
{% if "redirect" in command %}
|
||||
m_redirects["{{domain.domain}}.{{command.name}}"] = "{{command.redirect}}.{{command.name}}";
|
||||
{% continue %}
|
||||
{% endif %}
|
||||
{% if not protocol.generate_command(domain.domain, command.name) %}{% continue %}{% endif %}
|
||||
m_dispatchMap["{{domain.domain}}.{{command.name}}"] = &DispatcherImpl::{{command.name}};
|
||||
{% endfor %}
|
||||
}
|
||||
~DispatcherImpl() override { }
|
||||
DispatchResponse::Status dispatch(int callId, const String& method, std::unique_ptr<protocol::DictionaryValue> messageObject) override;
|
||||
HashMap<String, String>& redirects() { return m_redirects; }
|
||||
|
||||
protected:
|
||||
using CallHandler = DispatchResponse::Status (DispatcherImpl::*)(int callId, std::unique_ptr<DictionaryValue> messageObject, ErrorSupport* errors);
|
||||
using DispatchMap = protocol::HashMap<String, CallHandler>;
|
||||
DispatchMap m_dispatchMap;
|
||||
HashMap<String, String> m_redirects;
|
||||
|
||||
{% for command in domain.commands %}
|
||||
{% if "redirect" in command %}{% continue %}{% endif %}
|
||||
@ -337,9 +343,9 @@ DispatchResponse::Status DispatcherImpl::{{command.name}}(int callId, std::uniqu
|
||||
&out_{{parameter.name}}
|
||||
{%- endfor %}
|
||||
{% endif %});
|
||||
{% if "returns" in command %}
|
||||
if (response.status() == DispatchResponse::kFallThrough)
|
||||
return response.status();
|
||||
{% if "returns" in command %}
|
||||
std::unique_ptr<protocol::DictionaryValue> result = DictionaryValue::create();
|
||||
if (response.status() == DispatchResponse::kSuccess) {
|
||||
{% for parameter in command.returns %}
|
||||
@ -378,9 +384,11 @@ DispatchResponse::Status DispatcherImpl::{{command.name}}(int callId, std::uniqu
|
||||
{% endfor %}
|
||||
|
||||
// static
|
||||
void Dispatcher::wire(UberDispatcher* dispatcher, Backend* backend)
|
||||
void Dispatcher::wire(UberDispatcher* uber, Backend* backend)
|
||||
{
|
||||
dispatcher->registerBackend("{{domain.domain}}", std::unique_ptr<protocol::DispatcherBase>(new DispatcherImpl(dispatcher->channel(), backend, dispatcher->fallThroughForNotFound())));
|
||||
std::unique_ptr<DispatcherImpl> dispatcher(new DispatcherImpl(uber->channel(), backend, uber->fallThroughForNotFound()));
|
||||
uber->setupRedirects(dispatcher->redirects());
|
||||
uber->registerBackend("{{domain.domain}}", std::move(dispatcher));
|
||||
}
|
||||
|
||||
} // {{domain.domain}}
|
||||
|
@ -14,7 +14,9 @@
|
||||
// For each imported domain we generate a ValueConversions struct instead of a full domain definition
|
||||
// and include Domain::API version from there.
|
||||
{% for name in domain.dependencies %}
|
||||
{% if protocol.is_imported_dependency(name) %}
|
||||
#include {{format_include(config.protocol.package, name)}}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% if protocol.is_exported_domain(domain.domain) %}
|
||||
#include {{format_include(config.exported.package, domain.domain)}}
|
||||
@ -27,6 +29,7 @@ namespace {{domain.domain}} {
|
||||
|
||||
// ------------- Forward and enum declarations.
|
||||
{% for type in domain.types %}
|
||||
{% if not protocol.generate_type(domain.domain, type.id) %}{% continue %}{% endif %}
|
||||
{% if type.type == "object" %}
|
||||
{% if "properties" in type %}
|
||||
// {{type.description}}
|
||||
@ -41,6 +44,7 @@ using {{type.id}} = {{protocol.resolve_type(type).type}};
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% for type in domain.types %}
|
||||
{% if not protocol.generate_type(domain.domain, type.id) %}{% continue %}{% endif %}
|
||||
{% if "enum" in type %}
|
||||
|
||||
namespace {{type.id}}Enum {
|
||||
@ -67,6 +71,7 @@ namespace {{param.name | to_title_case}}Enum {
|
||||
|
||||
// ------------- Type and builder declarations.
|
||||
{% for type in domain.types %}
|
||||
{% if not protocol.generate_type(domain.domain, type.id) %}{% continue %}{% endif %}
|
||||
{% if not (type.type == "object") or not ("properties" in type) %}{% continue %}{% endif %}
|
||||
|
||||
// {{type.description}}
|
||||
@ -110,12 +115,8 @@ public:
|
||||
public:
|
||||
enum {
|
||||
NoFieldsSet = 0,
|
||||
{% set count = 0 %}
|
||||
{% for property in type.properties %}
|
||||
{% if not(property.optional) %}
|
||||
{% set count = count + 1 %}
|
||||
{{property.name | to_title_case}}Set = 1 << {{count}},
|
||||
{% endif %}
|
||||
{% for property in type.properties|rejectattr("optional") %}
|
||||
{{property.name | to_title_case}}Set = 1 << {{loop.index}},
|
||||
{% endfor %}
|
||||
AllFieldsSet = (
|
||||
{%- for property in type.properties %}
|
||||
|
Loading…
Reference in New Issue
Block a user