From e27ef6c21a149b94c709e5fcd89cdd543b84e70a Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Wed, 28 Dec 2011 09:13:38 +0100 Subject: [PATCH] Bug 713550 - Move Base64 code on nsXPConnect to XPCOM / xpcpublic.h; r=bholley+khuey --- content/base/src/nsContentUtils.cpp | 7 +- dom/base/nsStructuredCloneContainer.cpp | 9 +- dom/workers/FileReaderSync.cpp | 1 - dom/workers/Makefile.in | 1 - dom/workers/WorkerScope.cpp | 7 +- js/xpconnect/loader/mozJSComponentLoader.cpp | 5 +- js/xpconnect/src/nsXPConnect.cpp | 130 +++---------------- js/xpconnect/src/xpcprivate.h | 18 --- js/xpconnect/src/xpcpublic.h | 4 + xpcom/io/Base64.cpp | 101 +++++++++++++- xpcom/io/Base64.h | 10 ++ 11 files changed, 151 insertions(+), 142 deletions(-) diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp index 1cfb1d57a38e..b18ba6f2fdbb 100644 --- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -193,7 +193,7 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID); #include "mozAutoDocUpdate.h" #include "imgICache.h" -#include "xpcprivate.h" +#include "xpcprivate.h" // nsXPConnect #include "nsScriptSecurityManager.h" #include "nsIChannelPolicy.h" #include "nsChannelPolicy.h" @@ -207,6 +207,7 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID); #include "nsIContentViewer.h" #include "nsIObjectLoadingContent.h" +#include "mozilla/Base64.h" #include "mozilla/Preferences.h" #include "nsWrapperCacheInlines.h" @@ -633,7 +634,7 @@ nsContentUtils::Btoa(const nsAString& aBinaryData, return NS_ERROR_DOM_INVALID_CHARACTER_ERR; } - return nsXPConnect::Base64Encode(aBinaryData, aAsciiBase64String); + return Base64Encode(aBinaryData, aAsciiBase64String); } nsresult @@ -645,7 +646,7 @@ nsContentUtils::Atob(const nsAString& aAsciiBase64String, return NS_ERROR_DOM_INVALID_CHARACTER_ERR; } - nsresult rv = nsXPConnect::Base64Decode(aAsciiBase64String, aBinaryData); + nsresult rv = Base64Decode(aAsciiBase64String, aBinaryData); if (NS_FAILED(rv) && rv == NS_ERROR_INVALID_ARG) { return NS_ERROR_DOM_INVALID_CHARACTER_ERR; } diff --git a/dom/base/nsStructuredCloneContainer.cpp b/dom/base/nsStructuredCloneContainer.cpp index ab09ba8fe8c1..968ca64b89e7 100644 --- a/dom/base/nsStructuredCloneContainer.cpp +++ b/dom/base/nsStructuredCloneContainer.cpp @@ -45,7 +45,10 @@ #include "nsIVariant.h" #include "nsServiceManagerUtils.h" #include "nsContentUtils.h" -#include "xpcprivate.h" + +#include "mozilla/Base64.h" + +using namespace mozilla; NS_IMPL_ADDREF(nsStructuredCloneContainer) NS_IMPL_RELEASE(nsStructuredCloneContainer) @@ -124,7 +127,7 @@ nsStructuredCloneContainer::InitFromBase64(const nsAString &aData, NS_ConvertUTF16toUTF8 data(aData); nsCAutoString binaryData; - nsresult rv = nsXPConnect::Base64Decode(data, binaryData); + nsresult rv = Base64Decode(data, binaryData); NS_ENSURE_SUCCESS(rv, rv); // Copy the string's data into our own buffer. @@ -171,7 +174,7 @@ nsStructuredCloneContainer::GetDataAsBase64(nsAString &aOut) nsCAutoString binaryData(reinterpret_cast(mData), mSize); nsCAutoString base64Data; - nsresult rv = nsXPConnect::Base64Encode(binaryData, base64Data); + nsresult rv = Base64Encode(binaryData, base64Data); NS_ENSURE_SUCCESS(rv, rv); aOut.Assign(NS_ConvertASCIItoUTF16(base64Data)); diff --git a/dom/workers/FileReaderSync.cpp b/dom/workers/FileReaderSync.cpp index 9de22d7027e4..57627f268c8b 100644 --- a/dom/workers/FileReaderSync.cpp +++ b/dom/workers/FileReaderSync.cpp @@ -46,7 +46,6 @@ #include "jscntxt.h" #include "jstypedarray.h" #include "nsJSUtils.h" -#include "xpcprivate.h" #include "Exceptions.h" #include "File.h" diff --git a/dom/workers/Makefile.in b/dom/workers/Makefile.in index 10d8f008ff70..d4d0a8be34af 100644 --- a/dom/workers/Makefile.in +++ b/dom/workers/Makefile.in @@ -77,7 +77,6 @@ LOCAL_INCLUDES = \ -I$(topsrcdir)/content/base/src \ -I$(topsrcdir)/content/events/src \ -I$(topsrcdir)/dom/base \ - -I$(topsrcdir)/js/xpconnect/src \ -I$(topsrcdir)/xpcom/build \ $(NULL) diff --git a/dom/workers/WorkerScope.cpp b/dom/workers/WorkerScope.cpp index 5be1fdf1e84b..fec437504a0a 100644 --- a/dom/workers/WorkerScope.cpp +++ b/dom/workers/WorkerScope.cpp @@ -42,10 +42,11 @@ #include "WorkerScope.h" #include "jsapi.h" +#include "jsdbgapi.h" #include "jscntxt.h" #include "nsTraceRefcnt.h" -#include "xpcprivate.h" +#include "xpcpublic.h" #include "ChromeWorkerScope.h" #include "Events.h" @@ -548,7 +549,7 @@ private: } jsval result; - if (!nsXPConnect::Base64Decode(aCx, string, &result)) { + if (!xpc::Base64Decode(aCx, string, &result)) { return false; } @@ -574,7 +575,7 @@ private: } jsval result; - if (!nsXPConnect::Base64Encode(aCx, binary, &result)) { + if (!xpc::Base64Encode(aCx, binary, &result)) { return false; } diff --git a/js/xpconnect/loader/mozJSComponentLoader.cpp b/js/xpconnect/loader/mozJSComponentLoader.cpp index eb1ab67ab946..86edffa0d7a0 100644 --- a/js/xpconnect/loader/mozJSComponentLoader.cpp +++ b/js/xpconnect/loader/mozJSComponentLoader.cpp @@ -90,6 +90,7 @@ #include "nsILocalFileWin.h" #endif #include "xpcprivate.h" +#include "xpcpublic.h" #include "nsIResProtocolHandler.h" #include "mozilla/scache/StartupCache.h" @@ -235,7 +236,7 @@ Atob(JSContext *cx, uintN argc, jsval *vp) if (!argc) return true; - return nsXPConnect::Base64Decode(cx, JS_ARGV(cx, vp)[0], &JS_RVAL(cx, vp)); + return xpc::Base64Decode(cx, JS_ARGV(cx, vp)[0], &JS_RVAL(cx, vp)); } static JSBool @@ -244,7 +245,7 @@ Btoa(JSContext *cx, uintN argc, jsval *vp) if (!argc) return true; - return nsXPConnect::Base64Encode(cx, JS_ARGV(cx, vp)[0], &JS_RVAL(cx, vp)); + return xpc::Base64Encode(cx, JS_ARGV(cx, vp)[0], &JS_RVAL(cx, vp)); } static JSBool diff --git a/js/xpconnect/src/nsXPConnect.cpp b/js/xpconnect/src/nsXPConnect.cpp index 633bbbaa7939..088615f38538 100644 --- a/js/xpconnect/src/nsXPConnect.cpp +++ b/js/xpconnect/src/nsXPConnect.cpp @@ -54,7 +54,6 @@ #include "nsNullPrincipal.h" #include "nsIURI.h" #include "nsJSEnvironment.h" -#include "plbase64.h" #include "XrayWrapper.h" #include "WrapperFactory.h" @@ -64,6 +63,10 @@ #include "XPCQuickStubs.h" #include "dombindings.h" + +#include "mozilla/Assertions.h" +#include "mozilla/Base64.h" + #include "nsWrapperCacheInlines.h" NS_IMPL_THREADSAFE_ISUPPORTS7(nsXPConnect, @@ -2797,65 +2800,22 @@ nsXPConnect::GetCaller(JSContext **aJSContext, JSObject **aObj) *aObj = ccx->GetFlattenedJSObject(); } -// static -nsresult -nsXPConnect::Base64Encode(const nsACString &aBinaryData, nsACString &aString) +namespace xpc { + +bool +Base64Encode(JSContext *cx, JS::Value val, JS::Value *out) { - // Check for overflow. - if (aBinaryData.Length() > (PR_UINT32_MAX / 4) * 3) - return NS_ERROR_FAILURE; + MOZ_ASSERT(cx); + MOZ_ASSERT(out); - PRUint32 stringLen = ((aBinaryData.Length() + 2) / 3) * 4; - - char *buffer; - - // Add one byte for null termination. - if (aString.SetCapacity(stringLen + 1) && - (buffer = aString.BeginWriting()) && - PL_Base64Encode(aBinaryData.BeginReading(), aBinaryData.Length(), buffer)) { - // PL_Base64Encode doesn't null terminate the buffer for us when we pass - // the buffer in. Do that manually. - buffer[stringLen] = '\0'; - - aString.SetLength(stringLen); - return NS_OK; - } - - aString.Truncate(); - return NS_ERROR_INVALID_ARG; -} - -// static -nsresult -nsXPConnect::Base64Encode(const nsAString &aString, nsAString &aBinaryData) -{ - NS_LossyConvertUTF16toASCII string(aString); - nsCAutoString binaryData; - - nsresult rv = Base64Encode(string, binaryData); - if (NS_SUCCEEDED(rv)) - CopyASCIItoUTF16(binaryData, aBinaryData); - else - aBinaryData.Truncate(); - - return rv; -} - -// static -JSBool -nsXPConnect::Base64Encode(JSContext *cx, jsval val, jsval *out) -{ - NS_ASSERTION(cx, "Null context!"); - NS_ASSERTION(out, "Null jsval pointer!"); - - jsval root = val; + JS::Value root = val; xpc_qsACString encodedString(cx, root, &root, xpc_qsACString::eNull, xpc_qsACString::eStringify); if (!encodedString.IsValid()) return false; nsCAutoString result; - if (NS_FAILED(nsXPConnect::Base64Encode(encodedString, result))) { + if (NS_FAILED(mozilla::Base64Encode(encodedString, result))) { JS_ReportError(cx, "Failed to encode base64 data!"); return false; } @@ -2868,72 +2828,20 @@ nsXPConnect::Base64Encode(JSContext *cx, jsval val, jsval *out) return true; } -// static -nsresult -nsXPConnect::Base64Decode(const nsACString &aString, nsACString &aBinaryData) +bool +Base64Decode(JSContext *cx, JS::Value val, JS::Value *out) { - // Check for overflow. - if (aString.Length() > PR_UINT32_MAX / 3) - return NS_ERROR_FAILURE; + MOZ_ASSERT(cx); + MOZ_ASSERT(out); - PRUint32 binaryDataLen = ((aString.Length() * 3) / 4); - - char *buffer; - - // Add one byte for null termination. - if (aBinaryData.SetCapacity(binaryDataLen + 1) && - (buffer = aBinaryData.BeginWriting()) && - PL_Base64Decode(aString.BeginReading(), aString.Length(), buffer)) { - // PL_Base64Decode doesn't null terminate the buffer for us when we pass - // the buffer in. Do that manually, taking into account the number of '=' - // characters we were passed. - if (!aString.IsEmpty() && aString[aString.Length() - 1] == '=') { - if (aString.Length() > 1 && aString[aString.Length() - 2] == '=') - binaryDataLen -= 2; - else - binaryDataLen -= 1; - } - buffer[binaryDataLen] = '\0'; - - aBinaryData.SetLength(binaryDataLen); - return NS_OK; - } - - aBinaryData.Truncate(); - return NS_ERROR_INVALID_ARG; -} - -// static -nsresult -nsXPConnect::Base64Decode(const nsAString &aBinaryData, nsAString &aString) -{ - NS_LossyConvertUTF16toASCII binaryData(aBinaryData); - nsCAutoString string; - - nsresult rv = Base64Decode(binaryData, string); - if (NS_SUCCEEDED(rv)) - CopyASCIItoUTF16(string, aString); - else - aString.Truncate(); - - return rv; -} - -// static -JSBool -nsXPConnect::Base64Decode(JSContext *cx, jsval val, jsval *out) -{ - NS_ASSERTION(cx, "Null context!"); - NS_ASSERTION(out, "Null jsval pointer!"); - - jsval root = val; + JS::Value root = val; xpc_qsACString encodedString(cx, root, &root, xpc_qsACString::eNull, xpc_qsACString::eNull); if (!encodedString.IsValid()) return false; nsCAutoString result; - if (NS_FAILED(nsXPConnect::Base64Decode(encodedString, result))) { + if (NS_FAILED(mozilla::Base64Decode(encodedString, result))) { JS_ReportError(cx, "Failed to decode base64 string!"); return false; } @@ -2946,6 +2854,8 @@ nsXPConnect::Base64Decode(JSContext *cx, jsval val, jsval *out) return true; } +} // namespace xpc + NS_IMETHODIMP nsXPConnect::SetDebugModeWhenPossible(bool mode, bool allowSyncDisable) { diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index c10527c16444..e196dab01452 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -532,24 +532,6 @@ public: nsresult GetInfoForIID(const nsIID * aIID, nsIInterfaceInfo** info); nsresult GetInfoForName(const char * name, nsIInterfaceInfo** info); - static nsresult Base64Encode(const nsACString &aString, - nsACString &aBinary); - - static nsresult Base64Encode(const nsAString &aString, - nsAString &aBinaryData); - - // If this returns false then an exception will be set on cx. - static JSBool Base64Encode(JSContext *cx, jsval val, jsval *out); - - static nsresult Base64Decode(const nsACString &aBinaryData, - nsACString &aString); - - static nsresult Base64Decode(const nsAString &aBinaryData, - nsAString &aString); - - // If this returns false then an exception will be set on cx. - static JSBool Base64Decode(JSContext *cx, jsval val, jsval *out); - // nsCycleCollectionParticipant NS_IMETHOD Root(void *p); NS_IMETHOD Unlink(void *p); diff --git a/js/xpconnect/src/xpcpublic.h b/js/xpconnect/src/xpcpublic.h index 2b836e361aaa..10316b72ec94 100644 --- a/js/xpconnect/src/xpcpublic.h +++ b/js/xpconnect/src/xpcpublic.h @@ -196,6 +196,10 @@ xpc_ActivateDebugMode(); namespace xpc { +// If these functions return false, then an exception will be set on cx. +bool Base64Encode(JSContext *cx, JS::Value val, JS::Value *out); +bool Base64Decode(JSContext *cx, JS::Value val, JS::Value *out); + /** * Convert an nsString to jsval, returning true on success. * Note, the ownership of the string buffer may be moved from str to rval. diff --git a/xpcom/io/Base64.cpp b/xpcom/io/Base64.cpp index aad01788d9c1..ae0dd71cbcb4 100644 --- a/xpcom/io/Base64.cpp +++ b/xpcom/io/Base64.cpp @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -39,6 +39,9 @@ #include "Base64.h" #include "nsIInputStream.h" +#include "nsStringGlue.h" + +#include "plbase64.h" namespace { @@ -255,4 +258,100 @@ Base64EncodeInputStream(nsIInputStream *aInputStream, return EncodeInputStream(aInputStream, aDest, aCount, aOffset); } +nsresult +Base64Encode(const nsACString &aBinaryData, nsACString &aString) +{ + // Check for overflow. + if (aBinaryData.Length() > (PR_UINT32_MAX / 4) * 3) { + return NS_ERROR_FAILURE; + } + + PRUint32 stringLen = ((aBinaryData.Length() + 2) / 3) * 4; + + char *buffer; + + // Add one byte for null termination. + if (aString.SetCapacity(stringLen + 1) && + (buffer = aString.BeginWriting()) && + PL_Base64Encode(aBinaryData.BeginReading(), aBinaryData.Length(), buffer)) { + // PL_Base64Encode doesn't null terminate the buffer for us when we pass + // the buffer in. Do that manually. + buffer[stringLen] = '\0'; + + aString.SetLength(stringLen); + return NS_OK; + } + + aString.Truncate(); + return NS_ERROR_INVALID_ARG; +} + +nsresult +Base64Encode(const nsAString &aString, nsAString &aBinaryData) +{ + NS_LossyConvertUTF16toASCII string(aString); + nsCAutoString binaryData; + + nsresult rv = Base64Encode(string, binaryData); + if (NS_SUCCEEDED(rv)) { + CopyASCIItoUTF16(binaryData, aBinaryData); + } else { + aBinaryData.Truncate(); + } + + return rv; +} + +nsresult +Base64Decode(const nsACString &aString, nsACString &aBinaryData) +{ + // Check for overflow. + if (aString.Length() > PR_UINT32_MAX / 3) { + return NS_ERROR_FAILURE; + } + + PRUint32 binaryDataLen = ((aString.Length() * 3) / 4); + + char *buffer; + + // Add one byte for null termination. + if (aBinaryData.SetCapacity(binaryDataLen + 1) && + (buffer = aBinaryData.BeginWriting()) && + PL_Base64Decode(aString.BeginReading(), aString.Length(), buffer)) { + // PL_Base64Decode doesn't null terminate the buffer for us when we pass + // the buffer in. Do that manually, taking into account the number of '=' + // characters we were passed. + if (!aString.IsEmpty() && aString[aString.Length() - 1] == '=') { + if (aString.Length() > 1 && aString[aString.Length() - 2] == '=') { + binaryDataLen -= 2; + } else { + binaryDataLen -= 1; + } + } + buffer[binaryDataLen] = '\0'; + + aBinaryData.SetLength(binaryDataLen); + return NS_OK; + } + + aBinaryData.Truncate(); + return NS_ERROR_INVALID_ARG; +} + +nsresult +Base64Decode(const nsAString &aBinaryData, nsAString &aString) +{ + NS_LossyConvertUTF16toASCII binaryData(aBinaryData); + nsCAutoString string; + + nsresult rv = Base64Decode(binaryData, string); + if (NS_SUCCEEDED(rv)) { + CopyASCIItoUTF16(string, aString); + } else { + aString.Truncate(); + } + + return rv; +} + } // namespace mozilla diff --git a/xpcom/io/Base64.h b/xpcom/io/Base64.h index 3be044ad6c47..a9a81484a8f3 100644 --- a/xpcom/io/Base64.h +++ b/xpcom/io/Base64.h @@ -55,6 +55,16 @@ Base64EncodeInputStream(nsIInputStream *aInputStream, PRUint32 aCount, PRUint32 aOffset = 0); +nsresult +Base64Encode(const nsACString &aString, nsACString &aBinary); +nsresult +Base64Encode(const nsAString &aString, nsAString &aBinaryData); + +nsresult +Base64Decode(const nsACString &aBinaryData, nsACString &aString); +nsresult +Base64Decode(const nsAString &aBinaryData, nsAString &aString); + } // namespace mozilla #endif