dom/base/nsStructuredCloneContainer.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
michael@0 2 * vim: set ts=8 sw=2 et tw=80:
michael@0 3 *
michael@0 4 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 5 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 7
michael@0 8 #include "nsStructuredCloneContainer.h"
michael@0 9
michael@0 10 #include "nsCOMPtr.h"
michael@0 11 #include "nsIScriptContext.h"
michael@0 12 #include "nsIVariant.h"
michael@0 13 #include "nsIXPConnect.h"
michael@0 14 #include "nsServiceManagerUtils.h"
michael@0 15 #include "nsContentUtils.h"
michael@0 16 #include "jsapi.h"
michael@0 17 #include "js/StructuredClone.h"
michael@0 18
michael@0 19 #include "mozilla/Base64.h"
michael@0 20
michael@0 21 using namespace mozilla;
michael@0 22
michael@0 23 NS_IMPL_ADDREF(nsStructuredCloneContainer)
michael@0 24 NS_IMPL_RELEASE(nsStructuredCloneContainer)
michael@0 25
michael@0 26 NS_INTERFACE_MAP_BEGIN(nsStructuredCloneContainer)
michael@0 27 NS_INTERFACE_MAP_ENTRY(nsIStructuredCloneContainer)
michael@0 28 NS_INTERFACE_MAP_ENTRY(nsISupports)
michael@0 29 NS_INTERFACE_MAP_END
michael@0 30
michael@0 31 nsStructuredCloneContainer::nsStructuredCloneContainer()
michael@0 32 : mData(nullptr), mSize(0), mVersion(0)
michael@0 33 {
michael@0 34 }
michael@0 35
michael@0 36 nsStructuredCloneContainer::~nsStructuredCloneContainer()
michael@0 37 {
michael@0 38 free(mData);
michael@0 39 }
michael@0 40
michael@0 41 nsresult
michael@0 42 nsStructuredCloneContainer::InitFromJSVal(JS::Handle<JS::Value> aData,
michael@0 43 JSContext* aCx)
michael@0 44 {
michael@0 45 NS_ENSURE_STATE(!mData);
michael@0 46 NS_ENSURE_ARG_POINTER(aCx);
michael@0 47
michael@0 48 // Make sure that we serialize in the right context.
michael@0 49 MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
michael@0 50 JS::Rooted<JS::Value> jsData(aCx, aData);
michael@0 51 bool success = JS_WrapValue(aCx, &jsData);
michael@0 52 NS_ENSURE_STATE(success);
michael@0 53
michael@0 54 uint64_t* jsBytes = nullptr;
michael@0 55 success = JS_WriteStructuredClone(aCx, jsData, &jsBytes, &mSize,
michael@0 56 nullptr, nullptr,
michael@0 57 JS::UndefinedHandleValue);
michael@0 58 NS_ENSURE_STATE(success);
michael@0 59 NS_ENSURE_STATE(jsBytes);
michael@0 60
michael@0 61 // Copy jsBytes into our own buffer.
michael@0 62 mData = (uint64_t*) malloc(mSize);
michael@0 63 if (!mData) {
michael@0 64 mSize = 0;
michael@0 65 mVersion = 0;
michael@0 66
michael@0 67 JS_ClearStructuredClone(jsBytes, mSize, nullptr, nullptr);
michael@0 68 return NS_ERROR_FAILURE;
michael@0 69 }
michael@0 70 else {
michael@0 71 mVersion = JS_STRUCTURED_CLONE_VERSION;
michael@0 72 }
michael@0 73
michael@0 74 memcpy(mData, jsBytes, mSize);
michael@0 75
michael@0 76 JS_ClearStructuredClone(jsBytes, mSize, nullptr, nullptr);
michael@0 77 return NS_OK;
michael@0 78 }
michael@0 79
michael@0 80 nsresult
michael@0 81 nsStructuredCloneContainer::InitFromBase64(const nsAString &aData,
michael@0 82 uint32_t aFormatVersion,
michael@0 83 JSContext *aCx)
michael@0 84 {
michael@0 85 NS_ENSURE_STATE(!mData);
michael@0 86
michael@0 87 NS_ConvertUTF16toUTF8 data(aData);
michael@0 88
michael@0 89 nsAutoCString binaryData;
michael@0 90 nsresult rv = Base64Decode(data, binaryData);
michael@0 91 NS_ENSURE_SUCCESS(rv, rv);
michael@0 92
michael@0 93 // Copy the string's data into our own buffer.
michael@0 94 mData = (uint64_t*) malloc(binaryData.Length());
michael@0 95 NS_ENSURE_STATE(mData);
michael@0 96 memcpy(mData, binaryData.get(), binaryData.Length());
michael@0 97
michael@0 98 mSize = binaryData.Length();
michael@0 99 mVersion = aFormatVersion;
michael@0 100 return NS_OK;
michael@0 101 }
michael@0 102
michael@0 103
michael@0 104 nsresult
michael@0 105 nsStructuredCloneContainer::DeserializeToVariant(JSContext *aCx,
michael@0 106 nsIVariant **aData)
michael@0 107 {
michael@0 108 NS_ENSURE_STATE(mData);
michael@0 109 NS_ENSURE_ARG_POINTER(aData);
michael@0 110 *aData = nullptr;
michael@0 111
michael@0 112 // Deserialize to a JS::Value.
michael@0 113 JS::Rooted<JS::Value> jsStateObj(aCx);
michael@0 114 bool hasTransferable = false;
michael@0 115 bool success = JS_ReadStructuredClone(aCx, mData, mSize, mVersion,
michael@0 116 &jsStateObj, nullptr, nullptr) &&
michael@0 117 JS_StructuredCloneHasTransferables(mData, mSize,
michael@0 118 &hasTransferable);
michael@0 119 // We want to be sure that mData doesn't contain transferable objects
michael@0 120 MOZ_ASSERT(!hasTransferable);
michael@0 121 NS_ENSURE_STATE(success && !hasTransferable);
michael@0 122
michael@0 123 // Now wrap the JS::Value as an nsIVariant.
michael@0 124 nsCOMPtr<nsIVariant> varStateObj;
michael@0 125 nsCOMPtr<nsIXPConnect> xpconnect = do_GetService(nsIXPConnect::GetCID());
michael@0 126 NS_ENSURE_STATE(xpconnect);
michael@0 127 xpconnect->JSValToVariant(aCx, jsStateObj, getter_AddRefs(varStateObj));
michael@0 128 NS_ENSURE_STATE(varStateObj);
michael@0 129
michael@0 130 NS_ADDREF(*aData = varStateObj);
michael@0 131 return NS_OK;
michael@0 132 }
michael@0 133
michael@0 134 nsresult
michael@0 135 nsStructuredCloneContainer::GetDataAsBase64(nsAString &aOut)
michael@0 136 {
michael@0 137 NS_ENSURE_STATE(mData);
michael@0 138 aOut.Truncate();
michael@0 139
michael@0 140 nsAutoCString binaryData(reinterpret_cast<char*>(mData), mSize);
michael@0 141 nsAutoCString base64Data;
michael@0 142 nsresult rv = Base64Encode(binaryData, base64Data);
michael@0 143 NS_ENSURE_SUCCESS(rv, rv);
michael@0 144
michael@0 145 aOut.Assign(NS_ConvertASCIItoUTF16(base64Data));
michael@0 146 return NS_OK;
michael@0 147 }
michael@0 148
michael@0 149 nsresult
michael@0 150 nsStructuredCloneContainer::GetSerializedNBytes(uint64_t *aSize)
michael@0 151 {
michael@0 152 NS_ENSURE_STATE(mData);
michael@0 153 NS_ENSURE_ARG_POINTER(aSize);
michael@0 154
michael@0 155 // mSize is a size_t, while aSize is a uint64_t. We rely on an implicit cast
michael@0 156 // here so that we'll get a compile error if a size_t-to-uint64_t cast is
michael@0 157 // narrowing.
michael@0 158 *aSize = mSize;
michael@0 159
michael@0 160 return NS_OK;
michael@0 161 }
michael@0 162
michael@0 163 nsresult
michael@0 164 nsStructuredCloneContainer::GetFormatVersion(uint32_t *aFormatVersion)
michael@0 165 {
michael@0 166 NS_ENSURE_STATE(mData);
michael@0 167 NS_ENSURE_ARG_POINTER(aFormatVersion);
michael@0 168 *aFormatVersion = mVersion;
michael@0 169 return NS_OK;
michael@0 170 }

mercurial