Modern IDB: Possible crash deallocating IDBDatabaseInfo/IDBObjectStoreInfo/IDBIndexInfo.
[WebKit-https.git] / Source / WebCore / Modules / indexeddb / shared / IDBDatabaseInfo.cpp
1 /*
2  * Copyright (C) 2015 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "IDBDatabaseInfo.h"
28
29 #if ENABLE(INDEXED_DATABASE)
30
31 namespace WebCore {
32
33 IDBDatabaseInfo::IDBDatabaseInfo()
34 {
35 }
36
37 IDBDatabaseInfo::IDBDatabaseInfo(const String& name, uint64_t version)
38     : m_name(name)
39     , m_version(version)
40 {
41 }
42
43 IDBDatabaseInfo::IDBDatabaseInfo(const IDBDatabaseInfo& other, IsolatedCopyTag)
44     : m_name(other.m_name.isolatedCopy())
45     , m_version(other.m_version)
46     , m_maxObjectStoreID(other.m_maxObjectStoreID)
47 {
48     for (auto entry : other.m_objectStoreMap)
49         m_objectStoreMap.set(entry.key, entry.value.isolatedCopy());
50 }
51
52 IDBDatabaseInfo IDBDatabaseInfo::isolatedCopy() const
53 {
54     return { *this, IDBDatabaseInfo::IsolatedCopy };
55 }
56
57 bool IDBDatabaseInfo::hasObjectStore(const String& name) const
58 {
59     for (auto& objectStore : m_objectStoreMap.values()) {
60         if (objectStore.name() == name)
61             return true;
62     }
63
64     return false;
65 }
66
67 IDBObjectStoreInfo IDBDatabaseInfo::createNewObjectStore(const String& name, const IDBKeyPath& keyPath, bool autoIncrement)
68 {
69     IDBObjectStoreInfo info(++m_maxObjectStoreID, name, keyPath, autoIncrement);
70     m_objectStoreMap.set(info.identifier(), info);
71     return info;
72 }
73
74 void IDBDatabaseInfo::addExistingObjectStore(const IDBObjectStoreInfo& info)
75 {
76     ASSERT(!m_objectStoreMap.contains(info.identifier()));
77
78     if (info.identifier() > m_maxObjectStoreID)
79         m_maxObjectStoreID = info.identifier();
80
81     m_objectStoreMap.set(info.identifier(), info);
82 }
83
84 IDBObjectStoreInfo* IDBDatabaseInfo::getInfoForExistingObjectStore(uint64_t objectStoreIdentifier)
85 {
86     auto iterator = m_objectStoreMap.find(objectStoreIdentifier);
87     if (iterator == m_objectStoreMap.end())
88         return nullptr;
89
90     return &iterator->value;
91 }
92
93 IDBObjectStoreInfo* IDBDatabaseInfo::getInfoForExistingObjectStore(const String& name)
94 {
95     for (auto& objectStore : m_objectStoreMap.values()) {
96         if (objectStore.name() == name)
97             return &objectStore;
98     }
99
100     return nullptr;
101 }
102
103 const IDBObjectStoreInfo* IDBDatabaseInfo::infoForExistingObjectStore(uint64_t objectStoreIdentifier) const
104 {
105     return const_cast<IDBDatabaseInfo*>(this)->getInfoForExistingObjectStore(objectStoreIdentifier);
106 }
107
108 IDBObjectStoreInfo* IDBDatabaseInfo::infoForExistingObjectStore(uint64_t objectStoreIdentifier)
109 {
110     return getInfoForExistingObjectStore(objectStoreIdentifier);
111 }
112
113 const IDBObjectStoreInfo* IDBDatabaseInfo::infoForExistingObjectStore(const String& name) const
114 {
115     return const_cast<IDBDatabaseInfo*>(this)->getInfoForExistingObjectStore(name);
116 }
117
118 IDBObjectStoreInfo* IDBDatabaseInfo::infoForExistingObjectStore(const String& name)
119 {
120     return getInfoForExistingObjectStore(name);
121 }
122
123 Vector<String> IDBDatabaseInfo::objectStoreNames() const
124 {
125     Vector<String> names;
126     names.reserveCapacity(m_objectStoreMap.size());
127     for (auto& objectStore : m_objectStoreMap.values())
128         names.uncheckedAppend(objectStore.name());
129
130     return names;
131 }
132
133 void IDBDatabaseInfo::deleteObjectStore(const String& objectStoreName)
134 {
135     auto* info = infoForExistingObjectStore(objectStoreName);
136     if (!info)
137         return;
138
139     m_objectStoreMap.remove(info->identifier());
140 }
141
142 void IDBDatabaseInfo::deleteObjectStore(uint64_t objectStoreIdentifier)
143 {
144     m_objectStoreMap.remove(objectStoreIdentifier);
145 }
146
147 #ifndef NDEBUG
148 String IDBDatabaseInfo::loggingString() const
149 {
150     String top = makeString("Database: ", m_name, " version ", String::number(m_version), "\n");
151     for (auto objectStore : m_objectStoreMap.values())
152         top.append(makeString(objectStore.loggingString(1), "\n"));
153
154     return top; 
155 }
156 #endif
157
158 } // namespace WebCore
159
160 #endif // ENABLE(INDEXED_DATABASE)