Attachment #722755: Named Sandboxed Navigation fix to nsDocShell for bug #838692

View | Details | Raw Unified | Return to bug 838692
Collapse All | Expand All

(-)a/docshell/base/nsDocShell.cpp (-20 / +30 lines)
Line     Link Here 
 Lines 3166-3189   nsDocShell::FindItemWithName(const PRUni Link Here 
3166
    NS_ENSURE_ARG_POINTER(_retval);
3166
    NS_ENSURE_ARG_POINTER(_retval);
3167
3167
3168
    // If we don't find one, we return NS_OK and a null result
3168
    // If we don't find one, we return NS_OK and a null result
3169
    *_retval = nullptr;
3169
    *_retval = nullptr;
3170
3170
3171
    if (!*aName)
3171
    if (!*aName)
3172
        return NS_OK;
3172
        return NS_OK;
3173
3173
3174
    if (!aRequestor)
3174
    if (aRequestor) {
3175
    {
3175
        // We are being called as part of the recursive search just hand
3176
        nsCOMPtr<nsIDocShellTreeItem> foundItem;
3176
        // straight off to the search by actual name function.
3177
        return DoFindItemWithName(aName, aRequestor, aOriginalRequestor,
3178
                                  _retval);
3179
    } else {
3177
3180
3178
        // This is the entry point into the target-finding algorithm.  Check
3181
        // This is the entry point into the target-finding algorithm.  Check
3179
        // for special names.  This should only be done once, hence the check
3182
        // for special names.  This should only be done once, hence the check
3180
        // for a null aRequestor.
3183
        // for a null aRequestor.
3181
3184
3185
        nsCOMPtr<nsIDocShellTreeItem> foundItem;
3182
        nsDependentString name(aName);
3186
        nsDependentString name(aName);
3183
        if (name.LowerCaseEqualsLiteral("_self")) {
3187
        if (name.LowerCaseEqualsLiteral("_self")) {
3184
            foundItem = this;
3188
            foundItem = this;
3185
        }
3189
        }
3186
        else if (name.LowerCaseEqualsLiteral("_blank"))
3190
        else if (name.LowerCaseEqualsLiteral("_blank"))
3187
        {
3191
        {
3188
            // Just return null.  Caller must handle creating a new window with
3192
            // Just return null.  Caller must handle creating a new window with
3189
            // a blank name himself.
3193
            // a blank name himself.
 Lines 3222-3247   nsDocShell::FindItemWithName(const PRUni Link Here 
3222
                // Note: _content should always exist.  If we don't have one
3226
                // Note: _content should always exist.  If we don't have one
3223
                // hanging off the treeowner, just create a named window....
3227
                // hanging off the treeowner, just create a named window....
3224
                // so don't return here, in case we did that and can now find
3228
                // so don't return here, in case we did that and can now find
3225
                // it.                
3229
                // it.                
3226
                // XXXbz should we be using |root| instead of creating
3230
                // XXXbz should we be using |root| instead of creating
3227
                // a new window?
3231
                // a new window?
3228
            }
3232
            }
3229
#endif
3233
#endif
3234
        } else {
3235
            // Do the search for item by an actual name.
3236
            DoFindItemWithName(aName, aRequestor, aOriginalRequestor,
3237
                               getter_AddRefs(foundItem));
3230
        }
3238
        }
3231
3239
3232
        if (foundItem && !CanAccessItem(foundItem, aOriginalRequestor)) {
3240
        if (foundItem && !CanAccessItem(foundItem, aOriginalRequestor)) {
3233
            foundItem = nullptr;
3241
            foundItem = nullptr;
3234
        }
3242
        }
3235
3243
3244
        // DoFindItemWithName only returns active items and we don't check if
3245
        // the item is active for the special cases.
3236
        if (foundItem) {
3246
        if (foundItem) {
3237
            // We return foundItem here even if it's not an active
3238
            // item since all the names we've dealt with so far are
3239
            // special cases that we won't bother looking for further.
3240
3247
3241
            // If our document is sandboxed, we need to do some extra checks.
3248
            // If our document is sandboxed, we need to do some extra checks.
3242
            uint32_t sandboxFlags = 0;
3249
            uint32_t sandboxFlags = 0;
3243
3250
3244
            nsCOMPtr<nsIDocument> doc = do_GetInterface(aOriginalRequestor);
3251
            nsCOMPtr<nsIDocument> doc = do_GetInterface(aOriginalRequestor);
3245
3252
3246
            if (doc) {
3253
            if (doc) {
3247
                sandboxFlags = doc->GetSandboxFlags();
3254
                sandboxFlags = doc->GetSandboxFlags();
 Lines 3252-3279   nsDocShell::FindItemWithName(const PRUni Link Here 
3252
                GetSameTypeRootTreeItem(getter_AddRefs(root));
3259
                GetSameTypeRootTreeItem(getter_AddRefs(root));
3253
3260
3254
                // Is the found item not a top level browsing context and not ourself ?
3261
                // Is the found item not a top level browsing context and not ourself ?
3255
                nsCOMPtr<nsIDocShellTreeItem> selfAsItem = static_cast<nsIDocShellTreeItem *>(this);
3262
                nsCOMPtr<nsIDocShellTreeItem> selfAsItem = static_cast<nsIDocShellTreeItem *>(this);
3256
                if (foundItem != root && foundItem != selfAsItem) {
3263
                if (foundItem != root && foundItem != selfAsItem) {
3257
                    // Are we an ancestor of the foundItem ?
3264
                    // Are we an ancestor of the foundItem ?
3258
                    bool isAncestor = false;
3265
                    bool isAncestor = false;
3259
3266
3260
                    nsCOMPtr<nsIDocShellTreeItem> parentAsItem;
3267
                    nsIDocShellTreeItem* tmp;
3261
                    GetSameTypeParent(getter_AddRefs(parentAsItem));
3268
                    foundItem->GetSameTypeParent(&tmp);
3262
3269
                    nsCOMPtr<nsIDocShellTreeItem> parentAsItem = dont_AddRef(tmp);
3263
                    while (parentAsItem) {
3270
                    while (parentAsItem) {
3264
                        nsCOMPtr<nsIDocShellTreeItem> tmp;
3271
                        if (parentAsItem == selfAsItem) {
3265
                        parentAsItem->GetParent(getter_AddRefs(tmp));
3266
3267
                        if (tmp && tmp == selfAsItem) {
3268
                            isAncestor = true;
3272
                            isAncestor = true;
3269
                            break;
3273
                            break;
3270
                        }
3274
                        }
3271
                        parentAsItem = tmp;
3275
                        parentAsItem->GetSameTypeParent(&tmp);
3276
                        parentAsItem = dont_AddRef(tmp);
3272
                    }
3277
                    }
3273
3278
3274
                    if (!isAncestor) {
3279
                    if (!isAncestor) {
3275
                        // No, we are not an ancestor and our document is
3280
                        // No, we are not an ancestor and our document is
3276
                        // sandboxed, we can't allow this.
3281
                        // sandboxed, we can't allow this.
3277
                        foundItem = nullptr;
3282
                        foundItem = nullptr;
3278
                    }
3283
                    }
3279
                } else {
3284
                } else {
 Lines 3291-3312   nsDocShell::FindItemWithName(const PRUni Link Here 
3291
                            break;
3296
                            break;
3292
                        }
3297
                        }
3293
                        tmp->GetParent(getter_AddRefs(tmp));
3298
                        tmp->GetParent(getter_AddRefs(tmp));
3294
                    }
3299
                    }
3295
                }
3300
                }
3296
            }
3301
            }
3297
3302
3298
            foundItem.swap(*_retval);
3303
            foundItem.swap(*_retval);
3299
            return NS_OK;
3304
        }
3300
        }
3305
        return NS_OK;
3301
    }
3306
    }
3302
3307
}
3303
    // Keep looking
3308
3304
        
3309
nsresult
3310
nsDocShell::DoFindItemWithName(const PRUnichar * aName,
3311
                             nsISupports * aRequestor,
3312
                             nsIDocShellTreeItem * aOriginalRequestor,
3313
                             nsIDocShellTreeItem ** _retval)
3314
{
3305
    // First we check our name.
3315
    // First we check our name.
3306
    if (mName.Equals(aName) && ItemIsActive(this) &&
3316
    if (mName.Equals(aName) && ItemIsActive(this) &&
3307
        CanAccessItem(this, aOriginalRequestor)) {
3317
        CanAccessItem(this, aOriginalRequestor)) {
3308
        NS_ADDREF(*_retval = this);
3318
        NS_ADDREF(*_retval = this);
3309
        return NS_OK;
3319
        return NS_OK;
3310
    }
3320
    }
3311
3321
3312
    // This QI may fail, but the places where we want to compare, comparing
3322
    // This QI may fail, but the places where we want to compare, comparing
(-)a/docshell/base/nsDocShell.h (+7 lines)
Line     Link Here 
 Lines 864-879   protected: Link Here 
864
864
865
private:
865
private:
866
    nsCOMPtr<nsIAtom> mForcedCharset;
866
    nsCOMPtr<nsIAtom> mForcedCharset;
867
    nsCOMPtr<nsIAtom> mParentCharset;
867
    nsCOMPtr<nsIAtom> mParentCharset;
868
    nsTObserverArray<nsWeakPtr> mPrivacyObservers;
868
    nsTObserverArray<nsWeakPtr> mPrivacyObservers;
869
    int32_t           mParentCharsetSource;
869
    int32_t           mParentCharsetSource;
870
    nsCString         mOriginalUriString;
870
    nsCString         mOriginalUriString;
871
871
872
    // Separate function to do the actual name (i.e. not _top, _self etc.)
873
    // searching for FindItemWithName.
874
    nsresult DoFindItemWithName(const PRUnichar * aName,
875
                                 nsISupports * aRequestor,
876
                                 nsIDocShellTreeItem * aOriginalRequestor,
877
                                 nsIDocShellTreeItem ** _retval);
878
872
#ifdef DEBUG
879
#ifdef DEBUG
873
    // We're counting the number of |nsDocShells| to help find leaks
880
    // We're counting the number of |nsDocShells| to help find leaks
874
    static unsigned long gNumberOfDocShells;
881
    static unsigned long gNumberOfDocShells;
875
#endif /* DEBUG */
882
#endif /* DEBUG */
876
883
877
public:
884
public:
878
    class InterfaceRequestorProxy : public nsIInterfaceRequestor {
885
    class InterfaceRequestorProxy : public nsIInterfaceRequestor {
879
    public:
886
    public:

Return to bug 838692