diff options
Diffstat (limited to 'extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp')
-rw-r--r-- | extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp b/extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp new file mode 100644 index 000000000..87f2bef20 --- /dev/null +++ b/extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp @@ -0,0 +1,138 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "jsapi.h" +#include "nsIXPConnect.h" +#include "nsCOMPtr.h" +#include "nsIServiceManager.h" +#include "nsIComponentManager.h" +#include "nsString.h" +#include "nsIPrefService.h" +#include "nspr.h" +#include "mozilla/Attributes.h" +#include "mozilla/Maybe.h" +#include "nsContentUtils.h" +#include "nsIScriptSecurityManager.h" +#include "nsJSPrincipals.h" +#include "nsIScriptError.h" +#include "jswrapper.h" + +extern mozilla::LazyLogModule MCD; +using mozilla::AutoSafeJSContext; +using mozilla::dom::AutoJSAPI; + +//***************************************************************************** + +static JS::PersistentRooted<JSObject *> autoconfigSb; + +nsresult CentralizedAdminPrefManagerInit() +{ + nsresult rv; + + // If the sandbox is already created, no need to create it again. + if (autoconfigSb.initialized()) + return NS_OK; + + // Grab XPConnect. + nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID(), &rv); + if (NS_FAILED(rv)) { + return rv; + } + + // Grab the system principal. + nsCOMPtr<nsIPrincipal> principal; + nsContentUtils::GetSecurityManager()->GetSystemPrincipal(getter_AddRefs(principal)); + + + // Create a sandbox. + AutoSafeJSContext cx; + JS::Rooted<JSObject*> sandbox(cx); + rv = xpc->CreateSandbox(cx, principal, sandbox.address()); + NS_ENSURE_SUCCESS(rv, rv); + + // Unwrap, store and root the sandbox. + NS_ENSURE_STATE(sandbox); + autoconfigSb.init(cx, js::UncheckedUnwrap(sandbox)); + + return NS_OK; +} + +nsresult CentralizedAdminPrefManagerFinish() +{ + if (autoconfigSb.initialized()) { + AutoSafeJSContext cx; + autoconfigSb.reset(); + JS_MaybeGC(cx); + } + return NS_OK; +} + +nsresult EvaluateAdminConfigScript(const char *js_buffer, size_t length, + const char *filename, bool bGlobalContext, + bool bCallbacks, bool skipFirstLine) +{ + nsresult rv = NS_OK; + + if (skipFirstLine) { + /* In order to protect the privacy of the JavaScript preferences file + * from loading by the browser, we make the first line unparseable + * by JavaScript. We must skip that line here before executing + * the JavaScript code. + */ + unsigned int i = 0; + while (i < length) { + char c = js_buffer[i++]; + if (c == '\r') { + if (js_buffer[i] == '\n') + i++; + break; + } + if (c == '\n') + break; + } + + length -= i; + js_buffer += i; + } + + // Grab XPConnect. + nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID(), &rv); + if (NS_FAILED(rv)) { + return rv; + } + + AutoJSAPI jsapi; + if (!jsapi.Init(autoconfigSb)) { + return NS_ERROR_UNEXPECTED; + } + JSContext* cx = jsapi.cx(); + + nsAutoCString script(js_buffer, length); + JS::RootedValue v(cx); + + nsString convertedScript; + bool isUTF8 = IsUTF8(script); + if (isUTF8) { + convertedScript = NS_ConvertUTF8toUTF16(script); + } else { + nsContentUtils::ReportToConsoleNonLocalized( + NS_LITERAL_STRING("Your AutoConfig file is ASCII. Please convert it to UTF-8."), + nsIScriptError::warningFlag, + NS_LITERAL_CSTRING("autoconfig"), + nullptr); + /* If the length is 0, the conversion failed. Fallback to ASCII */ + convertedScript = NS_ConvertASCIItoUTF16(script); + } + JS::Rooted<JS::Value> value(cx, JS::BooleanValue(isUTF8)); + if (!JS_DefineProperty(cx, autoconfigSb, "gIsUTF8", value, JSPROP_ENUMERATE)) { + return NS_ERROR_UNEXPECTED; + } + rv = xpc->EvalInSandboxObject(convertedScript, filename, cx, + autoconfigSb, JSVERSION_LATEST, &v); + NS_ENSURE_SUCCESS(rv, rv); + + return NS_OK; +} + |