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.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
michael@0 | 2 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | #include "nsXULTemplateQueryProcessorRDF.h" |
michael@0 | 7 | #include "nsXULTemplateResultRDF.h" |
michael@0 | 8 | #include "nsRDFBinding.h" |
michael@0 | 9 | |
michael@0 | 10 | #ifdef DEBUG |
michael@0 | 11 | #include "nsXULContentUtils.h" |
michael@0 | 12 | #endif |
michael@0 | 13 | |
michael@0 | 14 | RDFBindingSet::~RDFBindingSet() |
michael@0 | 15 | { |
michael@0 | 16 | while (mFirst) { |
michael@0 | 17 | RDFBinding* doomed = mFirst; |
michael@0 | 18 | mFirst = mFirst->mNext; |
michael@0 | 19 | delete doomed; |
michael@0 | 20 | } |
michael@0 | 21 | |
michael@0 | 22 | MOZ_COUNT_DTOR(RDFBindingSet); |
michael@0 | 23 | } |
michael@0 | 24 | |
michael@0 | 25 | nsresult |
michael@0 | 26 | RDFBindingSet::AddBinding(nsIAtom* aVar, nsIAtom* aRef, nsIRDFResource* aPredicate) |
michael@0 | 27 | { |
michael@0 | 28 | RDFBinding* newbinding = new RDFBinding(aRef, aPredicate, aVar); |
michael@0 | 29 | if (! newbinding) |
michael@0 | 30 | return NS_ERROR_OUT_OF_MEMORY; |
michael@0 | 31 | |
michael@0 | 32 | if (mFirst) { |
michael@0 | 33 | RDFBinding* binding = mFirst; |
michael@0 | 34 | |
michael@0 | 35 | while (binding) { |
michael@0 | 36 | // the binding is dependant on the calculation of a previous binding |
michael@0 | 37 | if (binding->mSubjectVariable == aVar) |
michael@0 | 38 | newbinding->mHasDependency = true; |
michael@0 | 39 | |
michael@0 | 40 | // if the target variable is already used in a binding, ignore it |
michael@0 | 41 | // since it won't be useful for anything |
michael@0 | 42 | if (binding->mTargetVariable == aVar) { |
michael@0 | 43 | delete newbinding; |
michael@0 | 44 | return NS_OK; |
michael@0 | 45 | } |
michael@0 | 46 | |
michael@0 | 47 | // add the binding at the end of the list |
michael@0 | 48 | if (! binding->mNext) { |
michael@0 | 49 | binding->mNext = newbinding; |
michael@0 | 50 | break; |
michael@0 | 51 | } |
michael@0 | 52 | |
michael@0 | 53 | binding = binding->mNext; |
michael@0 | 54 | } |
michael@0 | 55 | } |
michael@0 | 56 | else { |
michael@0 | 57 | mFirst = newbinding; |
michael@0 | 58 | } |
michael@0 | 59 | |
michael@0 | 60 | mCount++; |
michael@0 | 61 | |
michael@0 | 62 | return NS_OK; |
michael@0 | 63 | } |
michael@0 | 64 | |
michael@0 | 65 | bool |
michael@0 | 66 | RDFBindingSet::SyncAssignments(nsIRDFResource* aSubject, |
michael@0 | 67 | nsIRDFResource* aPredicate, |
michael@0 | 68 | nsIRDFNode* aTarget, |
michael@0 | 69 | nsIAtom* aMemberVariable, |
michael@0 | 70 | nsXULTemplateResultRDF* aResult, |
michael@0 | 71 | nsBindingValues& aBindingValues) |
michael@0 | 72 | { |
michael@0 | 73 | NS_ASSERTION(aBindingValues.GetBindingSet() == this, |
michael@0 | 74 | "nsBindingValues not for this RDFBindingSet"); |
michael@0 | 75 | NS_PRECONDITION(aResult, "Must have result"); |
michael@0 | 76 | |
michael@0 | 77 | bool needSync = false; |
michael@0 | 78 | nsCOMPtr<nsIRDFNode>* valuesArray = aBindingValues.ValuesArray(); |
michael@0 | 79 | if (!valuesArray) |
michael@0 | 80 | return false; |
michael@0 | 81 | |
michael@0 | 82 | RDFBinding* binding = mFirst; |
michael@0 | 83 | int32_t count = 0; |
michael@0 | 84 | |
michael@0 | 85 | // QI for proper comparisons just to be safe |
michael@0 | 86 | nsCOMPtr<nsIRDFNode> subjectnode = do_QueryInterface(aSubject); |
michael@0 | 87 | |
michael@0 | 88 | // iterate through the bindings looking for ones that would match the RDF |
michael@0 | 89 | // nodes that were involved in a change |
michael@0 | 90 | nsCOMPtr<nsIRDFNode> value; |
michael@0 | 91 | while (binding) { |
michael@0 | 92 | if (aPredicate == binding->mPredicate) { |
michael@0 | 93 | // if the source of the binding is the member variable, optimize |
michael@0 | 94 | if (binding->mSubjectVariable == aMemberVariable) { |
michael@0 | 95 | valuesArray[count] = aTarget; |
michael@0 | 96 | needSync = true; |
michael@0 | 97 | } |
michael@0 | 98 | else { |
michael@0 | 99 | aResult->GetAssignment(binding->mSubjectVariable, getter_AddRefs(value)); |
michael@0 | 100 | if (value == subjectnode) { |
michael@0 | 101 | valuesArray[count] = aTarget; |
michael@0 | 102 | needSync = true; |
michael@0 | 103 | } |
michael@0 | 104 | } |
michael@0 | 105 | } |
michael@0 | 106 | |
michael@0 | 107 | binding = binding->mNext; |
michael@0 | 108 | count++; |
michael@0 | 109 | } |
michael@0 | 110 | |
michael@0 | 111 | return needSync; |
michael@0 | 112 | } |
michael@0 | 113 | |
michael@0 | 114 | void |
michael@0 | 115 | RDFBindingSet::AddDependencies(nsIRDFResource* aSubject, |
michael@0 | 116 | nsXULTemplateResultRDF* aResult) |
michael@0 | 117 | { |
michael@0 | 118 | NS_PRECONDITION(aResult, "Must have result"); |
michael@0 | 119 | |
michael@0 | 120 | // iterate through the bindings and add binding dependencies to the |
michael@0 | 121 | // processor |
michael@0 | 122 | |
michael@0 | 123 | nsXULTemplateQueryProcessorRDF* processor = aResult->GetProcessor(); |
michael@0 | 124 | if (! processor) |
michael@0 | 125 | return; |
michael@0 | 126 | |
michael@0 | 127 | nsCOMPtr<nsIRDFNode> value; |
michael@0 | 128 | |
michael@0 | 129 | RDFBinding* binding = mFirst; |
michael@0 | 130 | while (binding) { |
michael@0 | 131 | aResult->GetAssignment(binding->mSubjectVariable, getter_AddRefs(value)); |
michael@0 | 132 | |
michael@0 | 133 | nsCOMPtr<nsIRDFResource> valueres = do_QueryInterface(value); |
michael@0 | 134 | if (valueres) |
michael@0 | 135 | processor->AddBindingDependency(aResult, valueres); |
michael@0 | 136 | |
michael@0 | 137 | binding = binding->mNext; |
michael@0 | 138 | } |
michael@0 | 139 | } |
michael@0 | 140 | |
michael@0 | 141 | void |
michael@0 | 142 | RDFBindingSet::RemoveDependencies(nsIRDFResource* aSubject, |
michael@0 | 143 | nsXULTemplateResultRDF* aResult) |
michael@0 | 144 | { |
michael@0 | 145 | NS_PRECONDITION(aResult, "Must have result"); |
michael@0 | 146 | |
michael@0 | 147 | // iterate through the bindings and remove binding dependencies from the |
michael@0 | 148 | // processor |
michael@0 | 149 | |
michael@0 | 150 | nsXULTemplateQueryProcessorRDF* processor = aResult->GetProcessor(); |
michael@0 | 151 | if (! processor) |
michael@0 | 152 | return; |
michael@0 | 153 | |
michael@0 | 154 | nsCOMPtr<nsIRDFNode> value; |
michael@0 | 155 | |
michael@0 | 156 | RDFBinding* binding = mFirst; |
michael@0 | 157 | while (binding) { |
michael@0 | 158 | aResult->GetAssignment(binding->mSubjectVariable, getter_AddRefs(value)); |
michael@0 | 159 | |
michael@0 | 160 | nsCOMPtr<nsIRDFResource> valueres = do_QueryInterface(value); |
michael@0 | 161 | if (valueres) |
michael@0 | 162 | processor->RemoveBindingDependency(aResult, valueres); |
michael@0 | 163 | |
michael@0 | 164 | binding = binding->mNext; |
michael@0 | 165 | } |
michael@0 | 166 | } |
michael@0 | 167 | |
michael@0 | 168 | int32_t |
michael@0 | 169 | RDFBindingSet::LookupTargetIndex(nsIAtom* aTargetVariable, RDFBinding** aBinding) |
michael@0 | 170 | { |
michael@0 | 171 | int32_t idx = 0; |
michael@0 | 172 | RDFBinding* binding = mFirst; |
michael@0 | 173 | |
michael@0 | 174 | while (binding) { |
michael@0 | 175 | if (binding->mTargetVariable == aTargetVariable) { |
michael@0 | 176 | *aBinding = binding; |
michael@0 | 177 | return idx; |
michael@0 | 178 | } |
michael@0 | 179 | idx++; |
michael@0 | 180 | binding = binding->mNext; |
michael@0 | 181 | } |
michael@0 | 182 | |
michael@0 | 183 | return -1; |
michael@0 | 184 | } |
michael@0 | 185 | |
michael@0 | 186 | nsBindingValues::~nsBindingValues() |
michael@0 | 187 | { |
michael@0 | 188 | ClearBindingSet(); |
michael@0 | 189 | MOZ_COUNT_DTOR(nsBindingValues); |
michael@0 | 190 | } |
michael@0 | 191 | |
michael@0 | 192 | void |
michael@0 | 193 | nsBindingValues::ClearBindingSet() |
michael@0 | 194 | { |
michael@0 | 195 | if (mBindings && mValues) { |
michael@0 | 196 | delete [] mValues; |
michael@0 | 197 | mValues = nullptr; |
michael@0 | 198 | } |
michael@0 | 199 | |
michael@0 | 200 | mBindings = nullptr; |
michael@0 | 201 | } |
michael@0 | 202 | |
michael@0 | 203 | nsresult |
michael@0 | 204 | nsBindingValues::SetBindingSet(RDFBindingSet* aBindings) |
michael@0 | 205 | { |
michael@0 | 206 | ClearBindingSet(); |
michael@0 | 207 | |
michael@0 | 208 | int32_t count = aBindings->Count(); |
michael@0 | 209 | if (count) { |
michael@0 | 210 | mValues = new nsCOMPtr<nsIRDFNode>[count]; |
michael@0 | 211 | if (!mValues) |
michael@0 | 212 | return NS_ERROR_OUT_OF_MEMORY; |
michael@0 | 213 | |
michael@0 | 214 | mBindings = aBindings; |
michael@0 | 215 | } |
michael@0 | 216 | else { |
michael@0 | 217 | mValues = nullptr; |
michael@0 | 218 | } |
michael@0 | 219 | |
michael@0 | 220 | return NS_OK; |
michael@0 | 221 | } |
michael@0 | 222 | |
michael@0 | 223 | void |
michael@0 | 224 | nsBindingValues::GetAssignmentFor(nsXULTemplateResultRDF* aResult, |
michael@0 | 225 | nsIAtom* aVar, |
michael@0 | 226 | nsIRDFNode** aValue) |
michael@0 | 227 | { |
michael@0 | 228 | *aValue = nullptr; |
michael@0 | 229 | |
michael@0 | 230 | // assignments are calculated lazily when asked for. The only issue is |
michael@0 | 231 | // when a binding has no value in the RDF graph, it will be checked again |
michael@0 | 232 | // every time. |
michael@0 | 233 | |
michael@0 | 234 | if (mBindings && mValues) { |
michael@0 | 235 | RDFBinding* binding; |
michael@0 | 236 | int32_t idx = mBindings->LookupTargetIndex(aVar, &binding); |
michael@0 | 237 | if (idx >= 0) { |
michael@0 | 238 | *aValue = mValues[idx]; |
michael@0 | 239 | if (*aValue) { |
michael@0 | 240 | NS_ADDREF(*aValue); |
michael@0 | 241 | } |
michael@0 | 242 | else { |
michael@0 | 243 | nsXULTemplateQueryProcessorRDF* processor = aResult->GetProcessor(); |
michael@0 | 244 | if (! processor) |
michael@0 | 245 | return; |
michael@0 | 246 | |
michael@0 | 247 | nsIRDFDataSource* ds = processor->GetDataSource(); |
michael@0 | 248 | if (! ds) |
michael@0 | 249 | return; |
michael@0 | 250 | |
michael@0 | 251 | nsCOMPtr<nsIRDFNode> subjectValue; |
michael@0 | 252 | aResult->GetAssignment(binding->mSubjectVariable, |
michael@0 | 253 | getter_AddRefs(subjectValue)); |
michael@0 | 254 | if (subjectValue) { |
michael@0 | 255 | nsCOMPtr<nsIRDFResource> subject = do_QueryInterface(subjectValue); |
michael@0 | 256 | ds->GetTarget(subject, binding->mPredicate, true, aValue); |
michael@0 | 257 | if (*aValue) |
michael@0 | 258 | mValues[idx] = *aValue; |
michael@0 | 259 | } |
michael@0 | 260 | } |
michael@0 | 261 | } |
michael@0 | 262 | } |
michael@0 | 263 | } |
michael@0 | 264 | |
michael@0 | 265 | void |
michael@0 | 266 | nsBindingValues::RemoveDependencies(nsIRDFResource* aSubject, |
michael@0 | 267 | nsXULTemplateResultRDF* aResult) |
michael@0 | 268 | { |
michael@0 | 269 | if (mBindings) |
michael@0 | 270 | mBindings->RemoveDependencies(aSubject, aResult); |
michael@0 | 271 | } |