// FindWithName follows the rules for choosing a browsing context, // with the exception of sandboxing for iframes. The implementation // for arbitrarily choosing between two browsing contexts with the // same name is as follows: // // 1) The start browsing context, i.e. 'this' // 2) Descendants in insertion order // 3) The parent // 4) Siblings and their children, both in insertion order // 5) After this we iteratively follow the parent chain, repeating 3 // and 4 until // 6) If there is no parent, consider all other top level browsing // contexts and their children, both in insertion order // // See // https://html.spec.whatwg.org/multipage/browsers.html#the-rules-for-choosing-a-browsing-context-given-a-browsing-context-name BrowsingContext* BrowsingContext::FindWithName(const nsAString& aName) { BrowsingContext* found = nullptr; if (aName.IsEmpty()) { // You can't find a browsing context with an empty name. found = nullptr; } else if (BrowsingContext* special = FindWithSpecialName(aName)) { found = special; } else if (aName.LowerCaseEqualsLiteral("_blank")) { // Just return null. Caller must handle creating a new window with // a blank name. found = nullptr; } else if (BrowsingContext* child = FindWithNameInSubtree(aName, this)) { found = child; } else { BrowsingContext* current = this; do { Children* siblings; BrowsingContext* parent = current->mParent; if (!parent) { // We've reached the root of the tree, consider browsing // contexts in the same browsing context group. siblings = &mGroup->Toplevels(); } else if (parent->NameEquals(aName) && CanAccess(parent) && parent->IsActive()) { found = parent; break; } else { siblings = &parent->mChildren; } for (BrowsingContext* sibling : *siblings) { if (sibling == current) { continue; } if (BrowsingContext* relative = sibling->FindWithNameInSubtree(aName, this)) { found = relative; // Breaks the outer loop parent = nullptr; break; } } current = parent; } while (current); } // Helpers should perform access control checks, which means that we // only need to assert that we can access found. MOZ_DIAGNOSTIC_ASSERT(!found || CanAccess(found)); return found; }
BrowsingContext* BrowsingContext::FindWithSpecialName(const nsAString& aName) { // TODO(farre): Neither BrowsingContext nor nsDocShell checks if the // browsing context pointed to by a special name is active. Should // it be? See Bug 1527913. if (aName.LowerCaseEqualsLiteral("_self")) { return this; } if (aName.LowerCaseEqualsLiteral("_parent")) { return mParent && CanAccess(mParent.get()) ? mParent.get() : this; } if (aName.LowerCaseEqualsLiteral("_top")) { BrowsingContext* top = TopLevelBrowsingContext(); return CanAccess(top) ? top : nullptr; } return nullptr; }
BrowsingContext* BrowsingContext::FindChildWithName(const nsAString& aName) { if (aName.IsEmpty()) { // You can't find a browsing context with the empty name. return nullptr; } for (BrowsingContext* child : mChildren) { if (child->NameEquals(aName) && CanAccess(child) && child->IsActive()) { return child; } } return nullptr; }
HRESULT AbstractDeviceContent::GetObjectIDByPersistentID( ACCESS_SCOPE Scope, _In_ LPCWSTR wszPersistentID, _Out_ IPortableDevicePropVariantCollection* pObjectIDs) { HRESULT hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); CComCritSecLock<CComAutoCriticalSection> Lock(m_ChildrenCS); if (CanAccess(Scope)) { if (PersistentUniqueID.CompareNoCase(wszPersistentID) == 0) { PROPVARIANT pv = {0}; PropVariantInit(&pv); pv.vt = VT_LPWSTR; pv.pwszVal = ObjectID.GetBuffer(); hr = pObjectIDs->Add(&pv); CHECK_HR(hr, "Failed to add '%ws' to the list of object IDs", ObjectID); } else { DWORD dwIndex = 0; AbstractDeviceContent* pChild = NULL; while (FindNext(Scope, dwIndex, &pChild)) { hr = pChild->GetObjectIDByPersistentID(Scope, wszPersistentID, pObjectIDs); if (hr == S_OK || hr == E_ACCESSDENIED) { // Found the object or was denied access break; } else if (hr != HRESULT_FROM_WIN32(ERROR_NOT_FOUND)) { CHECK_HR(hr, "Failed to get object ID for child at index %d", dwIndex); } dwIndex++; } } } else { hr = E_ACCESSDENIED; } return hr; }
bool DOMStorage::CanUseStorage(nsIPrincipal& aSubjectPrincipal) { // This method is responsible for correct setting of mIsSessionOnly. if (!mozilla::Preferences::GetBool(kStorageEnabled)) { return false; } nsContentUtils::StorageAccess access = nsContentUtils::StorageAllowedForPrincipal(mPrincipal); if (access == nsContentUtils::StorageAccess::eDeny) { return false; } mIsSessionOnly = access <= nsContentUtils::StorageAccess::eSessionScoped; return CanAccess(&aSubjectPrincipal); }
HRESULT AbstractDeviceContent::GetObjectIDsByFormat( ACCESS_SCOPE Scope, REFGUID guidFormat, const DWORD dwDepth, _Inout_ IPortableDevicePropVariantCollection* pObjectIDs) { HRESULT hr = S_OK; CComCritSecLock<CComAutoCriticalSection> Lock(m_ChildrenCS); if (CanAccess(Scope)) { DWORD dwIndex = 0; AbstractDeviceContent* pChild = NULL; if (Format == guidFormat || guidFormat == WPD_OBJECT_FORMAT_ALL) { PROPVARIANT pv = {0}; PropVariantInit(&pv); pv.vt = VT_LPWSTR; pv.pwszVal = ObjectID.GetBuffer(); hr = pObjectIDs->Add(&pv); CHECK_HR(hr, "Failed to add '%ws' to the list of object IDs by format", ObjectID); } if (dwDepth > 0) { while ((hr == S_OK) && (FindNext(Scope, dwIndex, &pChild))) { hr = pChild->GetObjectIDsByFormat(Scope, guidFormat, dwDepth-1, pObjectIDs); CHECK_HR(hr, "Failed to get object IDs by format for child at index %d", dwIndex); dwIndex++; } } } else { hr = E_ACCESSDENIED; } return hr; }
HRESULT AbstractDeviceContent::GetContent( ACCESS_SCOPE Scope, _In_ LPCWSTR wszObjectID, _Out_ AbstractDeviceContent** ppContent) { HRESULT hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); CComCritSecLock<CComAutoCriticalSection> Lock(m_ChildrenCS); if (CanAccess(Scope)) { if (ObjectID.CompareNoCase(wszObjectID) == 0) { hr = S_OK; *ppContent = this; } else { DWORD dwIndex = 0; AbstractDeviceContent* pChild = NULL; while (FindNext(Scope, dwIndex, &pChild)) { hr = pChild->GetContent(Scope, wszObjectID, ppContent); if (hr == S_OK || hr == E_ACCESSDENIED) { break; } dwIndex++; } } } else { hr = E_ACCESSDENIED; CHECK_HR(hr, "GetContent: '%ws' was found but falls outside scope", wszObjectID); } return hr; }