IndexedDatabaseInlines.h (7074B)
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 #ifndef IndexedDatabaseInlines_h 8 #define IndexedDatabaseInlines_h 9 10 #ifndef mozilla_dom_indexeddatabase_h__ 11 # error Must include IndexedDatabase.h first 12 #endif 13 14 #include "DatabaseFileInfo.h" 15 #include "mozilla/dom/DOMStringList.h" 16 #include "mozilla/dom/File.h" 17 #include "mozilla/dom/ToJSValue.h" 18 #include "mozilla/dom/indexedDB/PBackgroundIDBSharedTypes.h" 19 20 namespace mozilla::dom::indexedDB { 21 22 #ifdef NS_BUILD_REFCNT_LOGGING 23 inline StructuredCloneFileChild::StructuredCloneFileChild( 24 StructuredCloneFileChild&& aOther) 25 : StructuredCloneFileBase{std::move(aOther)}, 26 mContents{std::move(aOther.mContents)} { 27 MOZ_COUNT_CTOR(StructuredCloneFileChild); 28 } 29 #endif 30 31 inline StructuredCloneFileChild::~StructuredCloneFileChild() { 32 MOZ_COUNT_DTOR(StructuredCloneFileChild); 33 } 34 35 inline StructuredCloneFileChild::StructuredCloneFileChild(FileType aType) 36 : StructuredCloneFileBase{aType}, mContents{Nothing()} { 37 MOZ_COUNT_CTOR(StructuredCloneFileChild); 38 } 39 40 inline StructuredCloneFileChild::StructuredCloneFileChild( 41 FileType aType, RefPtr<dom::Blob> aBlob) 42 : StructuredCloneFileBase{aType}, mContents{std::move(aBlob)} { 43 MOZ_ASSERT(eBlob == aType || eStructuredClone == aType); 44 MOZ_ASSERT(mContents->as<RefPtr<dom::Blob>>()); 45 MOZ_COUNT_CTOR(StructuredCloneFileChild); 46 } 47 48 inline StructuredCloneFileParent::StructuredCloneFileParent( 49 FileType aType, SafeRefPtr<DatabaseFileInfo> aFileInfo) 50 : StructuredCloneFileBase{aType}, mContents{Some(std::move(aFileInfo))} { 51 MOZ_ASSERT(**mContents); 52 MOZ_COUNT_CTOR(StructuredCloneFileParent); 53 } 54 55 #ifdef NS_BUILD_REFCNT_LOGGING 56 inline StructuredCloneFileParent::StructuredCloneFileParent( 57 StructuredCloneFileParent&& aOther) 58 : StructuredCloneFileBase{std::move(aOther)}, 59 mContents{std::move(aOther.mContents)} { 60 MOZ_COUNT_CTOR(StructuredCloneFileParent); 61 } 62 #endif 63 64 inline StructuredCloneFileParent::~StructuredCloneFileParent() { 65 MOZ_COUNT_DTOR(StructuredCloneFileParent); 66 } 67 68 inline SafeRefPtr<DatabaseFileInfo> StructuredCloneFileParent::FileInfoPtr() 69 const { 70 return (*mContents)->clonePtr(); 71 } 72 73 inline RefPtr<dom::Blob> StructuredCloneFileChild::BlobPtr() const { 74 return mContents->as<RefPtr<dom::Blob>>(); 75 } 76 77 template <typename StructuredCloneFile> 78 inline StructuredCloneReadInfo<StructuredCloneFile>::StructuredCloneReadInfo( 79 JS::StructuredCloneScope aScope) 80 : StructuredCloneReadInfoBase(JSStructuredCloneData{aScope}) { 81 MOZ_COUNT_CTOR(StructuredCloneReadInfo); 82 } 83 84 template <typename StructuredCloneFile> 85 inline StructuredCloneReadInfo<StructuredCloneFile>::StructuredCloneReadInfo() 86 : StructuredCloneReadInfo( 87 JS::StructuredCloneScope::DifferentProcessForIndexedDB) {} 88 89 template <typename StructuredCloneFile> 90 inline StructuredCloneReadInfo<StructuredCloneFile>::StructuredCloneReadInfo( 91 JSStructuredCloneData&& aData, nsTArray<StructuredCloneFile> aFiles) 92 : StructuredCloneReadInfoBase{std::move(aData)}, mFiles{std::move(aFiles)} { 93 MOZ_COUNT_CTOR(StructuredCloneReadInfo); 94 } 95 96 #ifdef NS_BUILD_REFCNT_LOGGING 97 template <typename StructuredCloneFile> 98 inline StructuredCloneReadInfo<StructuredCloneFile>::StructuredCloneReadInfo( 99 StructuredCloneReadInfo&& aOther) noexcept 100 : StructuredCloneReadInfoBase{std::move(aOther)}, 101 mFiles{std::move(aOther.mFiles)} { 102 MOZ_COUNT_CTOR(StructuredCloneReadInfo); 103 } 104 105 template <typename StructuredCloneFile> 106 inline StructuredCloneReadInfo< 107 StructuredCloneFile>::~StructuredCloneReadInfo() { 108 MOZ_COUNT_DTOR(StructuredCloneReadInfo); 109 } 110 111 #endif 112 113 template <typename StructuredCloneFile> 114 inline size_t StructuredCloneReadInfo<StructuredCloneFile>::Size() const { 115 // We do not check the structured clone size against 116 // IndexedDatabaseManager::MaxStructuredCloneSize here. 117 // The size has already been validated before being sent from the content 118 // process to the parent process. At this stage, the parent process has 119 // either stored the data in the database or written it to a separate file, 120 // ensuring that size constraints are enforced elsewhere. 121 // 122 // If necessary, we could add a warning to flag oversized structured clones 123 // here. However, failing the request entirely would require additional 124 // changes, such as making these methods fallible, which would add complexity. 125 126 // Serialized structured clone size in bytes. For structured clone sizes > 127 // IPC::kMessageBufferShmemThreshold, only the size and shared memory handle 128 // are included in the IPC message. The value 16 is an estimate. 129 size_t size = 130 Data().Size() > IPC::kMessageBufferShmemThreshold ? 16 : Data().Size(); 131 132 for (uint32_t i = 0, count = mFiles.Length(); i < count; ++i) { 133 // We don't want to calculate the size of files and so on, because are 134 // mainly file descriptors. 135 size += sizeof(uint64_t); 136 } 137 138 return size; 139 } 140 141 inline StructuredCloneReadInfoChild::StructuredCloneReadInfoChild( 142 JSStructuredCloneData&& aData, nsTArray<StructuredCloneFileChild> aFiles, 143 IDBDatabase* aDatabase) 144 : StructuredCloneReadInfo{std::move(aData), std::move(aFiles)}, 145 mDatabase{aDatabase} {} 146 147 template <typename E, typename Map> 148 RefPtr<DOMStringList> CreateSortedDOMStringList(const nsTArray<E>& aArray, 149 const Map& aMap) { 150 auto list = MakeRefPtr<DOMStringList>(); 151 152 if (!aArray.IsEmpty()) { 153 nsTArray<nsString>& mapped = list->StringArray(); 154 mapped.SetCapacity(aArray.Length()); 155 156 std::transform(aArray.cbegin(), aArray.cend(), MakeBackInserter(mapped), 157 aMap); 158 159 mapped.Sort(); 160 } 161 162 return list; 163 } 164 165 template <typename StructuredCloneReadInfoType> 166 JSObject* StructuredCloneReadCallback( 167 JSContext* const aCx, JSStructuredCloneReader* const aReader, 168 const JS::CloneDataPolicy& aCloneDataPolicy, const uint32_t aTag, 169 const uint32_t aData, void* const aClosure) { 170 auto* const database = [aClosure]() -> IDBDatabase* { 171 if constexpr (std::is_same_v<StructuredCloneReadInfoType, 172 StructuredCloneReadInfoChild>) { 173 return static_cast<StructuredCloneReadInfoChild*>(aClosure)->Database(); 174 } 175 (void)aClosure; 176 return nullptr; 177 }(); 178 return CommonStructuredCloneReadCallback( 179 aCx, aReader, aCloneDataPolicy, aTag, aData, 180 static_cast<StructuredCloneReadInfoType*>(aClosure), database); 181 } 182 183 template <typename T> 184 bool WrapAsJSObject(JSContext* const aCx, T& aBaseObject, 185 JS::MutableHandle<JSObject*> aResult) { 186 JS::Rooted<JS::Value> wrappedValue(aCx); 187 if (!ToJSValue(aCx, aBaseObject, &wrappedValue)) { 188 return false; 189 } 190 191 aResult.set(&wrappedValue.toObject()); 192 return true; 193 } 194 195 } // namespace mozilla::dom::indexedDB 196 197 #endif // IndexedDatabaseInlines_h