Sat, 03 Jan 2015 20:18:00 +0100
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.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "nsArray.h"
7 #include "nsArrayEnumerator.h"
8 #include "nsIWeakReference.h"
9 #include "nsIWeakReferenceUtils.h"
10 #include "nsThreadUtils.h"
12 // used by IndexOf()
13 struct findIndexOfClosure
14 {
15 nsISupports *targetElement;
16 uint32_t startIndex;
17 uint32_t resultIndex;
18 };
20 static bool FindElementCallback(void* aElement, void* aClosure);
22 NS_INTERFACE_MAP_BEGIN(nsArray)
23 NS_INTERFACE_MAP_ENTRY(nsIArray)
24 NS_INTERFACE_MAP_ENTRY(nsIMutableArray)
25 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIMutableArray)
26 NS_INTERFACE_MAP_END
28 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsArrayCC)
29 NS_INTERFACE_MAP_ENTRY(nsIArray)
30 NS_INTERFACE_MAP_ENTRY(nsIMutableArray)
31 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIMutableArray)
32 NS_INTERFACE_MAP_END
34 nsArray::~nsArray()
35 {
36 Clear();
37 }
40 NS_IMPL_ADDREF(nsArray)
41 NS_IMPL_RELEASE(nsArray)
43 NS_IMPL_CYCLE_COLLECTION_CLASS(nsArrayCC)
45 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsArrayCC)
46 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsArrayCC)
48 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsArrayCC)
49 tmp->Clear();
50 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
51 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsArrayCC)
52 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mArray)
53 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
55 NS_IMETHODIMP
56 nsArray::GetLength(uint32_t* aLength)
57 {
58 *aLength = mArray.Count();
59 return NS_OK;
60 }
62 NS_IMETHODIMP
63 nsArray::QueryElementAt(uint32_t aIndex,
64 const nsIID& aIID,
65 void ** aResult)
66 {
67 nsISupports * obj = mArray.SafeObjectAt(aIndex);
68 if (!obj) return NS_ERROR_ILLEGAL_VALUE;
70 // no need to worry about a leak here, because SafeObjectAt()
71 // doesn't addref its result
72 return obj->QueryInterface(aIID, aResult);
73 }
75 NS_IMETHODIMP
76 nsArray::IndexOf(uint32_t aStartIndex, nsISupports* aElement,
77 uint32_t* aResult)
78 {
79 // optimize for the common case by forwarding to mArray
80 if (aStartIndex == 0) {
81 uint32_t idx = mArray.IndexOf(aElement);
82 if (idx == UINT32_MAX)
83 return NS_ERROR_FAILURE;
85 *aResult = idx;
86 return NS_OK;
87 }
89 findIndexOfClosure closure = { aElement, aStartIndex, 0 };
90 bool notFound = mArray.EnumerateForwards(FindElementCallback, &closure);
91 if (notFound)
92 return NS_ERROR_FAILURE;
94 *aResult = closure.resultIndex;
95 return NS_OK;
96 }
98 NS_IMETHODIMP
99 nsArray::Enumerate(nsISimpleEnumerator **aResult)
100 {
101 return NS_NewArrayEnumerator(aResult, static_cast<nsIArray*>(this));
102 }
104 // nsIMutableArray implementation
106 NS_IMETHODIMP
107 nsArray::AppendElement(nsISupports* aElement, bool aWeak)
108 {
109 bool result;
110 if (aWeak) {
111 nsCOMPtr<nsIWeakReference> elementRef = do_GetWeakReference(aElement);
112 NS_ASSERTION(elementRef, "AppendElement: Trying to use weak references on an object that doesn't support it");
113 if (!elementRef)
114 return NS_ERROR_FAILURE;
115 result = mArray.AppendObject(elementRef);
116 }
118 else {
119 // add the object directly
120 result = mArray.AppendObject(aElement);
121 }
122 return result ? NS_OK : NS_ERROR_FAILURE;
123 }
125 NS_IMETHODIMP
126 nsArray::RemoveElementAt(uint32_t aIndex)
127 {
128 bool result = mArray.RemoveObjectAt(aIndex);
129 return result ? NS_OK : NS_ERROR_FAILURE;
130 }
132 NS_IMETHODIMP
133 nsArray::InsertElementAt(nsISupports* aElement, uint32_t aIndex, bool aWeak)
134 {
135 nsCOMPtr<nsISupports> elementRef;
136 if (aWeak) {
137 elementRef = do_GetWeakReference(aElement);
138 NS_ASSERTION(elementRef, "InsertElementAt: Trying to use weak references on an object that doesn't support it");
139 if (!elementRef)
140 return NS_ERROR_FAILURE;
141 } else {
142 elementRef = aElement;
143 }
144 bool result = mArray.InsertObjectAt(elementRef, aIndex);
145 return result ? NS_OK : NS_ERROR_FAILURE;
146 }
148 NS_IMETHODIMP
149 nsArray::ReplaceElementAt(nsISupports* aElement, uint32_t aIndex, bool aWeak)
150 {
151 nsCOMPtr<nsISupports> elementRef;
152 if (aWeak) {
153 elementRef = do_GetWeakReference(aElement);
154 NS_ASSERTION(elementRef, "ReplaceElementAt: Trying to use weak references on an object that doesn't support it");
155 if (!elementRef)
156 return NS_ERROR_FAILURE;
157 } else {
158 elementRef = aElement;
159 }
160 bool result = mArray.ReplaceObjectAt(elementRef, aIndex);
161 return result ? NS_OK : NS_ERROR_FAILURE;
162 }
164 NS_IMETHODIMP
165 nsArray::Clear()
166 {
167 mArray.Clear();
168 return NS_OK;
169 }
171 //
172 // static helper routines
173 //
174 bool
175 FindElementCallback(void *aElement, void* aClosure)
176 {
177 findIndexOfClosure* closure =
178 static_cast<findIndexOfClosure*>(aClosure);
180 nsISupports* element =
181 static_cast<nsISupports*>(aElement);
183 // don't start searching until we're past the startIndex
184 if (closure->resultIndex >= closure->startIndex &&
185 element == closure->targetElement) {
186 return false; // stop! We found it
187 }
188 closure->resultIndex++;
190 return true;
191 }
193 nsresult
194 nsArray::XPCOMConstructor(nsISupports *aOuter, const nsIID& aIID, void **aResult)
195 {
196 if (aOuter)
197 return NS_ERROR_NO_AGGREGATION;
199 nsCOMPtr<nsIMutableArray> inst = Create();
200 return inst->QueryInterface(aIID, aResult);
201 }
203 already_AddRefed<nsIMutableArray>
204 nsArray::Create()
205 {
206 nsCOMPtr<nsIMutableArray> inst = NS_IsMainThread() ? new nsArrayCC : new nsArray;
207 return inst.forget();
208 }