Merge cherrypicks of [14126781, 14126782, 14127202, 14128466, 14127516, 14128057, 14127204, 14128747, 14128708, 14128059, 14128686, 14128127, 14128507, 14128809, 14128810, 14128811, 14128812] into security-aosp-pi-release

Change-Id: Ifc7ce70b253dbcdfe6192887206102cfddf7d75f
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..b9f159e
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,28 @@
+cc_library_shared {
+    name: "libpac",
+
+    srcs: [
+        "src/proxy_resolver_v8.cc",
+        "src/proxy_resolver_js_bindings.cc",
+        "src/net_util.cc",
+    ],
+
+    cflags: [
+        "-Wno-endif-labels",
+        "-Wno-import",
+        "-Wno-format",
+        "-Wno-unused-parameter",
+        "-Wno-non-virtual-dtor",
+        "-Werror",
+    ],
+
+    local_include_dirs: ["src"],
+
+    static_libs: ["libv8"],
+
+    shared_libs: [
+        "libutils",
+        "liblog",
+    ],
+
+}
diff --git a/Android.mk b/Android.mk
deleted file mode 100644
index ae0e768..0000000
--- a/Android.mk
+++ /dev/null
@@ -1,33 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
-
-LOCAL_CPP_EXTENSION := .cc
-
-# Set up the target identity
-LOCAL_MODULE := libpac
-LOCAL_MODULE_CLASS := SHARED_LIBRARIES
-
-LOCAL_SRC_FILES := \
-  src/proxy_resolver_v8.cc \
-  src/proxy_resolver_js_bindings.cc \
-  src/net_util.cc
-
-LOCAL_CFLAGS += \
-  -Wno-endif-labels \
-  -Wno-import \
-  -Wno-format \
-  -Wno-unused-parameter \
-  -Werror
-
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/src $(LOCAL_PATH)/../v8
-
-LOCAL_STATIC_LIBRARIES := libv8
-
-LOCAL_SHARED_LIBRARIES := libutils liblog libicuuc libicui18n
-
-LOCAL_CXX_STL := libc++
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(LOCAL_PATH)/test/Android.mk
diff --git a/src/proxy_resolver_v8.cc b/src/proxy_resolver_v8.cc
index 5d8b776..28cf1a7 100644
--- a/src/proxy_resolver_v8.cc
+++ b/src/proxy_resolver_v8.cc
@@ -148,17 +148,19 @@
 }
 
 // Converts a V8 String to a UTF8 std::string.
-std::string V8StringToUTF8(v8::Handle<v8::String> s) {
+std::string V8StringToUTF8(v8::Isolate* isolate, v8::Handle<v8::String> s) {
+  int len = s->Length();
   std::string result;
-  s->WriteUtf8(WriteInto(&result, s->Length() + 1));
+  if (len > 0)
+    s->WriteUtf8(isolate, WriteInto(&result, len + 1));
   return result;
 }
 
 // Converts a V8 String to a UTF16 string.
-android::String16 V8StringToUTF16(v8::Handle<v8::String> s) {
+android::String16 V8StringToUTF16(v8::Isolate* isolate, v8::Handle<v8::String> s) {
   int len = s->Length();
   char16_t* buf = new char16_t[len + 1];
-  s->Write(reinterpret_cast<uint16_t*>(buf), 0, len);
+  s->Write(isolate, reinterpret_cast<uint16_t*>(buf), 0, len);
   android::String16 ret(buf, len);
   delete[] buf;
   return ret;
@@ -171,13 +173,13 @@
 
 // Converts an ASCII std::string to a V8 string.
 v8::Local<v8::String> ASCIIStringToV8String(v8::Isolate* isolate, const std::string& s) {
-  return v8::String::NewFromUtf8(isolate, s.data(), v8::String::kNormalString, s.size());
+  return v8::String::NewFromUtf8(isolate, s.data(), v8::NewStringType::kNormal, s.size()).ToLocalChecked();
 }
 
 v8::Local<v8::String> UTF16StringToV8String(v8::Isolate* isolate, const android::String16& s) {
   return v8::String::NewFromTwoByte(
       isolate, reinterpret_cast<const uint16_t*>(s.string()),
-      v8::String::kNormalString, s.size());
+      v8::NewStringType::kNormal, s.size()).ToLocalChecked();
 }
 
 // Converts an ASCII string literal to a V8 string.
@@ -185,8 +187,8 @@
 //  DCHECK(IsStringASCII(ascii));
   size_t length = strlen(ascii);
   if (length <= kMaxStringBytesForCopy)
-    return v8::String::NewFromUtf8(isolate, ascii, v8::String::kNormalString, length);
-  return v8::String::NewExternal(isolate, new V8ExternalASCIILiteral(ascii, length));
+    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
@@ -198,10 +200,11 @@
     return false;
 
   v8::HandleScope scope(isolate);
-  v8::Local<v8::String> str_object = object->ToString();
-  if (str_object.IsEmpty())
+  v8::Local<v8::String> str_object;
+
+  if (!object->ToString(isolate->GetCurrentContext()).ToLocal(&str_object))
     return false;
-  *utf16_result = V8StringToUTF16(str_object);
+  *utf16_result = V8StringToUTF16(isolate, str_object);
   return true;
 }
 
@@ -212,7 +215,7 @@
   if (args.Length() == 0 || args[0].IsEmpty() || !args[0]->IsString())
     return false;
 
-  const android::String16 hostname_utf16 = V8StringToUTF16(args[0]->ToString());
+  const android::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 (IsStringASCII(hostname_utf16)) {
@@ -392,13 +395,11 @@
         UTF16StringToV8String(isolate_, url),
         UTF16StringToV8String(isolate_, host) };
 
-    v8::TryCatch try_catch;
-    v8::Local<v8::Value> ret = v8::Function::Cast(*function)->Call(
-        context->Global(), 2, argv);
-
-    if (try_catch.HasCaught()) {
-      error_listener_->ErrorMessage(
-          V8StringToUTF16(try_catch.Message()->Get()));
+    v8::TryCatch try_catch(isolate_);
+    v8::Local<v8::Value> ret;
+    if (!v8::Function::Cast(*function)->Call(
+        context, context->Global(), 2, argv).ToLocal(&ret)) {
+      error_listener_->ErrorMessage(V8StringToUTF16(isolate_, try_catch.Message()->Get()));
       return ERR_PAC_SCRIPT_FAILED;
     }
 
@@ -408,7 +409,7 @@
       return ERR_PAC_SCRIPT_FAILED;
     }
 
-    *results = V8StringToUTF16(ret->ToString());
+    *results = V8StringToUTF16(isolate_, v8::Local<v8::String>::Cast(ret));
 
     if (!IsStringASCII(*results)) {
       // TODO:         Rather than failing when a wide string is returned, we
@@ -431,7 +432,7 @@
     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();
+    v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(isolate_);
 
     // Attach the javascript bindings.
     v8::Local<v8::FunctionTemplate> alert_template =
@@ -514,34 +515,61 @@
   bool GetFindProxyForURL(v8::Local<v8::Value>* function) {
     v8::Local<v8::Context> context =
         v8::Local<v8::Context>::New(isolate_, v8_context_);
-    *function = context->Global()->Get(
-        ASCIILiteralToV8String(isolate_, "FindProxyForURL"));
-    return (*function)->IsFunction();
+
+    v8::TryCatch try_catch(isolate_);
+
+    if (!context->Global()
+        ->Get(context, ASCIILiteralToV8String(isolate_, "FindProxyForURL"))
+        .ToLocal(function)) {
+      HandleError(try_catch.Message());
+    // Fall through since try_catch.HasCaught() will be true
+    }
+
+    if (function->IsEmpty() || try_catch.HasCaught()) {
+      error_listener_->ErrorMessage(android::String16(
+          "Accessing FindProxyForURL threw an exception."));
+      return false;
+    }
+
+    if (!(*function)->IsFunction()) {
+      error_listener_->ErrorMessage(android::String16(
+          "FindProxyForURL is undefined or not a function."));
+      return false;
+    }
+
+    return true;
   }
 
   // Handle an exception thrown by V8.
   void HandleError(v8::Handle<v8::Message> message) {
     if (message.IsEmpty())
       return;
-    error_listener_->ErrorMessage(V8StringToUTF16(message->Get()));
+    error_listener_->ErrorMessage(V8StringToUTF16(isolate_, message->Get()));
   }
 
   // Compiles and runs |script| in the current V8 context.
   // Returns OK on success, otherwise an error code.
   int RunScript(v8::Handle<v8::String> script, const char* script_name) {
-    v8::TryCatch try_catch;
+    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::Local<v8::Script> code = v8::Script::Compile(script, &origin);
+    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)) {
+      HandleError(try_catch.Message());
+      return ERR_PAC_SCRIPT_FAILED;
+    }
 
     // Execute.
-    if (!code.IsEmpty())
-      code->Run();
-
-    // Check for errors.
-    if (try_catch.HasCaught()) {
+    auto result = code->Run(context);
+    if (result.IsEmpty()) {
       HandleError(try_catch.Message());
       return ERR_PAC_SCRIPT_FAILED;
     }
@@ -679,7 +707,7 @@
       return;
     }
 
-    std::string ip_address_list = V8StringToUTF8(args[0]->ToString());
+    std::string ip_address_list = V8StringToUTF8(args.GetIsolate(), v8::Local<v8::String>::Cast(args[0]));
     std::string sorted_ip_address_list;
     bool success = SortIpAddressList(ip_address_list, &sorted_ip_address_list);
     if (!success) {
@@ -698,8 +726,8 @@
       return;
     }
 
-    std::string ip_address = V8StringToUTF8(args[0]->ToString());
-    std::string ip_prefix = V8StringToUTF8(args[1]->ToString());
+    std::string ip_address = V8StringToUTF8(args.GetIsolate(), v8::Local<v8::String>::Cast(args[0]));
+    std::string ip_prefix = V8StringToUTF8(args.GetIsolate(), v8::Local<v8::String>::Cast(args[1]));
     args.GetReturnValue().Set(IsInNetEx(ip_address, ip_prefix));
   }
 
@@ -720,8 +748,8 @@
     : context_(NULL), js_bindings_(custom_js_bindings),
       error_listener_(error_listener) {
   if (!initialized_for_this_process_) {
-    v8::Platform* platform = v8::platform::CreateDefaultPlatform();
-    v8::V8::InitializePlatform(platform);
+    static std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
+    v8::V8::InitializePlatform(platform.get());
     v8::V8::Initialize();
     initialized_for_this_process_ = true;
   }