Improve sanitization of remoteFrontendUrl in DevTools

This change ensures that the decoded remoteFrontendUrl parameter cannot
contain any single quote in its value. As of this commit, none of the
permitted query params in SanitizeFrontendQueryParam can contain single
quotes.
Note that the existing SanitizeEndpoint function does not explicitly
check for single quotes. This is fine since single quotes in the query
string are already URL-encoded and the values validated by
SanitizeEndpoint are not url-decoded elsewhere.

BUG=798163
TEST=Manually, see https://crbug.com/798163#c1
TEST=./unit_tests --gtest_filter=DevToolsUIBindingsTest.SanitizeFrontendURL

Change-Id: I5a08e8ce6f1abc2c8d2a0983fef63e1e194cd242
Reviewed-on: https://chromium-review.googlesource.com/846979
Reviewed-by: Dmitry Gozman <dgozman@chromium.org>
Commit-Queue: Rob Wu <rob@robwu.nl>
Cr-Commit-Position: refs/heads/master@{#527250}
void DevToolsUIBindings::DispatchProtocolMessage(
    content::DevToolsAgentHost* agent_host, const std::string& message) {
  DCHECK(agent_host == agent_host_.get());
  if (!frontend_host_ || reloading_)
    return;

  if (message.length() < kMaxMessageChunkSize) {
    std::string param;
    base::EscapeJSONString(message, true, &param);
    base::string16 javascript =
        base::UTF8ToUTF16("DevToolsAPI.dispatchMessage(" + param + ");");
    web_contents_->GetMainFrame()->ExecuteJavaScript(javascript);
    return;
  }

  base::Value total_size(static_cast<int>(message.length()));
  for (size_t pos = 0; pos < message.length(); pos += kMaxMessageChunkSize) {
    base::Value message_value(message.substr(pos, kMaxMessageChunkSize));
    CallClientFunction("DevToolsAPI.dispatchMessageChunk",
                       &message_value, pos ? NULL : &total_size, NULL);
  }
}

void DevToolsUIBindings::DispatchProtocolMessage(
    content::DevToolsAgentHost* agent_host, const std::string& message) {
  DCHECK(agent_host == agent_host_.get());
  if (!frontend_host_ || reloading_)
    return;

  if (message.length() < kMaxMessageChunkSize) {
    std::string param;
    base::EscapeJSONString(message, true, &param);
    base::string16 javascript =
        base::UTF8ToUTF16("DevToolsAPI.dispatchMessage(" + param + ");");
    web_contents_->GetMainFrame()->ExecuteJavaScript(javascript);
    return;
  }

  base::Value total_size(static_cast<int>(message.length()));
  for (size_t pos = 0; pos < message.length(); pos += kMaxMessageChunkSize) {
    base::Value message_value(message.substr(pos, kMaxMessageChunkSize));
    CallClientFunction("DevToolsAPI.dispatchMessageChunk",
                       &message_value, pos ? NULL : &total_size, NULL);
  }
}
