tor-browser

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

URLSearchParams.cpp (6174B)


      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 "mozilla/dom/URLSearchParams.h"
      8 
      9 // clang-format off
     10 #include "mozilla/Encoding.h"
     11 #include "encoding_rs.h"
     12 // clang-format on
     13 
     14 #include <new>
     15 #include <utility>
     16 
     17 #include "js/StructuredClone.h"
     18 #include "mozilla/ArrayIterator.h"
     19 #include "mozilla/ErrorResult.h"
     20 #include "mozilla/dom/BindingDeclarations.h"
     21 #include "mozilla/dom/Record.h"
     22 #include "mozilla/dom/StructuredCloneHolder.h"
     23 #include "mozilla/dom/URLSearchParamsBinding.h"
     24 #include "nsDOMString.h"
     25 #include "nsError.h"
     26 #include "nsIGlobalObject.h"
     27 #include "nsLiteralString.h"
     28 #include "nsPrintfCString.h"
     29 #include "nsString.h"
     30 #include "nsStringFlags.h"
     31 #include "nsStringIterator.h"
     32 #include "nsStringStream.h"
     33 #include "nsURLHelper.h"
     34 
     35 namespace mozilla::dom {
     36 
     37 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(URLSearchParams, mParent, mObserver)
     38 NS_IMPL_CYCLE_COLLECTING_ADDREF(URLSearchParams)
     39 NS_IMPL_CYCLE_COLLECTING_RELEASE(URLSearchParams)
     40 
     41 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(URLSearchParams)
     42  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
     43  NS_INTERFACE_MAP_ENTRY(nsISupports)
     44 NS_INTERFACE_MAP_END
     45 
     46 URLSearchParams::URLSearchParams(nsISupports* aParent,
     47                                 URLSearchParamsObserver* aObserver)
     48    : mParams(new URLParams()), mParent(aParent), mObserver(aObserver) {}
     49 
     50 URLSearchParams::~URLSearchParams() { DeleteAll(); }
     51 
     52 JSObject* URLSearchParams::WrapObject(JSContext* aCx,
     53                                      JS::Handle<JSObject*> aGivenProto) {
     54  return URLSearchParams_Binding::Wrap(aCx, this, aGivenProto);
     55 }
     56 
     57 /* static */
     58 already_AddRefed<URLSearchParams> URLSearchParams::Constructor(
     59    const GlobalObject& aGlobal,
     60    const UTF8StringSequenceSequenceOrUTF8StringUTF8StringRecordOrUTF8String&
     61        aInit,
     62    ErrorResult& aRv) {
     63  RefPtr<URLSearchParams> sp =
     64      new URLSearchParams(aGlobal.GetAsSupports(), nullptr);
     65 
     66  if (aInit.IsUTF8String()) {
     67    const auto& input = aInit.GetAsUTF8String();
     68    if (StringBeginsWith(input, "?"_ns)) {
     69      sp->ParseInput(Substring(input, 1, input.Length() - 1));
     70    } else {
     71      sp->ParseInput(input);
     72    }
     73  } else if (aInit.IsUTF8StringSequenceSequence()) {
     74    const Sequence<Sequence<nsCString>>& list =
     75        aInit.GetAsUTF8StringSequenceSequence();
     76    for (uint32_t i = 0; i < list.Length(); ++i) {
     77      const Sequence<nsCString>& item = list[i];
     78      if (item.Length() != 2) {
     79        nsPrintfCString err("Expected 2 items in pair but got %zu",
     80                            item.Length());
     81        aRv.ThrowTypeError(err);
     82        return nullptr;
     83      }
     84      sp->Append(item[0], item[1]);
     85    }
     86  } else if (aInit.IsUTF8StringUTF8StringRecord()) {
     87    const Record<nsCString, nsCString>& record =
     88        aInit.GetAsUTF8StringUTF8StringRecord();
     89    for (auto& entry : record.Entries()) {
     90      sp->Append(entry.mKey, entry.mValue);
     91    }
     92  } else {
     93    MOZ_CRASH("This should not happen.");
     94  }
     95 
     96  return sp.forget();
     97 }
     98 
     99 void URLSearchParams::ParseInput(const nsACString& aInput) {
    100  mParams->ParseInput(aInput);
    101 }
    102 
    103 uint32_t URLSearchParams::Size() const { return mParams->Length(); }
    104 
    105 void URLSearchParams::Get(const nsACString& aName, nsACString& aRetval) {
    106  return mParams->Get(aName, aRetval);
    107 }
    108 
    109 void URLSearchParams::GetAll(const nsACString& aName,
    110                             nsTArray<nsCString>& aRetval) {
    111  return mParams->GetAll(aName, aRetval);
    112 }
    113 
    114 void URLSearchParams::Set(const nsACString& aName, const nsACString& aValue) {
    115  mParams->Set(aName, aValue);
    116  NotifyObserver();
    117 }
    118 
    119 void URLSearchParams::Append(const nsACString& aName,
    120                             const nsACString& aValue) {
    121  mParams->Append(aName, aValue);
    122  NotifyObserver();
    123 }
    124 
    125 bool URLSearchParams::Has(const nsACString& aName,
    126                          const Optional<nsACString>& aValue) {
    127  if (!aValue.WasPassed()) {
    128    return mParams->Has(aName);
    129  }
    130  return mParams->Has(aName, aValue.Value());
    131 }
    132 
    133 void URLSearchParams::Delete(const nsACString& aName,
    134                             const Optional<nsACString>& aValue) {
    135  if (!aValue.WasPassed()) {
    136    mParams->Delete(aName);
    137    NotifyObserver();
    138    return;
    139  }
    140  mParams->Delete(aName, aValue.Value());
    141  NotifyObserver();
    142 }
    143 
    144 void URLSearchParams::DeleteAll() { mParams->DeleteAll(); }
    145 
    146 void URLSearchParams::Serialize(nsACString& aValue) const {
    147  mParams->Serialize(aValue, true);
    148 }
    149 
    150 // TODO(emilio): Allow stringifier attributes with CString return values.
    151 void URLSearchParams::Stringify(nsAString& aValue) const {
    152  nsAutoCString serialized;
    153  mParams->Serialize(serialized, true);
    154  CopyUTF8toUTF16(serialized, aValue);
    155 }
    156 
    157 void URLSearchParams::NotifyObserver() {
    158  if (mObserver) {
    159    mObserver->URLSearchParamsUpdated(this);
    160  }
    161 }
    162 
    163 uint32_t URLSearchParams::GetIterableLength() const {
    164  return mParams->Length();
    165 }
    166 
    167 const nsACString& URLSearchParams::GetKeyAtIndex(uint32_t aIndex) const {
    168  return mParams->GetKeyAtIndex(aIndex);
    169 }
    170 
    171 const nsACString& URLSearchParams::GetValueAtIndex(uint32_t aIndex) const {
    172  return mParams->GetValueAtIndex(aIndex);
    173 }
    174 
    175 void URLSearchParams::Sort(ErrorResult& aRv) {
    176  mParams->Sort();
    177  NotifyObserver();
    178 }
    179 
    180 // contentTypeWithCharset can be set to the contentType or
    181 // contentType+charset based on what the spec says.
    182 // See: https://fetch.spec.whatwg.org/#concept-bodyinit-extract
    183 nsresult URLSearchParams::GetSendInfo(nsIInputStream** aBody,
    184                                      uint64_t* aContentLength,
    185                                      nsACString& aContentTypeWithCharset,
    186                                      nsACString& aCharset) const {
    187  aContentTypeWithCharset.AssignLiteral(
    188      "application/x-www-form-urlencoded;charset=UTF-8");
    189  aCharset.AssignLiteral("UTF-8");
    190 
    191  nsAutoCString serialized;
    192  Serialize(serialized);
    193  *aContentLength = serialized.Length();
    194  return NS_NewCStringInputStream(aBody, std::move(serialized));
    195 }
    196 
    197 }  // namespace mozilla::dom