// 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 "starboard/common/string.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::Isolate* isolate, v8::Local<v8::String> s) {
  int len = s->Length();
  std::string result;
  if (len > 0)
    s->WriteUtf8(isolate, base::WriteInto(&result, len + 1));
  return result;
}

// Converts a V8 String to a UTF16 base::string16.
base::string16 V8StringToUTF16(v8::Isolate* isolate, 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(isolate,
             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(isolate, 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(args.GetIsolate(), 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,
          gin::IsolateHolder::IsolateType::kUtility));
    }

    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(isolate_, 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(args.GetIsolate(), 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(args.GetIsolate(), v8::Local<v8::String>::Cast(args[0]));
    if (!base::IsStringASCII(ip_address)) {
      args.GetReturnValue().Set(false);
      return;
    }
    std::string ip_prefix =
        V8StringToUTF8(args.GetIsolate(), 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(args.GetIsolate(), 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
