// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/proxy_resolution/proxy_resolver_v8.h"

#include <algorithm>
#include <cstdio>
#include <utility>

#include "base/auto_reset.h"
#include "base/compiler_specific.h"
#include "base/debug/leak_annotations.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/strings/string_tokenizer.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread_task_runner_handle.h"
#include "gin/array_buffer.h"
#include "gin/public/isolate_holder.h"
#include "gin/v8_initializer.h"
#include "net/base/ip_address.h"
#include "net/base/net_errors.h"
#include "net/proxy_resolution/pac_file_data.h"
#include "net/proxy_resolution/pac_js_library.h"
#include "net/proxy_resolution/proxy_info.h"
#include "url/gurl.h"
#include "url/url_canon.h"
#include "v8/include/v8.h"

// Notes on the javascript environment:
//
// For the majority of the PAC utility functions, we use the same code
// as Firefox. See the javascript library that pac_js_library.h pulls in.
//
// In addition, we implement a subset of Microsoft's extensions to PAC.
// - myIpAddressEx()
// - dnsResolveEx()
// - isResolvableEx()
// - isInNetEx()
// - sortIpAddressList()
//
// It is worth noting that the original PAC specification does not describe
// the return values on failure. Consequently, there are compatibility
// differences between browsers on what to return on failure, which are
// illustrated below:
//
// --------------------+-------------+-------------------+--------------
//                     | Firefox3    | InternetExplorer8 |  --> Us <---
// --------------------+-------------+-------------------+--------------
// myIpAddress()       | "127.0.0.1" |  ???              |  "127.0.0.1"
// dnsResolve()        | null        |  false            |  null
// myIpAddressEx()     | N/A         |  ""               |  ""
// sortIpAddressList() | N/A         |  false            |  false
// dnsResolveEx()      | N/A         |  ""               |  ""
// isInNetEx()         | N/A         |  false            |  false
// --------------------+-------------+-------------------+--------------
//
// TODO(eroman): The cell above reading ??? means I didn't test it.
//
// Another difference is in how dnsResolve() and myIpAddress() are
// implemented -- whether they should restrict to IPv4 results, or
// include both IPv4 and IPv6. The following table illustrates the
// differences:
//
// --------------------+-------------+-------------------+--------------
//                     | Firefox3    | InternetExplorer8 |  --> Us <---
// --------------------+-------------+-------------------+--------------
// myIpAddress()       | IPv4/IPv6   |  IPv4             |  IPv4
// dnsResolve()        | IPv4/IPv6   |  IPv4             |  IPv4
// isResolvable()      | IPv4/IPv6   |  IPv4             |  IPv4
// myIpAddressEx()     | N/A         |  IPv4/IPv6        |  IPv4/IPv6
// dnsResolveEx()      | N/A         |  IPv4/IPv6        |  IPv4/IPv6
// sortIpAddressList() | N/A         |  IPv4/IPv6        |  IPv4/IPv6
// isResolvableEx()    | N/A         |  IPv4/IPv6        |  IPv4/IPv6
// isInNetEx()         | N/A         |  IPv4/IPv6        |  IPv4/IPv6
// -----------------+-------------+-------------------+--------------

namespace net {

namespace {

// Pseudo-name for the PAC script.
const char kPacResourceName[] = "proxy-pac-script.js";
// Pseudo-name for the PAC utility script.
const char kPacUtilityResourceName[] = "proxy-pac-utility-script.js";

// External string wrapper so V8 can access the UTF16 string wrapped by
// PacFileData.
class V8ExternalStringFromScriptData
    : public v8::String::ExternalStringResource {
 public:
  explicit V8ExternalStringFromScriptData(
      const scoped_refptr<PacFileData>& script_data)
      : script_data_(script_data) {}

  const uint16_t* data() const override {
    return reinterpret_cast<const uint16_t*>(script_data_->utf16().data());
  }

  size_t length() const override { return script_data_->utf16().size(); }

 private:
  const scoped_refptr<PacFileData> script_data_;
  DISALLOW_COPY_AND_ASSIGN(V8ExternalStringFromScriptData);
};

// External string wrapper so V8 can access a string literal.
class V8ExternalASCIILiteral
    : public v8::String::ExternalOneByteStringResource {
 public:
  // |ascii| must be a NULL-terminated C string, and must remain valid
  // throughout this object's lifetime.
  V8ExternalASCIILiteral(const char* ascii, size_t length)
      : ascii_(ascii), length_(length) {
    DCHECK(base::IsStringASCII(ascii));
  }

  const char* data() const override { return ascii_; }

  size_t length() const override { return length_; }

 private:
  const char* ascii_;
  size_t length_;
  DISALLOW_COPY_AND_ASSIGN(V8ExternalASCIILiteral);
};

// When creating a v8::String from a C++ string we have two choices: create
// a copy, or create a wrapper that shares the same underlying storage.
// For small strings it is better to just make a copy, whereas for large
// strings there are savings by sharing the storage. This number identifies
// the cutoff length for when to start wrapping rather than creating copies.
const size_t kMaxStringBytesForCopy = 256;

// Converts a V8 String to a UTF8 std::string.
std::string V8StringToUTF8(v8::Local<v8::String> s) {
  int len = s->Length();
  std::string result;
  if (len > 0)
    s->WriteUtf8(base::WriteInto(&result, len + 1));
  return result;
}

// Converts a V8 String to a UTF16 base::string16.
base::string16 V8StringToUTF16(v8::Local<v8::String> s) {
  int len = s->Length();
  base::string16 result;
  // Note that the reinterpret cast is because on Windows string16 is an alias
  // to wstring, and hence has character type wchar_t not uint16_t.
  if (len > 0) {
    s->Write(reinterpret_cast<uint16_t*>(base::WriteInto(&result, len + 1)), 0,
             len);
  }
  return result;
}

// Converts an ASCII std::string to a V8 string.
v8::Local<v8::String> ASCIIStringToV8String(v8::Isolate* isolate,
                                            const std::string& s) {
  DCHECK(base::IsStringASCII(s));
  return v8::String::NewFromUtf8(isolate, s.data(), v8::NewStringType::kNormal,
                                 s.size()).ToLocalChecked();
}

// Converts a UTF16 base::string16 (wrapped by a PacFileData) to a
// V8 string.
v8::Local<v8::String> ScriptDataToV8String(
    v8::Isolate* isolate,
    const scoped_refptr<PacFileData>& s) {
  if (s->utf16().size() * 2 <= kMaxStringBytesForCopy) {
    return v8::String::NewFromTwoByte(
               isolate, reinterpret_cast<const uint16_t*>(s->utf16().data()),
               v8::NewStringType::kNormal, s->utf16().size()).ToLocalChecked();
  }
  return v8::String::NewExternalTwoByte(
             isolate, new V8ExternalStringFromScriptData(s)).ToLocalChecked();
}

// Converts an ASCII string literal to a V8 string.
v8::Local<v8::String> ASCIILiteralToV8String(v8::Isolate* isolate,
                                             const char* ascii) {
  DCHECK(base::IsStringASCII(ascii));
  size_t length = strlen(ascii);
  if (length <= kMaxStringBytesForCopy)
    return v8::String::NewFromUtf8(isolate, ascii, v8::NewStringType::kNormal,
                                   length).ToLocalChecked();
  return v8::String::NewExternalOneByte(
             isolate, new V8ExternalASCIILiteral(ascii, length))
      .ToLocalChecked();
}

// Stringizes a V8 object by calling its toString() method. Returns true
// on success. This may fail if the toString() throws an exception.
bool V8ObjectToUTF16String(v8::Local<v8::Value> object,
                           base::string16* utf16_result,
                           v8::Isolate* isolate) {
  if (object.IsEmpty())
    return false;

  v8::HandleScope scope(isolate);
  v8::Local<v8::String> str_object;
  if (!object->ToString(isolate->GetCurrentContext()).ToLocal(&str_object))
    return false;
  *utf16_result = V8StringToUTF16(str_object);
  return true;
}

// Extracts an hostname argument from |args|. On success returns true
// and fills |*hostname| with the result.
bool GetHostnameArgument(const v8::FunctionCallbackInfo<v8::Value>& args,
                         std::string* hostname) {
  // The first argument should be a string.
  if (args.Length() == 0 || args[0].IsEmpty() || !args[0]->IsString())
    return false;

  const base::string16 hostname_utf16 =
      V8StringToUTF16(v8::Local<v8::String>::Cast(args[0]));

  // If the hostname is already in ASCII, simply return it as is.
  if (base::IsStringASCII(hostname_utf16)) {
    *hostname = base::UTF16ToASCII(hostname_utf16);
    return true;
  }

  // Otherwise try to convert it from IDN to punycode.
  const int kInitialBufferSize = 256;
  url::RawCanonOutputT<base::char16, kInitialBufferSize> punycode_output;
  if (!url::IDNToASCII(hostname_utf16.data(), hostname_utf16.length(),
                       &punycode_output)) {
    return false;
  }

  // |punycode_output| should now be ASCII; convert it to a std::string.
  // (We could use UTF16ToASCII() instead, but that requires an extra string
  // copy. Since ASCII is a subset of UTF8 the following is equivalent).
  bool success = base::UTF16ToUTF8(punycode_output.data(),
                             punycode_output.length(),
                             hostname);
  DCHECK(success);
  DCHECK(base::IsStringASCII(*hostname));
  return success;
}

// Wrapper around an IP address that stores the original string as well as a
// corresponding parsed IPAddress.

// This struct is used as a helper for sorting IP address strings - the IP
// literal is parsed just once and used as the sorting key, while also
// preserving the original IP literal string.
struct IPAddressSortingEntry {
  IPAddressSortingEntry(const std::string& ip_string,
                        const IPAddress& ip_address)
      : string_value(ip_string), ip_address(ip_address) {}

  // Used for sorting IP addresses in ascending order in SortIpAddressList().
  // IPv6 addresses are placed ahead of IPv4 addresses.
  bool operator<(const IPAddressSortingEntry& rhs) const {
    const IPAddress& ip1 = this->ip_address;
    const IPAddress& ip2 = rhs.ip_address;
    if (ip1.size() != ip2.size())
      return ip1.size() > ip2.size();  // IPv6 before IPv4.
    return ip1 < ip2;                  // Ascending order.
  }

  std::string string_value;
  IPAddress ip_address;
};

// Handler for "sortIpAddressList(IpAddressList)". |ip_address_list| is a
// semi-colon delimited string containing IP addresses.
// |sorted_ip_address_list| is the resulting list of sorted semi-colon delimited
// IP addresses or an empty string if unable to sort the IP address list.
// Returns 'true' if the sorting was successful, and 'false' if the input was an
// empty string, a string of separators (";" in this case), or if any of the IP
// addresses in the input list failed to parse.
bool SortIpAddressList(const std::string& ip_address_list,
                       std::string* sorted_ip_address_list) {
  sorted_ip_address_list->clear();

  // Strip all whitespace (mimics IE behavior).
  std::string cleaned_ip_address_list;
  base::RemoveChars(ip_address_list, " \t", &cleaned_ip_address_list);
  if (cleaned_ip_address_list.empty())
    return false;

  // Split-up IP addresses and store them in a vector.
  std::vector<IPAddressSortingEntry> ip_vector;
  IPAddress ip_address;
  base::StringTokenizer str_tok(cleaned_ip_address_list, ";");
  while (str_tok.GetNext()) {
    if (!ip_address.AssignFromIPLiteral(str_tok.token()))
      return false;
    ip_vector.push_back(IPAddressSortingEntry(str_tok.token(), ip_address));
  }

  if (ip_vector.empty())  // Can happen if we have something like
    return false;         // sortIpAddressList(";") or sortIpAddressList("; ;")

  DCHECK(!ip_vector.empty());

  // Sort lists according to ascending numeric value.
  if (ip_vector.size() > 1)
    std::stable_sort(ip_vector.begin(), ip_vector.end());

  // Return a semi-colon delimited list of sorted addresses (IPv6 followed by
  // IPv4).
  for (size_t i = 0; i < ip_vector.size(); ++i) {
    if (i > 0)
      *sorted_ip_address_list += ";";
    *sorted_ip_address_list += ip_vector[i].string_value;
  }
  return true;
}

// Handler for "isInNetEx(ip_address, ip_prefix)". |ip_address| is a string
// containing an IPv4/IPv6 address, and |ip_prefix| is a string containg a
// slash-delimited IP prefix with the top 'n' bits specified in the bit
// field. This returns 'true' if the address is in the same subnet, and
// 'false' otherwise. Also returns 'false' if the prefix is in an incorrect
// format, or if an address and prefix of different types are used (e.g. IPv6
// address and IPv4 prefix).
bool IsInNetEx(const std::string& ip_address, const std::string& ip_prefix) {
  IPAddress address;
  if (!address.AssignFromIPLiteral(ip_address))
    return false;

  IPAddress prefix;
  size_t prefix_length_in_bits;
  if (!ParseCIDRBlock(ip_prefix, &prefix, &prefix_length_in_bits))
    return false;

  // Both |address| and |prefix| must be of the same type (IPv4 or IPv6).
  if (address.size() != prefix.size())
    return false;

  DCHECK((address.IsIPv4() && prefix.IsIPv4()) ||
         (address.IsIPv6() && prefix.IsIPv6()));

  return IPAddressMatchesPrefix(address, prefix, prefix_length_in_bits);
}

// Consider only single component domains like 'foo' as plain host names.
bool IsPlainHostName(const std::string& hostname_utf8) {
  if (hostname_utf8.find('.') != std::string::npos)
    return false;

  // IPv6 literals might not contain any periods, however are not considered
  // plain host names.
  IPAddress unused;
  return !unused.AssignFromIPLiteral(hostname_utf8);
}

// All instances of ProxyResolverV8 share the same v8::Isolate. This isolate is
// created lazily the first time it is needed and lives until process shutdown.
// This creation might happen from any thread, as ProxyResolverV8 is typically
// run in a threadpool.
//
// TODO(eroman): The lazily created isolate is never freed. Instead it should be
// disposed once there are no longer any ProxyResolverV8 referencing it.
class SharedIsolateFactory {
 public:
  SharedIsolateFactory() : has_initialized_v8_(false) {}

  // Lazily creates a v8::Isolate, or returns the already created instance.
  v8::Isolate* GetSharedIsolate() {
    base::AutoLock lock(lock_);

    if (!holder_) {
      // Do one-time initialization for V8.
      if (!has_initialized_v8_) {
#ifdef V8_USE_EXTERNAL_STARTUP_DATA
        gin::V8Initializer::LoadV8Snapshot();
        gin::V8Initializer::LoadV8Natives();
#endif

        // The performance of the proxy resolver is limited by DNS resolution,
        // and not V8, so tune down V8 to use as little memory as possible.
        static const char kOptimizeForSize[] = "--optimize_for_size";
        v8::V8::SetFlagsFromString(kOptimizeForSize, strlen(kOptimizeForSize));
        static const char kNoOpt[] = "--noopt";
        v8::V8::SetFlagsFromString(kNoOpt, strlen(kNoOpt));

        gin::IsolateHolder::Initialize(
            gin::IsolateHolder::kNonStrictMode,
            gin::IsolateHolder::kStableV8Extras,
            gin::ArrayBufferAllocator::SharedInstance());

        has_initialized_v8_ = true;
      }

      holder_.reset(new gin::IsolateHolder(base::ThreadTaskRunnerHandle::Get(),
                                           gin::IsolateHolder::kUseLocker));
    }

    return holder_->isolate();
  }

  v8::Isolate* GetSharedIsolateWithoutCreating() {
    base::AutoLock lock(lock_);
    return holder_ ? holder_->isolate() : NULL;
  }

 private:
  base::Lock lock_;
  std::unique_ptr<gin::IsolateHolder> holder_;
  bool has_initialized_v8_;

  DISALLOW_COPY_AND_ASSIGN(SharedIsolateFactory);
};

base::LazyInstance<SharedIsolateFactory>::Leaky g_isolate_factory =
    LAZY_INSTANCE_INITIALIZER;

}  // namespace

// ProxyResolverV8::Context ---------------------------------------------------

class ProxyResolverV8::Context {
 public:
  explicit Context(v8::Isolate* isolate)
      : js_bindings_(nullptr), isolate_(isolate) {
    DCHECK(isolate);
  }

  ~Context() {
    v8::Locker locked(isolate_);
    v8::Isolate::Scope isolate_scope(isolate_);

    v8_this_.Reset();
    v8_context_.Reset();
  }

  JSBindings* js_bindings() { return js_bindings_; }

  int ResolveProxy(const GURL& query_url,
                   ProxyInfo* results,
                   JSBindings* bindings) {
    DCHECK(bindings);
    base::AutoReset<JSBindings*> bindings_reset(&js_bindings_, bindings);
    v8::Locker locked(isolate_);
    v8::Isolate::Scope isolate_scope(isolate_);
    v8::Isolate::SafeForTerminationScope safe_for_termination(isolate_);
    v8::HandleScope scope(isolate_);

    v8::Local<v8::Context> context =
        v8::Local<v8::Context>::New(isolate_, v8_context_);
    v8::Context::Scope function_scope(context);

    v8::Local<v8::Value> function;
    int rv = GetFindProxyForURL(&function);
    if (rv != OK)
      return rv;

    v8::Local<v8::Value> argv[] = {
      ASCIIStringToV8String(isolate_, query_url.spec()),
      ASCIIStringToV8String(isolate_, query_url.HostNoBrackets()),
    };

    v8::TryCatch try_catch(isolate_);
    v8::Local<v8::Value> ret;
    if (!v8::Function::Cast(*function)
             ->Call(context, context->Global(), arraysize(argv), argv)
             .ToLocal(&ret)) {
      DCHECK(try_catch.HasCaught());
      HandleError(try_catch.Message());
      return ERR_PAC_SCRIPT_FAILED;
    }

    if (!ret->IsString()) {
      js_bindings()->OnError(
          -1, base::ASCIIToUTF16("FindProxyForURL() did not return a string."));
      return ERR_PAC_SCRIPT_FAILED;
    }

    base::string16 ret_str = V8StringToUTF16(v8::Local<v8::String>::Cast(ret));

    if (!base::IsStringASCII(ret_str)) {
      // TODO(eroman): Rather than failing when a wide string is returned, we
      //               could extend the parsing to handle IDNA hostnames by
      //               converting them to ASCII punycode.
      //               crbug.com/47234
      base::string16 error_message =
          base::ASCIIToUTF16("FindProxyForURL() returned a non-ASCII string "
                             "(crbug.com/47234): ") + ret_str;
      js_bindings()->OnError(-1, error_message);
      return ERR_PAC_SCRIPT_FAILED;
    }

    results->UsePacString(base::UTF16ToASCII(ret_str));
    return OK;
  }

  int InitV8(const scoped_refptr<PacFileData>& pac_script,
             JSBindings* bindings) {
    base::AutoReset<JSBindings*> bindings_reset(&js_bindings_, bindings);
    v8::Locker locked(isolate_);
    v8::Isolate::Scope isolate_scope(isolate_);
    v8::HandleScope scope(isolate_);

    v8_this_.Reset(isolate_, v8::External::New(isolate_, this));
    v8::Local<v8::External> v8_this =
        v8::Local<v8::External>::New(isolate_, v8_this_);
    v8::Local<v8::ObjectTemplate> global_template =
        v8::ObjectTemplate::New(isolate_);

    // Attach the javascript bindings.
    v8::Local<v8::FunctionTemplate> alert_template =
        v8::FunctionTemplate::New(isolate_, &AlertCallback, v8_this);
    alert_template->RemovePrototype();
    global_template->Set(ASCIILiteralToV8String(isolate_, "alert"),
                         alert_template);

    v8::Local<v8::FunctionTemplate> my_ip_address_template =
        v8::FunctionTemplate::New(isolate_, &MyIpAddressCallback, v8_this);
    my_ip_address_template->RemovePrototype();
    global_template->Set(ASCIILiteralToV8String(isolate_, "myIpAddress"),
                         my_ip_address_template);

    v8::Local<v8::FunctionTemplate> dns_resolve_template =
        v8::FunctionTemplate::New(isolate_, &DnsResolveCallback, v8_this);
    dns_resolve_template->RemovePrototype();
    global_template->Set(ASCIILiteralToV8String(isolate_, "dnsResolve"),
                         dns_resolve_template);

    v8::Local<v8::FunctionTemplate> is_plain_host_name_template =
        v8::FunctionTemplate::New(isolate_, &IsPlainHostNameCallback, v8_this);
    is_plain_host_name_template->RemovePrototype();
    global_template->Set(ASCIILiteralToV8String(isolate_, "isPlainHostName"),
                         is_plain_host_name_template);

    // Microsoft's PAC extensions:

    v8::Local<v8::FunctionTemplate> dns_resolve_ex_template =
        v8::FunctionTemplate::New(isolate_, &DnsResolveExCallback, v8_this);
    dns_resolve_ex_template->RemovePrototype();
    global_template->Set(ASCIILiteralToV8String(isolate_, "dnsResolveEx"),
                         dns_resolve_ex_template);

    v8::Local<v8::FunctionTemplate> my_ip_address_ex_template =
        v8::FunctionTemplate::New(isolate_, &MyIpAddressExCallback, v8_this);
    my_ip_address_ex_template->RemovePrototype();
    global_template->Set(ASCIILiteralToV8String(isolate_, "myIpAddressEx"),
                         my_ip_address_ex_template);

    v8::Local<v8::FunctionTemplate> sort_ip_address_list_template =
        v8::FunctionTemplate::New(isolate_,
                                  &SortIpAddressListCallback,
                                  v8_this);
    sort_ip_address_list_template->RemovePrototype();
    global_template->Set(ASCIILiteralToV8String(isolate_, "sortIpAddressList"),
                         sort_ip_address_list_template);

    v8::Local<v8::FunctionTemplate> is_in_net_ex_template =
        v8::FunctionTemplate::New(isolate_, &IsInNetExCallback, v8_this);
    is_in_net_ex_template->RemovePrototype();
    global_template->Set(ASCIILiteralToV8String(isolate_, "isInNetEx"),
                         is_in_net_ex_template);

    v8_context_.Reset(
        isolate_, v8::Context::New(isolate_, NULL, global_template));

    v8::Local<v8::Context> context =
        v8::Local<v8::Context>::New(isolate_, v8_context_);
    v8::Context::Scope ctx(context);

    // Add the PAC utility functions to the environment.
    // (This script should never fail, as it is a string literal!)
    // Note that the two string literals are concatenated.
    int rv = RunScript(
        ASCIILiteralToV8String(isolate_, PAC_JS_LIBRARY PAC_JS_LIBRARY_EX),
        kPacUtilityResourceName);
    if (rv != OK) {
      NOTREACHED();
      return rv;
    }

    // Add the user's PAC code to the environment.
    rv =
        RunScript(ScriptDataToV8String(isolate_, pac_script), kPacResourceName);
    if (rv != OK)
      return rv;

    // At a minimum, the FindProxyForURL() function must be defined for this
    // to be a legitimiate PAC script.
    v8::Local<v8::Value> function;
    return GetFindProxyForURL(&function);
  }

 private:
  int GetFindProxyForURL(v8::Local<v8::Value>* function) {
    v8::Local<v8::Context> context =
        v8::Local<v8::Context>::New(isolate_, v8_context_);

    v8::TryCatch try_catch(isolate_);

    if (!context->Global()
             ->Get(context, ASCIILiteralToV8String(isolate_, "FindProxyForURL"))
             .ToLocal(function)) {
      DCHECK(try_catch.HasCaught());
      HandleError(try_catch.Message());
    }

    // The value should only be empty if an exception was thrown. Code
    // defensively just in case.
    DCHECK_EQ(function->IsEmpty(), try_catch.HasCaught());
    if (function->IsEmpty() || try_catch.HasCaught()) {
      js_bindings()->OnError(
          -1,
          base::ASCIIToUTF16("Accessing FindProxyForURL threw an exception."));
      return ERR_PAC_SCRIPT_FAILED;
    }

    if (!(*function)->IsFunction()) {
      js_bindings()->OnError(
          -1, base::ASCIIToUTF16(
                  "FindProxyForURL is undefined or not a function."));
      return ERR_PAC_SCRIPT_FAILED;
    }

    return OK;
  }

  // Handle an exception thrown by V8.
  void HandleError(v8::Local<v8::Message> message) {
    v8::Local<v8::Context> context =
        v8::Local<v8::Context>::New(isolate_, v8_context_);
    base::string16 error_message;
    int line_number = -1;

    if (!message.IsEmpty()) {
      auto maybe = message->GetLineNumber(context);
      if (maybe.IsJust())
        line_number = maybe.FromJust();
      V8ObjectToUTF16String(message->Get(), &error_message, isolate_);
    }

    js_bindings()->OnError(line_number, error_message);
  }

  // Compiles and runs |script| in the current V8 context.
  // Returns OK on success, otherwise an error code.
  int RunScript(v8::Local<v8::String> script, const char* script_name) {
    v8::Local<v8::Context> context =
        v8::Local<v8::Context>::New(isolate_, v8_context_);
    v8::TryCatch try_catch(isolate_);

    // Compile the script.
    v8::ScriptOrigin origin =
        v8::ScriptOrigin(ASCIILiteralToV8String(isolate_, script_name));
    v8::ScriptCompiler::Source script_source(script, origin);
    v8::Local<v8::Script> code;
    if (!v8::ScriptCompiler::Compile(
             context, &script_source, v8::ScriptCompiler::kNoCompileOptions,
             v8::ScriptCompiler::NoCacheReason::kNoCacheBecausePacScript)
             .ToLocal(&code)) {
      DCHECK(try_catch.HasCaught());
      HandleError(try_catch.Message());
      return ERR_PAC_SCRIPT_FAILED;
    }

    // Execute.
    auto result = code->Run(context);
    if (result.IsEmpty()) {
      DCHECK(try_catch.HasCaught());
      HandleError(try_catch.Message());
      return ERR_PAC_SCRIPT_FAILED;
    }

    return OK;
  }

  // V8 callback for when "alert()" is invoked by the PAC script.
  static void AlertCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {
    Context* context =
        static_cast<Context*>(v8::External::Cast(*args.Data())->Value());

    // Like firefox we assume "undefined" if no argument was specified, and
    // disregard any arguments beyond the first.
    base::string16 message;
    if (args.Length() == 0) {
      message = base::ASCIIToUTF16("undefined");
    } else {
      if (!V8ObjectToUTF16String(args[0], &message, args.GetIsolate()))
        return;  // toString() threw an exception.
    }

    context->js_bindings()->Alert(message);
  }

  // V8 callback for when "myIpAddress()" is invoked by the PAC script.
  static void MyIpAddressCallback(
      const v8::FunctionCallbackInfo<v8::Value>& args) {
    DnsResolveCallbackHelper(args, JSBindings::MY_IP_ADDRESS);
  }

  // V8 callback for when "myIpAddressEx()" is invoked by the PAC script.
  static void MyIpAddressExCallback(
      const v8::FunctionCallbackInfo<v8::Value>& args) {
    DnsResolveCallbackHelper(args, JSBindings::MY_IP_ADDRESS_EX);
  }

  // V8 callback for when "dnsResolve()" is invoked by the PAC script.
  static void DnsResolveCallback(
      const v8::FunctionCallbackInfo<v8::Value>& args) {
    DnsResolveCallbackHelper(args, JSBindings::DNS_RESOLVE);
  }

  // V8 callback for when "dnsResolveEx()" is invoked by the PAC script.
  static void DnsResolveExCallback(
      const v8::FunctionCallbackInfo<v8::Value>& args) {
    DnsResolveCallbackHelper(args, JSBindings::DNS_RESOLVE_EX);
  }

  // Shared code for implementing:
  //   - myIpAddress(), myIpAddressEx(), dnsResolve(), dnsResolveEx().
  static void DnsResolveCallbackHelper(
      const v8::FunctionCallbackInfo<v8::Value>& args,
      JSBindings::ResolveDnsOperation op) {
    Context* context =
        static_cast<Context*>(v8::External::Cast(*args.Data())->Value());

    std::string hostname;

    // dnsResolve() and dnsResolveEx() need at least 1 argument.
    if (op == JSBindings::DNS_RESOLVE || op == JSBindings::DNS_RESOLVE_EX) {
      if (!GetHostnameArgument(args, &hostname)) {
        if (op == JSBindings::DNS_RESOLVE)
          args.GetReturnValue().SetNull();
        return;
      }
    }

    std::string result;
    bool success;
    bool terminate = false;

    {
      v8::Unlocker unlocker(args.GetIsolate());
      success = context->js_bindings()->ResolveDns(
          hostname, op, &result, &terminate);
    }

    if (terminate)
      args.GetIsolate()->TerminateExecution();

    if (success) {
      args.GetReturnValue().Set(
          ASCIIStringToV8String(args.GetIsolate(), result));
      return;
    }

    // Each function handles resolution errors differently.
    switch (op) {
      case JSBindings::DNS_RESOLVE:
        args.GetReturnValue().SetNull();
        return;
      case JSBindings::DNS_RESOLVE_EX:
        args.GetReturnValue().SetEmptyString();
        return;
      case JSBindings::MY_IP_ADDRESS:
        args.GetReturnValue().Set(
            ASCIILiteralToV8String(args.GetIsolate(), "127.0.0.1"));
        return;
      case JSBindings::MY_IP_ADDRESS_EX:
        args.GetReturnValue().SetEmptyString();
        return;
    }

    NOTREACHED();
  }

  // V8 callback for when "sortIpAddressList()" is invoked by the PAC script.
  static void SortIpAddressListCallback(
      const v8::FunctionCallbackInfo<v8::Value>& args) {
    // We need at least one string argument.
    if (args.Length() == 0 || args[0].IsEmpty() || !args[0]->IsString()) {
      args.GetReturnValue().SetNull();
      return;
    }

    std::string ip_address_list =
        V8StringToUTF8(v8::Local<v8::String>::Cast(args[0]));
    if (!base::IsStringASCII(ip_address_list)) {
      args.GetReturnValue().SetNull();
      return;
    }
    std::string sorted_ip_address_list;
    bool success = SortIpAddressList(ip_address_list, &sorted_ip_address_list);
    if (!success) {
      args.GetReturnValue().Set(false);
      return;
    }
    args.GetReturnValue().Set(
        ASCIIStringToV8String(args.GetIsolate(), sorted_ip_address_list));
  }

  // V8 callback for when "isInNetEx()" is invoked by the PAC script.
  static void IsInNetExCallback(
      const v8::FunctionCallbackInfo<v8::Value>& args) {
    // We need at least 2 string arguments.
    if (args.Length() < 2 || args[0].IsEmpty() || !args[0]->IsString() ||
        args[1].IsEmpty() || !args[1]->IsString()) {
      args.GetReturnValue().SetNull();
      return;
    }

    std::string ip_address =
        V8StringToUTF8(v8::Local<v8::String>::Cast(args[0]));
    if (!base::IsStringASCII(ip_address)) {
      args.GetReturnValue().Set(false);
      return;
    }
    std::string ip_prefix =
        V8StringToUTF8(v8::Local<v8::String>::Cast(args[1]));
    if (!base::IsStringASCII(ip_prefix)) {
      args.GetReturnValue().Set(false);
      return;
    }
    args.GetReturnValue().Set(IsInNetEx(ip_address, ip_prefix));
  }

  // V8 callback for when "isPlainHostName()" is invoked by the PAC script.
  static void IsPlainHostNameCallback(
      const v8::FunctionCallbackInfo<v8::Value>& args) {
    // Need at least 1 string arguments.
    if (args.Length() < 1 || args[0].IsEmpty() || !args[0]->IsString()) {
      args.GetIsolate()->ThrowException(
          v8::Exception::TypeError(ASCIIStringToV8String(
              args.GetIsolate(), "Requires 1 string parameter")));
      return;
    }

    std::string hostname_utf8 =
        V8StringToUTF8(v8::Local<v8::String>::Cast(args[0]));
    args.GetReturnValue().Set(IsPlainHostName(hostname_utf8));
  }

  mutable base::Lock lock_;
  ProxyResolverV8::JSBindings* js_bindings_;
  v8::Isolate* isolate_;
  v8::Persistent<v8::External> v8_this_;
  v8::Persistent<v8::Context> v8_context_;
};

// ProxyResolverV8 ------------------------------------------------------------

ProxyResolverV8::ProxyResolverV8(std::unique_ptr<Context> context)
    : context_(std::move(context)) {
  DCHECK(context_);
}

ProxyResolverV8::~ProxyResolverV8() = default;

int ProxyResolverV8::GetProxyForURL(const GURL& query_url,
                                    ProxyInfo* results,
                                    ProxyResolverV8::JSBindings* bindings) {
  return context_->ResolveProxy(query_url, results, bindings);
}

// static
int ProxyResolverV8::Create(const scoped_refptr<PacFileData>& script_data,
                            ProxyResolverV8::JSBindings* js_bindings,
                            std::unique_ptr<ProxyResolverV8>* resolver) {
  DCHECK(script_data.get());
  DCHECK(js_bindings);

  if (script_data->utf16().empty())
    return ERR_PAC_SCRIPT_FAILED;

  // Try parsing the PAC script.
  std::unique_ptr<Context> context(
      new Context(g_isolate_factory.Get().GetSharedIsolate()));
  int rv = context->InitV8(script_data, js_bindings);
  if (rv == OK)
    resolver->reset(new ProxyResolverV8(std::move(context)));
  return rv;
}

// static
size_t ProxyResolverV8::GetTotalHeapSize() {
  v8::Isolate* isolate =
      g_isolate_factory.Get().GetSharedIsolateWithoutCreating();
  if (!isolate)
    return 0;

  v8::Locker locked(isolate);
  v8::Isolate::Scope isolate_scope(isolate);
  v8::HeapStatistics heap_statistics;
  isolate->GetHeapStatistics(&heap_statistics);
  return heap_statistics.total_heap_size();
}

// static
size_t ProxyResolverV8::GetUsedHeapSize() {
  v8::Isolate* isolate =
      g_isolate_factory.Get().GetSharedIsolateWithoutCreating();
  if (!isolate)
    return 0;

  v8::Locker locked(isolate);
  v8::Isolate::Scope isolate_scope(isolate);
  v8::HeapStatistics heap_statistics;
  isolate->GetHeapStatistics(&heap_statistics);
  return heap_statistics.used_heap_size();
}

}  // namespace net
