tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsStructuredCloneContainer.cpp (4097B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "nsStructuredCloneContainer.h"
      8 
      9 #include <cstddef>
     10 
     11 #include "ErrorList.h"
     12 #include "js/RootingAPI.h"
     13 #include "js/StructuredClone.h"
     14 #include "js/Value.h"
     15 #include "mozilla/Assertions.h"
     16 #include "mozilla/Base64.h"
     17 #include "mozilla/CheckedInt.h"
     18 #include "mozilla/DebugOnly.h"
     19 #include "mozilla/ErrorResult.h"
     20 #include "mozilla/fallible.h"
     21 #include "nsCOMPtr.h"
     22 #include "nsDebug.h"
     23 #include "nsError.h"
     24 #include "nsIVariant.h"
     25 #include "nsIXPConnect.h"
     26 #include "nsString.h"
     27 #include "nscore.h"
     28 
     29 using namespace mozilla;
     30 using namespace mozilla::dom;
     31 
     32 NS_IMPL_ADDREF(nsStructuredCloneContainer)
     33 NS_IMPL_RELEASE(nsStructuredCloneContainer)
     34 
     35 NS_INTERFACE_MAP_BEGIN(nsStructuredCloneContainer)
     36  NS_INTERFACE_MAP_ENTRY(nsIStructuredCloneContainer)
     37  NS_INTERFACE_MAP_ENTRY(nsISupports)
     38 NS_INTERFACE_MAP_END
     39 
     40 nsStructuredCloneContainer::nsStructuredCloneContainer() : mVersion(0) {}
     41 nsStructuredCloneContainer::nsStructuredCloneContainer(uint32_t aVersion)
     42    : mVersion(aVersion) {}
     43 
     44 nsStructuredCloneContainer::~nsStructuredCloneContainer() = default;
     45 
     46 NS_IMETHODIMP
     47 nsStructuredCloneContainer::InitFromJSVal(JS::Handle<JS::Value> aData,
     48                                          JSContext* aCx) {
     49  if (DataLength()) {
     50    return NS_ERROR_FAILURE;
     51  }
     52 
     53  ErrorResult rv;
     54  Write(aCx, aData, rv);
     55  if (NS_WARN_IF(rv.Failed())) {
     56    // XXX propagate the error message as well.
     57    // We cannot StealNSResult because we threw a DOM exception.
     58    rv.SuppressException();
     59    return NS_ERROR_DOM_DATA_CLONE_ERR;
     60  }
     61 
     62  mVersion = JS_STRUCTURED_CLONE_VERSION;
     63  return NS_OK;
     64 }
     65 
     66 NS_IMETHODIMP
     67 nsStructuredCloneContainer::InitFromBase64(const nsAString& aData,
     68                                           uint32_t aFormatVersion) {
     69  if (DataLength()) {
     70    return NS_ERROR_FAILURE;
     71  }
     72 
     73  NS_ConvertUTF16toUTF8 data(aData);
     74 
     75  nsAutoCString binaryData;
     76  nsresult rv = Base64Decode(data, binaryData);
     77  NS_ENSURE_SUCCESS(rv, rv);
     78 
     79  if (!CopyExternalData(binaryData.get(), binaryData.Length())) {
     80    return NS_ERROR_OUT_OF_MEMORY;
     81  }
     82 
     83  mVersion = aFormatVersion;
     84  return NS_OK;
     85 }
     86 
     87 nsresult nsStructuredCloneContainer::DeserializeToJsval(
     88    JSContext* aCx, JS::MutableHandle<JS::Value> aValue) {
     89  aValue.setNull();
     90  JS::Rooted<JS::Value> jsStateObj(aCx);
     91 
     92  ErrorResult rv;
     93  Read(aCx, &jsStateObj, rv);
     94  if (NS_WARN_IF(rv.Failed())) {
     95    // XXX propagate the error message as well.
     96    // We cannot StealNSResult because we threw a DOM exception.
     97    rv.SuppressException();
     98    return NS_ERROR_DOM_DATA_CLONE_ERR;
     99  }
    100 
    101  aValue.set(jsStateObj);
    102  return NS_OK;
    103 }
    104 
    105 NS_IMETHODIMP
    106 nsStructuredCloneContainer::GetDataAsBase64(nsAString& aOut) {
    107  aOut.Truncate();
    108 
    109  if (!DataLength()) {
    110    return NS_ERROR_FAILURE;
    111  }
    112 
    113  if (HasClonedDOMObjects()) {
    114    return NS_ERROR_FAILURE;
    115  }
    116 
    117  auto iter = Data().Start();
    118  size_t size = Data().Size();
    119  CheckedInt<nsAutoCString::size_type> sizeCheck(size);
    120  if (!sizeCheck.isValid()) {
    121    return NS_ERROR_FAILURE;
    122  }
    123 
    124  nsAutoCString binaryData;
    125  if (!binaryData.SetLength(size, fallible)) {
    126    return NS_ERROR_OUT_OF_MEMORY;
    127  }
    128 
    129  DebugOnly<bool> res = Data().ReadBytes(iter, binaryData.BeginWriting(), size);
    130  MOZ_ASSERT(res);
    131 
    132  nsresult rv = Base64Encode(binaryData, aOut);
    133  if (NS_WARN_IF(NS_FAILED(rv))) {
    134    return rv;
    135  }
    136 
    137  return NS_OK;
    138 }
    139 
    140 NS_IMETHODIMP
    141 nsStructuredCloneContainer::GetSerializedNBytes(uint64_t* aSize) {
    142  NS_ENSURE_ARG_POINTER(aSize);
    143 
    144  if (!DataLength()) {
    145    return NS_ERROR_FAILURE;
    146  }
    147 
    148  *aSize = DataLength();
    149  return NS_OK;
    150 }
    151 
    152 NS_IMETHODIMP
    153 nsStructuredCloneContainer::GetFormatVersion(uint32_t* aFormatVersion) {
    154  NS_ENSURE_ARG_POINTER(aFormatVersion);
    155 
    156  if (!DataLength()) {
    157    return NS_ERROR_FAILURE;
    158  }
    159 
    160  *aFormatVersion = mVersion;
    161  return NS_OK;
    162 }