[automerger skipped] Upgrade V8 to 8.8.278.14 am: 204ba1d12f -s ours
am skip reason: Change-Id I2b2e3d4f8fc99d160b228efb9b96ad6018453e09 with SHA-1 9295700ee7 is in history
Original change: https://googleplex-android-review.googlesource.com/c/platform/external/chromium-libpac/+/13580728
MUST ONLY BE SUBMITTED BY AUTOMERGER
Change-Id: I49a706aa75bc040fb06b496ca5d89ed62092dab7
diff --git a/Android.bp b/Android.bp
index b9f159e..b552038 100644
--- a/Android.bp
+++ b/Android.bp
@@ -3,6 +3,7 @@
srcs: [
"src/proxy_resolver_v8.cc",
+ "src/proxy_resolver_v8_wrapper.cc",
"src/proxy_resolver_js_bindings.cc",
"src/net_util.cc",
],
@@ -16,13 +17,21 @@
"-Werror",
],
+ export_include_dirs: ["includes"],
local_include_dirs: ["src"],
static_libs: ["libv8"],
shared_libs: [
- "libutils",
"liblog",
+ "libicuuc",
+ "libicui18n",
],
+ stubs: {
+ symbol_file: "libpac.map.txt",
+ versions: [
+ "1",
+ ],
+ },
}
diff --git a/LICENSE b/LICENSE
index 8dc3504..fd537da 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,3 +1,42 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Akhil Arora <akhil.arora@sun.com>
+ * Tomi Leppikangas <Tomi.Leppikangas@oulu.fi>
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/MODULE_LICENSE_BSD b/MODULE_LICENSE_BSD
deleted file mode 100644
index e69de29..0000000
--- a/MODULE_LICENSE_BSD
+++ /dev/null
diff --git a/NOTICE b/NOTICE
deleted file mode 100644
index 8dc3504..0000000
--- a/NOTICE
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/NOTICE b/NOTICE
new file mode 120000
index 0000000..7a694c9
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1 @@
+LICENSE
\ No newline at end of file
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 0000000..995d180
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1,4 @@
+# Default code reviewers picked from top 3 or more developers.
+# Please update this list if you find better candidates.
+pgrafov@google.com
+rubinxu@google.com
diff --git a/includes/proxy_resolver_v8_wrapper.h b/includes/proxy_resolver_v8_wrapper.h
new file mode 100644
index 0000000..776a45d
--- /dev/null
+++ b/includes/proxy_resolver_v8_wrapper.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef NET_PROXY_PROXY_RESOLVER_V8_WRAPPER_H_
+#define NET_PROXY_PROXY_RESOLVER_V8_WRAPPER_H_
+
+// This header should be compatible with C or C++ compiler
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define OK 0
+#define ERR_PAC_SCRIPT_FAILED -1
+#define ERR_FAILED -2
+
+/**
+* Declare an incomplete type ProxyResolverV8Handle. A pointer of this should always be
+* either null or pointing to a C++ ProxyResolverV8 object.
+*/
+typedef void* ProxyResolverV8Handle;
+
+/**
+ * Create a ProxyResolverV8Handle. The caller must call ProxyResolverV8Handle_delete to release
+ * the memory.
+ */
+ProxyResolverV8Handle* ProxyResolverV8Handle_new();
+
+/**
+ * @return the result in char16_t array if the run is successful. The result contains a list of
+ * proxies according to the PAC specification. Otherwise, return NULL if the run fails.
+ * The memory is allocated with malloc() and the caller should use free() to release it
+ * after use.
+ */
+char16_t* ProxyResolverV8Handle_GetProxyForURL(ProxyResolverV8Handle* handle,
+ const char16_t* spec, const char16_t* host);
+/**
+ * @return OK if setting the pac script successfully.
+ */
+int ProxyResolverV8Handle_SetPacScript(ProxyResolverV8Handle* handle,
+ const char16_t* script_data);
+
+void ProxyResolverV8Handle_delete(ProxyResolverV8Handle* handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NET_PROXY_PROXY_RESOLVER_V8_WRAPPER_H_
\ No newline at end of file
diff --git a/libpac.map.txt b/libpac.map.txt
new file mode 100644
index 0000000..1936fa9
--- /dev/null
+++ b/libpac.map.txt
@@ -0,0 +1,23 @@
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LIBPAC_EXTERNAL_1 {
+ global:
+ ProxyResolverV8Handle_new;
+ ProxyResolverV8Handle_GetProxyForURL;
+ ProxyResolverV8Handle_SetPacScript;
+ ProxyResolverV8Handle_delete;
+ local:
+ *;
+};
\ No newline at end of file
diff --git a/src/proxy_resolver_js_bindings.h b/src/proxy_resolver_js_bindings.h
index 9559492..ebdacfe 100644
--- a/src/proxy_resolver_js_bindings.h
+++ b/src/proxy_resolver_js_bindings.h
@@ -6,13 +6,10 @@
#define NET_PROXY_PROXY_RESOLVER_JS_BINDINGS_H_
#pragma once
-#include <utils/String16.h>
#include <string>
namespace net {
-class ProxyErrorListener;
-
// Interface for the javascript bindings.
class ProxyResolverJSBindings {
public:
diff --git a/src/proxy_resolver_v8.cc b/src/proxy_resolver_v8.cc
index 28cf1a7..71226ac 100644
--- a/src/proxy_resolver_v8.cc
+++ b/src/proxy_resolver_v8.cc
@@ -2,13 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#ifdef ANDROID
+#define LOG_TAG "libpac"
+#include <utils/Log.h>
+#endif
+
#include "proxy_resolver_v8.h"
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <string>
-#include <utils/String8.h>
#include <v8.h>
#include <libplatform/libplatform.h>
#include <vector>
@@ -65,50 +69,49 @@
// isInNetEx() | N/A | IPv4/IPv6 | IPv4/IPv6
// -----------------+-------------+-------------------+--------------
-static bool DoIsStringASCII(const android::String16& str) {
- for (size_t i = 0; i < str.size(); i++) {
- unsigned short c = str.string()[i];
+static bool DoIsStringASCII(const std::u16string& str) {
+ for (size_t i = 0; i < str.length(); i++) {
+ unsigned short c = str.data()[i];
if (c > 0x7F)
return false;
}
return true;
}
-bool IsStringASCII(const android::String16& str) {
+bool IsStringASCII(const std::u16string& str) {
return DoIsStringASCII(str);
}
+#ifdef ANDROID
+#define LOG_ALERT(...) ALOGD(__VA_ARGS__)
+#define LOG_ERROR(...) ALOGE(__VA_ARGS__)
+#else
+#define LOG_ALERT(...) vprintf(__VA_ARGS__)
+#define LOG_ERROR(...) vfprintf(stderr, __VA_ARGS__)
+#endif
+
namespace net {
namespace {
+class DefaultProxyErrorListener : public ProxyErrorListener {
+public:
+ ~DefaultProxyErrorListener() {}
+ void AlertMessage(const std::string& message) {
+ LOG_ALERT("Alert: %s", message.data());
+ }
+ void ErrorMessage(const std::string& message) {
+ LOG_ERROR("Error: %s", message.data());
+ }
+};
+
+ProxyErrorListener* const defaultProxyErrorListener = new DefaultProxyErrorListener();
+
// 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
-// ProxyResolverScriptData.
-class V8ExternalStringFromScriptData
- : public v8::String::ExternalStringResource {
- public:
- explicit V8ExternalStringFromScriptData(
- const android::String16& script_data)
- : script_data_(script_data) {}
-
- virtual const uint16_t* data() const {
- return reinterpret_cast<const uint16_t*>(script_data_.string());
- }
-
- virtual size_t length() const {
- return script_data_.size();
- }
-
- private:
- const android::String16& script_data_;
-// DISALLOW_COPY_AND_ASSIGN(V8ExternalStringFromScriptData);
-};
-
// External string wrapper so V8 can access a string literal.
class V8ExternalASCIILiteral
: public v8::String::ExternalOneByteStringResource {
@@ -157,28 +160,23 @@
}
// Converts a V8 String to a UTF16 string.
-android::String16 V8StringToUTF16(v8::Isolate* isolate, v8::Handle<v8::String> s) {
+std::u16string V8StringToUTF16(v8::Isolate* isolate, v8::Handle<v8::String> s) {
int len = s->Length();
char16_t* buf = new char16_t[len + 1];
s->Write(isolate, reinterpret_cast<uint16_t*>(buf), 0, len);
- android::String16 ret(buf, len);
+ std::u16string ret(buf, len);
delete[] buf;
return ret;
}
-std::string UTF16ToASCII(const android::String16& str) {
- android::String8 rstr(str);
- return std::string(rstr.string());
-}
-
// 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::NewStringType::kNormal, s.size()).ToLocalChecked();
}
-v8::Local<v8::String> UTF16StringToV8String(v8::Isolate* isolate, const android::String16& s) {
+v8::Local<v8::String> UTF16StringToV8String(v8::Isolate* isolate, const std::u16string& s) {
return v8::String::NewFromTwoByte(
- isolate, reinterpret_cast<const uint16_t*>(s.string()),
+ isolate, reinterpret_cast<const uint16_t*>(s.data()),
v8::NewStringType::kNormal, s.size()).ToLocalChecked();
}
@@ -193,8 +191,8 @@
// 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::Handle<v8::Value> object,
- android::String16* utf16_result,
+bool V8ObjectToUTF8String(v8::Handle<v8::Value> object,
+ std::string* utf8_result,
v8::Isolate* isolate) {
if (object.IsEmpty())
return false;
@@ -204,7 +202,7 @@
if (!object->ToString(isolate->GetCurrentContext()).ToLocal(&str_object))
return false;
- *utf16_result = V8StringToUTF16(isolate, str_object);
+ *utf8_result = V8StringToUTF8(isolate, str_object);
return true;
}
@@ -215,11 +213,11 @@
if (args.Length() == 0 || args[0].IsEmpty() || !args[0]->IsString())
return false;
- const android::String16 hostname_utf16 = V8StringToUTF16(args.GetIsolate(), v8::Local<v8::String>::Cast(args[0]));
+ const std::u16string 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)) {
- *hostname = UTF16ToASCII(hostname_utf16);
+ *hostname = V8StringToUTF8(args.GetIsolate(), v8::Local<v8::String>::Cast(args[0]));
return true;
}
return false;
@@ -374,8 +372,8 @@
v8_context_.Reset();
}
- int ResolveProxy(const android::String16 url, const android::String16 host,
- android::String16* results) {
+ int ResolveProxy(const std::u16string url, const std::u16string host,
+ std::u16string* results) {
v8::Locker locked(isolate_);
v8::Isolate::Scope isolate_scope(isolate_);
v8::HandleScope scope(isolate_);
@@ -386,8 +384,7 @@
v8::Local<v8::Value> function;
if (!GetFindProxyForURL(&function)) {
- error_listener_->ErrorMessage(
- android::String16("FindProxyForURL() is undefined"));
+ error_listener_->ErrorMessage("FindProxyForURL() is undefined");
return ERR_PAC_SCRIPT_FAILED;
}
@@ -399,13 +396,12 @@
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()));
+ error_listener_->ErrorMessage(V8StringToUTF8(isolate_, try_catch.Message()->Get()));
return ERR_PAC_SCRIPT_FAILED;
}
if (!ret->IsString()) {
- error_listener_->ErrorMessage(
- android::String16("FindProxyForURL() did not return a string."));
+ error_listener_->ErrorMessage("FindProxyForURL() did not return a string.");
return ERR_PAC_SCRIPT_FAILED;
}
@@ -416,15 +412,14 @@
// could extend the parsing to handle IDNA hostnames by
// converting them to ASCII punycode.
// crbug.com/47234
- error_listener_->ErrorMessage(
- android::String16("FindProxyForURL() returned a non-ASCII string"));
+ error_listener_->ErrorMessage("FindProxyForURL() returned a non-ASCII string");
return ERR_PAC_SCRIPT_FAILED;
}
return OK;
}
- int InitV8(const android::String16& pac_script) {
+ int InitV8(const std::u16string& pac_script) {
v8::Locker locked(isolate_);
v8::Isolate::Scope isolate_scope(isolate_);
v8::HandleScope scope(isolate_);
@@ -526,14 +521,14 @@
}
if (function->IsEmpty() || try_catch.HasCaught()) {
- error_listener_->ErrorMessage(android::String16(
- "Accessing FindProxyForURL threw an exception."));
+ error_listener_->ErrorMessage(
+ "Accessing FindProxyForURL threw an exception.");
return false;
}
if (!(*function)->IsFunction()) {
- error_listener_->ErrorMessage(android::String16(
- "FindProxyForURL is undefined or not a function."));
+ error_listener_->ErrorMessage(
+ "FindProxyForURL is undefined or not a function.");
return false;
}
@@ -544,7 +539,7 @@
void HandleError(v8::Handle<v8::Message> message) {
if (message.IsEmpty())
return;
- error_listener_->ErrorMessage(V8StringToUTF16(isolate_, message->Get()));
+ error_listener_->ErrorMessage(V8StringToUTF8(isolate_, message->Get()));
}
// Compiles and runs |script| in the current V8 context.
@@ -584,14 +579,11 @@
// Like firefox we assume "undefined" if no argument was specified, and
// disregard any arguments beyond the first.
- android::String16 message;
+ std::string message;
if (args.Length() == 0) {
- std::string undef = "undefined";
- android::String8 undef8(undef.c_str());
- android::String16 wundef(undef8);
- message = wundef;
+ message = "undefined";
} else {
- if (!V8ObjectToUTF16String(args[0], &message, args.GetIsolate()))
+ if (!V8ObjectToUTF8String(args[0], &message, args.GetIsolate()))
return; // toString() threw an exception.
}
@@ -742,6 +734,10 @@
bool ProxyResolverV8::initialized_for_this_process_ = false;
+ProxyResolverV8::ProxyResolverV8(ProxyResolverJSBindings* custom_js_bindings)
+ : ProxyResolverV8(custom_js_bindings, defaultProxyErrorListener) {
+}
+
ProxyResolverV8::ProxyResolverV8(
ProxyResolverJSBindings* custom_js_bindings,
ProxyErrorListener* error_listener)
@@ -765,13 +761,14 @@
}
}
-int ProxyResolverV8::GetProxyForURL(const android::String16 spec, const android::String16 host,
- android::String16* results) {
+int ProxyResolverV8::GetProxyForURL(const std::u16string& spec, const std::u16string& host,
+ std::u16string* results) {
// If the V8 instance has not been initialized (either because
// SetPacScript() wasn't called yet, or because it failed.
- if (context_ == NULL)
+ if (context_ == NULL) {
+ error_listener_->ErrorMessage(std::string("Context is null."));
return ERR_FAILED;
-
+ }
// Otherwise call into V8.
int rv = context_->ResolveProxy(spec, host, results);
@@ -782,14 +779,16 @@
context_->PurgeMemory();
}
-int ProxyResolverV8::SetPacScript(const android::String16& script_data) {
+int ProxyResolverV8::SetPacScript(const std::u16string& script_data) {
if (context_ != NULL) {
delete context_;
context_ = NULL;
}
- if (script_data.size() == 0)
+ if (script_data.length() == 0)
return ERR_PAC_SCRIPT_FAILED;
+ // To help debugging v8 initialization issues, add "--log_all --print_all_exceptions"
+ // to the options
// Disable JIT
static const char kNoOpt[] = "--no-opt";
v8::V8::SetFlagsFromString(kNoOpt, strlen(kNoOpt));
diff --git a/src/proxy_resolver_v8.h b/src/proxy_resolver_v8.h
index 9b74e29..36a3214 100644
--- a/src/proxy_resolver_v8.h
+++ b/src/proxy_resolver_v8.h
@@ -6,25 +6,19 @@
#define NET_PROXY_PROXY_RESOLVER_V8_H_
#pragma once
-#include <utils/String16.h>
+#include <string>
#include "proxy_resolver_js_bindings.h"
+#include "proxy_resolver_v8_wrapper.h"
namespace net {
-typedef void* RequestHandle;
-typedef void* CompletionCallback;
-
-#define OK 0
-#define ERR_PAC_SCRIPT_FAILED -1
-#define ERR_FAILED -2
-
class ProxyErrorListener {
protected:
virtual ~ProxyErrorListener() {}
public:
- virtual void AlertMessage(android::String16 message) = 0;
- virtual void ErrorMessage(android::String16 error) = 0;
+ virtual void AlertMessage(const std::string& message) = 0;
+ virtual void ErrorMessage(const std::string& error) = 0;
};
// Implementation of ProxyResolver that uses V8 to evaluate PAC scripts.
@@ -50,6 +44,8 @@
// Constructs a ProxyResolverV8 with custom bindings. ProxyResolverV8 takes
// ownership of |custom_js_bindings| and deletes it when ProxyResolverV8
// is destroyed.
+ explicit ProxyResolverV8(ProxyResolverJSBindings* custom_js_bindings);
+ // This constructor should only be used for test.
explicit ProxyResolverV8(ProxyResolverJSBindings* custom_js_bindings,
ProxyErrorListener* error_listener);
@@ -57,10 +53,10 @@
ProxyResolverJSBindings* js_bindings() { return js_bindings_; }
- virtual int GetProxyForURL(const android::String16 spec, const android::String16 host,
- android::String16* results);
+ virtual int GetProxyForURL(const std::u16string& spec, const std::u16string& host,
+ std::u16string* results);
virtual void PurgeMemory();
- virtual int SetPacScript(const android::String16& script_data);
+ virtual int SetPacScript(const std::u16string& script_data);
private:
// Context holds the Javascript state for the most recently loaded PAC
diff --git a/src/proxy_resolver_v8_wrapper.cc b/src/proxy_resolver_v8_wrapper.cc
new file mode 100644
index 0000000..ae56d9a
--- /dev/null
+++ b/src/proxy_resolver_v8_wrapper.cc
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "proxy_resolver_v8_wrapper.h"
+#include "proxy_resolver_v8.h"
+
+using namespace net;
+
+// Implement C interface of ProxyResolverV8
+extern "C" {
+
+ProxyResolverV8Handle* ProxyResolverV8Handle_new() {
+ ProxyResolverV8* proxyResolver = new ProxyResolverV8(ProxyResolverJSBindings::CreateDefault());
+ return reinterpret_cast<ProxyResolverV8Handle*>(proxyResolver);
+}
+
+char16_t* ProxyResolverV8Handle_GetProxyForURL(ProxyResolverV8Handle* handle,
+ const char16_t* spec,
+ const char16_t* host) {
+ ProxyResolverV8* proxyResolver = reinterpret_cast<ProxyResolverV8*>(handle);
+ std::u16string specStr(spec);
+ std::u16string hostStr(host);
+ std::u16string proxies;
+ int code = proxyResolver->GetProxyForURL(specStr, hostStr, &proxies);
+ if (code != OK) {
+ return NULL;
+ }
+ auto len = proxies.length();
+ char16_t* result = (char16_t*) malloc(sizeof(char16_t) * (len + 1));
+ if (result == 0) { // Failed to allocate
+ return NULL;
+ }
+ proxies.copy(result, len);
+ result[len] = u'\0';
+ return result;
+}
+
+int ProxyResolverV8Handle_SetPacScript(ProxyResolverV8Handle* handle,
+ const char16_t* script_data) {
+ ProxyResolverV8* proxyResolver = reinterpret_cast<ProxyResolverV8*>(handle);
+ std::u16string script(script_data);
+ return proxyResolver->SetPacScript(script);
+}
+
+void ProxyResolverV8Handle_delete(ProxyResolverV8Handle* handle) {
+ ProxyResolverV8* proxyResolver = reinterpret_cast<ProxyResolverV8*>(handle);
+ delete proxyResolver;
+}
+
+} // extern "C"
\ No newline at end of file
diff --git a/test/Android.bp b/test/Android.bp
new file mode 100644
index 0000000..5910ebb
--- /dev/null
+++ b/test/Android.bp
@@ -0,0 +1,23 @@
+cc_test {
+ name: "proxy_resolver_v8_unittest",
+
+ srcs: ["proxy_resolver_v8_unittest.cc"],
+
+ include_dirs: ["external/chromium-libpac/src"],
+
+ cflags: [
+ "-Wno-endif-labels",
+ "-Wno-import",
+ "-Wno-format",
+ ],
+
+ // Use the non-APEX version for C++ API.
+ bootstrap: true,
+
+ shared_libs: [
+ "libpac",
+ "libutils",
+ "liblog",
+ "libandroid_runtime",
+ ],
+}
diff --git a/test/Android.mk b/test/Android.mk
deleted file mode 100644
index edf9107..0000000
--- a/test/Android.mk
+++ /dev/null
@@ -1,23 +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 := proxy_resolver_v8_unittest
-
-LOCAL_SRC_FILES := \
- proxy_resolver_v8_unittest.cc
-
-LOCAL_CFLAGS += \
- -Wno-endif-labels \
- -Wno-import \
- -Wno-format \
-
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/../src $(LOCAL_PATH)/ external/v8
-
-LOCAL_SHARED_LIBRARIES := libpac libutils liblog libandroid_runtime
-
-include $(BUILD_NATIVE_TEST)
diff --git a/test/js-unittest/string_functions.js b/test/js-unittest/string_functions.js
new file mode 100644
index 0000000..a7c430f
--- /dev/null
+++ b/test/js-unittest/string_functions.js
@@ -0,0 +1,3 @@
+function FindProxyForURL(url, host) {
+ return "direct".toUpperCase();
+}
diff --git a/test/jstocstring.pl b/test/jstocstring.pl
index 7b50772..eade2b8 100755
--- a/test/jstocstring.pl
+++ b/test/jstocstring.pl
@@ -15,6 +15,7 @@
if (s/\.js/_JS/) {
$upper = uc();
print FILE "#define $upper \\\n";
+ print FILE " u\"\"\\\n";
while (<FH>) {
s/\"/\\\"/g;
chomp();
diff --git a/test/proxy_resolver_v8_unittest.cc b/test/proxy_resolver_v8_unittest.cc
index e66f68b..8469cab 100644
--- a/test/proxy_resolver_v8_unittest.cc
+++ b/test/proxy_resolver_v8_unittest.cc
@@ -11,9 +11,9 @@
#include "android_runtime/AndroidRuntime.h"
#include "proxy_test_script.h"
+#include "proxy_resolver_v8_wrapper.h"
#include "proxy_resolver_v8.h"
-using namespace android;
namespace net {
namespace {
@@ -49,20 +49,14 @@
return !dns_resolve_ex_result.empty();
}
- virtual void AlertMessage(String16 message) {
- String8 m8(message);
- std::string mstd(m8.string());
-
- ALOGD("PAC-alert: %s\n", mstd.c_str()); // Helpful when debugging.
- alerts.push_back(mstd);
+ virtual void AlertMessage(const std::string& message) {
+ ALOGD("PAC-alert: %s\n", message.c_str()); // Helpful when debugging.
+ alerts.push_back(message);
}
- virtual void ErrorMessage(const String16 message) {
- String8 m8(message);
- std::string mstd(m8.string());
-
- ALOGD("PAC-error: %s\n", mstd.c_str()); // Helpful when debugging.
- errors.push_back(mstd);
+ virtual void ErrorMessage(const std::string& message) {
+ ALOGD("PAC-error: %s\n", message.c_str()); // Helpful when debugging.
+ errors.push_back(message);
}
virtual void Shutdown() {}
@@ -100,12 +94,12 @@
};
// Doesn't really matter what these values are for many of the tests.
-const String16 kQueryUrl("http://www.google.com");
-const String16 kQueryHost("www.google.com");
-String16 kResults;
+const std::u16string kQueryUrl(u"http://www.google.com");
+const std::u16string kQueryHost(u"www.google.com");
+std::u16string kResults;
-String16 currentPac;
-#define SCRIPT(x) (currentPac = String16(x))
+std::u16string currentPac;
+#define SCRIPT(x) (currentPac = std::u16string(x))
void addString(std::vector<std::string>* list, std::string str) {
if (str.compare(0, 6, "DIRECT") == 0) {
@@ -117,9 +111,21 @@
}
}
-std::vector<std::string> string16ToProxyList(String16 response) {
+std::unique_ptr<ProxyResolverV8Handle, void(*)(ProxyResolverV8Handle*)> newProxyResolverV8Handle() {
+ return std::unique_ptr<ProxyResolverV8Handle, void(*)(ProxyResolverV8Handle*)>(
+ ProxyResolverV8Handle_new(), &ProxyResolverV8Handle_delete);
+}
+
+std::unique_ptr<char16_t, decltype(&free)> getProxyForURL(ProxyResolverV8Handle* handle,
+ const char16_t* spec,
+ const char16_t* host) {
+ return std::unique_ptr<char16_t, decltype(&free)>(
+ ProxyResolverV8Handle_GetProxyForURL(handle, spec, host), &free);
+}
+
+std::vector<std::string> string16ToProxyList(const std::u16string& response) {
std::vector<std::string> ret;
- String8 response8(response);
+ android::String8 response8(response.data());
std::string rstr(response8.string());
if (rstr.find(';') == std::string::npos) {
addString(&ret, rstr);
@@ -163,6 +169,21 @@
EXPECT_EQ(0U, resolver.mock_js_bindings()->errors.size());
}
+TEST(ProxyResolverV8Test, Direct_C_API) {
+ auto handle = newProxyResolverV8Handle();
+ int result = ProxyResolverV8Handle_SetPacScript(handle.get(), DIRECT_JS);
+ EXPECT_EQ(OK, result);
+
+ std::unique_ptr<char16_t, decltype(&free)> result_list = getProxyForURL(
+ handle.get(), kQueryUrl.data(), kQueryHost.data());
+
+ ASSERT_NE(nullptr, result_list.get());
+ kResults = result_list.get();
+ std::vector<std::string> proxies = string16ToProxyList(kResults);
+ EXPECT_EQ(proxies.size(), 1U);
+ EXPECT_EQ("DIRECT",proxies[0]);
+}
+
TEST(ProxyResolverV8Test, ReturnEmptyString) {
ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
int result = resolver.SetPacScript(SCRIPT(RETURN_EMPTY_STRING_JS));
@@ -187,8 +208,8 @@
// arguments into a pseudo-host. The purpose of this test is to verify that
// the correct arguments are being passed to FindProxyForURL().
{
- String16 queryUrl("http://query.com/path");
- String16 queryHost("query.com");
+ std::u16string queryUrl(u"http://query.com/path");
+ std::u16string queryHost(u"query.com");
result = resolver.GetProxyForURL(queryUrl, queryHost, &kResults);
EXPECT_EQ(OK, result);
std::vector<std::string> proxies = string16ToProxyList(kResults);
@@ -196,8 +217,8 @@
EXPECT_EQ("http.query.com.path.query.com", proxies[0]);
}
{
- String16 queryUrl("ftp://query.com:90/path");
- String16 queryHost("query.com");
+ std::u16string queryUrl(u"ftp://query.com:90/path");
+ std::u16string queryHost(u"query.com");
int result = resolver.GetProxyForURL(queryUrl, queryHost, &kResults);
EXPECT_EQ(OK, result);
@@ -219,16 +240,33 @@
resolver.PurgeMemory();
}
+TEST(ProxyResolverV8Test, Basic_C_API) {
+ auto handle = newProxyResolverV8Handle();
+ int result = ProxyResolverV8Handle_SetPacScript(handle.get(), PASSTHROUGH_JS);
+ EXPECT_EQ(OK, result);
+
+ // The "FindProxyForURL" of this PAC script simply concatenates all of the
+ // arguments into a pseudo-host. The purpose of this test is to verify that
+ // the correct arguments are being passed to FindProxyForURL().
+ std::unique_ptr<char16_t, decltype(&free)> result_list = getProxyForURL(
+ handle.get(), u"http://query.com/path", u"query.com");
+ ASSERT_NE(nullptr, result_list.get());
+ kResults = result_list.get();
+ std::vector<std::string> proxies = string16ToProxyList(kResults);
+ EXPECT_EQ(1U, proxies.size());
+ EXPECT_EQ("http.query.com.path.query.com", proxies[0]);
+}
+
TEST(ProxyResolverV8Test, BadReturnType) {
// These are the files of PAC scripts which each return a non-string
// types for FindProxyForURL(). They should all fail with
// ERR_PAC_SCRIPT_FAILED.
- static const String16 files[] = {
- String16(RETURN_UNDEFINED_JS),
- String16(RETURN_INTEGER_JS),
- String16(RETURN_FUNCTION_JS),
- String16(RETURN_OBJECT_JS),
- String16(RETURN_NULL_JS)
+ static const std::u16string files[] = {
+ std::u16string(RETURN_UNDEFINED_JS),
+ std::u16string(RETURN_INTEGER_JS),
+ std::u16string(RETURN_FUNCTION_JS),
+ std::u16string(RETURN_OBJECT_JS),
+ std::u16string(RETURN_NULL_JS)
};
for (size_t i = 0; i < 5; ++i) {
@@ -273,10 +311,20 @@
EXPECT_EQ(0U, bindings->alerts.size());
// We get one error during compilation.
- ASSERT_EQ(1U, bindings->errors.size());
+ ASSERT_EQ(2U, bindings->errors.size());
EXPECT_EQ("Uncaught SyntaxError: Unexpected end of input",
bindings->errors[0]);
+ EXPECT_EQ("Context is null.", bindings->errors[1]);
+}
+
+TEST(ProxyResolverV8Test, ParseError_C_API) {
+ auto handle = newProxyResolverV8Handle();
+ int result = ProxyResolverV8Handle_SetPacScript(handle.get(), MISSING_CLOSE_BRACE_JS);
+ EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, result);
+ std::unique_ptr<char16_t, decltype(&free)> result_list = getProxyForURL(
+ handle.get(), u"http://query.com/path", u"query.com");
+ EXPECT_EQ(nullptr, result_list.get());
}
// Run a PAC script several times, which has side-effects.
@@ -366,6 +414,9 @@
// Resolve should fail, as we are not yet initialized with a script.
int result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);
EXPECT_EQ(ERR_FAILED, result);
+ EXPECT_EQ(0U, resolver.mock_js_bindings()->alerts.size());
+ EXPECT_EQ(1U, resolver.mock_js_bindings()->errors.size());
+ EXPECT_EQ("Context is null.", resolver.mock_js_bindings()->errors[0]);
// Initialize it.
result = resolver.SetPacScript(SCRIPT(DIRECT_JS));
@@ -382,6 +433,10 @@
result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);
EXPECT_EQ(ERR_FAILED, result);
+ EXPECT_EQ(0U, resolver.mock_js_bindings()->alerts.size());
+ EXPECT_EQ(2U, resolver.mock_js_bindings()->errors.size());
+ EXPECT_EQ("Context is null.", resolver.mock_js_bindings()->errors[1]);
+
// Load a good script once more.
result = resolver.SetPacScript(SCRIPT(DIRECT_JS));
EXPECT_EQ(OK, result);
@@ -389,7 +444,7 @@
EXPECT_EQ(OK, result);
EXPECT_EQ(0U, resolver.mock_js_bindings()->alerts.size());
- EXPECT_EQ(0U, resolver.mock_js_bindings()->errors.size());
+ EXPECT_EQ(2U, resolver.mock_js_bindings()->errors.size());
}
// Test marshalling/un-marshalling of values between C++/V8.
@@ -522,7 +577,7 @@
TEST(ProxyResolverV8Test, DNSResolutionOfInternationDomainName) {
return;
ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
- int result = resolver.SetPacScript(String16(INTERNATIONAL_DOMAIN_NAMES_JS));
+ int result = resolver.SetPacScript(SCRIPT(INTERNATIONAL_DOMAIN_NAMES_JS));
EXPECT_EQ(OK, result);
// Execute FindProxyForURL().
@@ -544,9 +599,25 @@
EXPECT_EQ("xn--bcher-kva.ch", bindings->dns_resolves_ex[0]);
}
+TEST(ProxyResolverV8Test, StringPrototype) {
+ ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
+ int result = resolver.SetPacScript(SCRIPT(STRING_FUNCTIONS_JS));
+ EXPECT_EQ(OK, result);
+
+ result = resolver.GetProxyForURL(kQueryUrl, kQueryHost, &kResults);
+
+ EXPECT_EQ(OK, result);
+ std::vector<std::string> proxies = string16ToProxyList(kResults);
+ EXPECT_EQ(proxies.size(), 1U);
+ EXPECT_EQ("DIRECT",proxies[0]);
+
+ EXPECT_EQ(0U, resolver.mock_js_bindings()->alerts.size());
+ EXPECT_EQ(0U, resolver.mock_js_bindings()->errors.size());
+}
+
TEST(ProxyResolverV8Test, GetterChangesElementKind) {
ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
- int result = resolver.SetPacScript(String16(CHANGE_ELEMENT_KIND_JS));
+ int result = resolver.SetPacScript(SCRIPT(CHANGE_ELEMENT_KIND_JS));
EXPECT_EQ(OK, result);
// Execute FindProxyForURL().
@@ -560,7 +631,7 @@
TEST(ProxyResolverV8Test, B_132073833) {
ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
- int result = resolver.SetPacScript(String16(B_132073833_JS));
+ int result = resolver.SetPacScript(SCRIPT(B_132073833_JS));
EXPECT_EQ(OK, result);
// Execute FindProxyForURL().
@@ -574,7 +645,7 @@
TEST(ProxyResolverV8Test, B_139806216) {
ProxyResolverV8WithMockBindings resolver(new MockJSBindings());
- int result = resolver.SetPacScript(String16(B_139806216_JS));
+ int result = resolver.SetPacScript(SCRIPT(B_139806216_JS));
EXPECT_EQ(OK, result);
// Execute FindProxyForURL().
diff --git a/test/proxy_test_script.h b/test/proxy_test_script.h
index 0deb19f..2a86491 100644
--- a/test/proxy_test_script.h
+++ b/test/proxy_test_script.h
@@ -5,6 +5,7 @@
#define PROXY_TEST_SCRIPT_H_
#define B_132073833_JS \
+ u""\
"function FindProxyForURL(url, host){\n" \
" function opt() {\n" \
" opt['x'] = 1.1;\n" \
@@ -28,6 +29,7 @@
"var object;\n" \
#define B_139806216_JS \
+ u""\
"function FindProxyForURL(url, host){\n" \
" var x = new ArrayBuffer(1);\n" \
" return \"DIRECT\";\n" \
@@ -58,6 +60,7 @@
"}\n" \
#define BINDING_FROM_GLOBAL_JS \
+ u""\
"// Calls a bindings outside of FindProxyForURL(). This causes the code to\n" \
"// get exercised during initialization.\n" \
"\n" \
@@ -68,6 +71,7 @@
"}\n" \
#define BINDINGS_JS \
+ u""\
"// Try calling the browser-side bound functions with varying (invalid)\n" \
"// inputs. There is no notion of \"success\" for this test, other than\n" \
"// verifying the correct C++ bindings were reached with expected values.\n" \
@@ -132,6 +136,7 @@
"\n" \
#define CHANGE_ELEMENT_KIND_JS \
+ u""\
"// PAC script with getter that changes element kind.\n" \
"\n" \
"function FindProxyForURL(url, host) {\n" \
@@ -149,12 +154,14 @@
"}\n" \
#define DIRECT_JS \
+ u""\
"function FindProxyForURL(url, host) {\n" \
" return \"DIRECT\";\n" \
"}\n" \
"\n" \
#define DNS_FAIL_JS \
+ u""\
"// This script should be run in an environment where all DNS resolution are\n" \
"// failing. It tests that functions return the expected values.\n" \
"//\n" \
@@ -184,6 +191,7 @@
"\n" \
#define ENDS_WITH_COMMENT_JS \
+ u""\
"function FindProxyForURL(url, host) {\n" \
" return \"PROXY success:80\";\n" \
"}\n" \
@@ -194,11 +202,13 @@
"// those extra functions was being considered part of the comment.\n" \
#define ENDS_WITH_STATEMENT_NO_SEMICOLON_JS \
+ u""\
"// Ends with a statement, and no terminal newline.\n" \
"function FindProxyForURL(url, host) { return \"PROXY success:\" + x; }\n" \
"x = 3\n" \
#define INTERNATIONAL_DOMAIN_NAMES_JS \
+ u""\
"// Try resolving hostnames containing non-ASCII characters.\n" \
"\n" \
"function FindProxyForURL(url, host) {\n" \
@@ -217,6 +227,7 @@
"\n" \
#define MISSING_CLOSE_BRACE_JS \
+ u""\
"// This PAC script is invalid, because there is a missing close brace\n" \
"// on the function FindProxyForURL().\n" \
"\n" \
@@ -225,10 +236,12 @@
"\n" \
#define NO_ENTRYPOINT_JS \
+ u""\
"var x = \"This is an invalid PAC script because it lacks a \" +\n" \
" \"FindProxyForURL() function\";\n" \
#define PAC_LIBRARY_UNITTEST_JS \
+ u""\
"// This should output \"PROXY success:80\" if all the tests pass.\n" \
"// Otherwise it will output \"PROXY failure:<num-failures>\".\n" \
"//\n" \
@@ -597,6 +610,7 @@
"\n" \
#define PASSTHROUGH_JS \
+ u""\
"// Return a single-proxy result, which encodes ALL the arguments that were\n" \
"// passed to FindProxyForURL().\n" \
"\n" \
@@ -644,48 +658,56 @@
"}\n" \
#define RETURN_EMPTY_STRING_JS \
+ u""\
"function FindProxyForURL(url, host) {\n" \
" return \"\";\n" \
"}\n" \
"\n" \
#define RETURN_FUNCTION_JS \
+ u""\
"function FindProxyForURL(url, host) {\n" \
" return FindProxyForURL;\n" \
"}\n" \
"\n" \
#define RETURN_INTEGER_JS \
+ u""\
"function FindProxyForURL(url, host) {\n" \
" return 0;\n" \
"}\n" \
"\n" \
#define RETURN_NULL_JS \
+ u""\
"function FindProxyForURL(url, host) {\n" \
" return null;\n" \
"}\n" \
"\n" \
#define RETURN_OBJECT_JS \
+ u""\
"function FindProxyForURL(url, host) {\n" \
" return {result: \"PROXY foo\"};\n" \
"}\n" \
"\n" \
#define RETURN_UNDEFINED_JS \
+ u""\
"function FindProxyForURL(url, host) {\n" \
" return undefined;\n" \
"}\n" \
"\n" \
#define RETURN_UNICODE_JS \
+ u""\
"// U+200B is the codepoint for zero-width-space.\n" \
"function FindProxyForURL(url, host) {\n" \
" return \"PROXY foo.com\u200B\";\n" \
"}\n" \
#define SIDE_EFFECTS_JS \
+ u""\
"if (!gCounter) {\n" \
" // We write it this way so if the script gets loaded twice,\n" \
" // gCounter remains dirty.\n" \
@@ -698,6 +720,7 @@
"\n" \
#define SIMPLE_JS \
+ u""\
"// PAC script which uses isInNet on both IP addresses and hosts, and calls\n" \
"// isResolvable().\n" \
"\n" \
@@ -720,7 +743,14 @@
" return \"DIRECT\";\n" \
"}\n" \
+#define STRING_FUNCTIONS_JS \
+ u""\
+ "function FindProxyForURL(url, host) {\n" \
+ " return \"direct\".toUpperCase();\n" \
+ "}\n" \
+
#define UNHANDLED_EXCEPTION_JS \
+ u""\
"function FindProxyForURL(url, host) {\n" \
" // This will throw a runtime exception.\n" \
" return \"PROXY x\" + undefined_variable;\n" \