Attachment #713440: 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 / +28 lines)
Line     Link Here 
 Lines 3099-3122   nsDocShell::FindItemWithName(const PRUni Link Here 
3099
    NS_ENSURE_ARG_POINTER(_retval);
3099
    NS_ENSURE_ARG_POINTER(_retval);
3100
3100
3101
    // If we don't find one, we return NS_OK and a null result
3101
    // If we don't find one, we return NS_OK and a null result
3102
    *_retval = nullptr;
3102
    *_retval = nullptr;
3103
3103
3104
    if (!*aName)
3104
    if (!*aName)
3105
        return NS_OK;
3105
        return NS_OK;
3106
3106
3107
    if (!aRequestor)
3107
    if (aRequestor) {
3108
    {
3108
        // We are being called as part of the recursive search just hand
3109
        nsCOMPtr<nsIDocShellTreeItem> foundItem;
3109
        // straight off to the search by actual name function.
3110
        return DoFindItemWithName(aName, aRequestor, aOriginalRequestor,
3111
                                  _retval);
3112
    } else {
3110
3113
3111
        // This is the entry point into the target-finding algorithm.  Check
3114
        // This is the entry point into the target-finding algorithm.  Check
3112
        // for special names.  This should only be done once, hence the check
3115
        // for special names.  This should only be done once, hence the check
3113
        // for a null aRequestor.
3116
        // for a null aRequestor.
3114
3117
3118
        nsCOMPtr<nsIDocShellTreeItem> foundItem;
3115
        nsDependentString name(aName);
3119
        nsDependentString name(aName);
3116
        if (name.LowerCaseEqualsLiteral("_self")) {
3120
        if (name.LowerCaseEqualsLiteral("_self")) {
3117
            foundItem = this;
3121
            foundItem = this;
3118
        }
3122
        }
3119
        else if (name.LowerCaseEqualsLiteral("_blank"))
3123
        else if (name.LowerCaseEqualsLiteral("_blank"))
3120
        {
3124
        {
3121
            // Just return null.  Caller must handle creating a new window with
3125
            // Just return null.  Caller must handle creating a new window with
3122
            // a blank name himself.
3126
            // a blank name himself.
 Lines 3155-3180   nsDocShell::FindItemWithName(const PRUni Link Here 
3155
                // Note: _content should always exist.  If we don't have one
3159
                // Note: _content should always exist.  If we don't have one
3156
                // hanging off the treeowner, just create a named window....
3160
                // hanging off the treeowner, just create a named window....
3157
                // so don't return here, in case we did that and can now find
3161
                // so don't return here, in case we did that and can now find
3158
                // it.                
3162
                // it.                
3159
                // XXXbz should we be using |root| instead of creating
3163
                // XXXbz should we be using |root| instead of creating
3160
                // a new window?
3164
                // a new window?
3161
            }
3165
            }
3162
#endif
3166
#endif
3167
        } else {
3168
            // Do the search for item by an actual name.
3169
            DoFindItemWithName(aName, aRequestor, aOriginalRequestor,
3170
                               getter_AddRefs(foundItem));
3163
        }
3171
        }
3164
3172
3165
        if (foundItem && !CanAccessItem(foundItem, aOriginalRequestor)) {
3173
        if (foundItem && !CanAccessItem(foundItem, aOriginalRequestor)) {
3166
            foundItem = nullptr;
3174
            foundItem = nullptr;
3167
        }
3175
        }
3168
3176
3177
        // DoFindItemWithName only returns active items and we don't check if
3178
        // the item is active for the special cases.
3169
        if (foundItem) {
3179
        if (foundItem) {
3170
            // We return foundItem here even if it's not an active
3171
            // item since all the names we've dealt with so far are
3172
            // special cases that we won't bother looking for further.
3173
3180
3174
            // If our document is sandboxed, we need to do some extra checks.
3181
            // If our document is sandboxed, we need to do some extra checks.
3175
            uint32_t sandboxFlags = 0;
3182
            uint32_t sandboxFlags = 0;
3176
3183
3177
            nsCOMPtr<nsIDocument> doc = do_GetInterface(aOriginalRequestor);
3184
            nsCOMPtr<nsIDocument> doc = do_GetInterface(aOriginalRequestor);
3178
3185
3179
            if (doc) {
3186
            if (doc) {
3180
                sandboxFlags = doc->GetSandboxFlags();
3187
                sandboxFlags = doc->GetSandboxFlags();
 Lines 3186-3212   nsDocShell::FindItemWithName(const PRUni Link Here 
3186
3193
3187
                // Is the found item not a top level browsing context and not ourself ?
3194
                // Is the found item not a top level browsing context and not ourself ?
3188
                nsCOMPtr<nsIDocShellTreeItem> selfAsItem = static_cast<nsIDocShellTreeItem *>(this);
3195
                nsCOMPtr<nsIDocShellTreeItem> selfAsItem = static_cast<nsIDocShellTreeItem *>(this);
3189
                if (foundItem != root && foundItem != selfAsItem) {
3196
                if (foundItem != root && foundItem != selfAsItem) {
3190
                    // Are we an ancestor of the foundItem ?
3197
                    // Are we an ancestor of the foundItem ?
3191
                    bool isAncestor = false;
3198
                    bool isAncestor = false;
3192
3199
3193
                    nsCOMPtr<nsIDocShellTreeItem> parentAsItem;
3200
                    nsCOMPtr<nsIDocShellTreeItem> parentAsItem;
3194
                    GetSameTypeParent(getter_AddRefs(parentAsItem));
3201
                    foundItem->GetSameTypeParent(getter_AddRefs(parentAsItem));
3195
3202
3196
                    while (parentAsItem) {
3203
                    while (parentAsItem) {
3197
                        nsCOMPtr<nsIDocShellTreeItem> tmp;
3204
                        if (parentAsItem == selfAsItem) {
3198
                        parentAsItem->GetParent(getter_AddRefs(tmp));
3199
3200
                        if (tmp && tmp == selfAsItem) {
3201
                            isAncestor = true;
3205
                            isAncestor = true;
3202
                            break;
3206
                            break;
3203
                        }
3207
                        }
3204
                        parentAsItem = tmp;
3208
                        parentAsItem->GetSameTypeParent(getter_AddRefs(parentAsItem));
3205
                    }
3209
                    }
3206
3210
3207
                    if (!isAncestor) {
3211
                    if (!isAncestor) {
3208
                        // No, we are not an ancestor and our document is
3212
                        // No, we are not an ancestor and our document is
3209
                        // sandboxed, we can't allow this.
3213
                        // sandboxed, we can't allow this.
3210
                        foundItem = nullptr;
3214
                        foundItem = nullptr;
3211
                    }
3215
                    }
3212
                } else {
3216
                } else {
 Lines 3224-3248   nsDocShell::FindItemWithName(const PRUni Link Here 
3224
                            break;
3228
                            break;
3225
                        }
3229
                        }
3226
                        tmp->GetParent(getter_AddRefs(tmp));
3230
                        tmp->GetParent(getter_AddRefs(tmp));
3227
                    }
3231
                    }
3228
                }
3232
                }
3229
            }
3233
            }
3230
3234
3231
            foundItem.swap(*_retval);
3235
            foundItem.swap(*_retval);
3232
            return NS_OK;
3236
        }
3233
        }
3237
        return NS_OK;
3234
    }
3238
    }
3235
3239
}
3236
    // Keep looking
3240
3237
        
3241
nsresult
3242
nsDocShell::DoFindItemWithName(const PRUnichar * aName,
3243
                             nsISupports * aRequestor,
3244
                             nsIDocShellTreeItem * aOriginalRequestor,
3245
                             nsIDocShellTreeItem ** _retval)
3246
{
3238
    // First we check our name.
3247
    // First we check our name.
3239
    if (mName.Equals(aName) && ItemIsActive(this) &&
3248
    if (mName.Equals(aName) && ItemIsActive(this)) {
3240
        CanAccessItem(this, aOriginalRequestor)) {
3241
        NS_ADDREF(*_retval = this);
3249
        NS_ADDREF(*_retval = this);
3242
        return NS_OK;
3250
        return NS_OK;
3243
    }
3251
    }
3244
3252
3245
    // This QI may fail, but the places where we want to compare, comparing
3253
    // This QI may fail, but the places where we want to compare, comparing
3246
    // against nullptr serves the same purpose.
3254
    // against nullptr serves the same purpose.
3247
    nsCOMPtr<nsIDocShellTreeItem> reqAsTreeItem(do_QueryInterface(aRequestor));
3255
    nsCOMPtr<nsIDocShellTreeItem> reqAsTreeItem(do_QueryInterface(aRequestor));
3248
3256
(-)a/docshell/base/nsDocShell.h (+7 lines)
Line     Link Here 
 Lines 868-883   protected: Link Here 
868
868
869
private:
869
private:
870
    nsCOMPtr<nsIAtom> mForcedCharset;
870
    nsCOMPtr<nsIAtom> mForcedCharset;
871
    nsCOMPtr<nsIAtom> mParentCharset;
871
    nsCOMPtr<nsIAtom> mParentCharset;
872
    nsTObserverArray<nsWeakPtr> mPrivacyObservers;
872
    nsTObserverArray<nsWeakPtr> mPrivacyObservers;
873
    int32_t           mParentCharsetSource;
873
    int32_t           mParentCharsetSource;
874
    nsCString         mOriginalUriString;
874
    nsCString         mOriginalUriString;
875
875
876
    // Separate function to do the actual name (i.e. not _top, _self etc.)
877
    // searching for FindItemWithName.
878
    nsresult DoFindItemWithName(const PRUnichar * aName,
879
                                 nsISupports * aRequestor,
880
                                 nsIDocShellTreeItem * aOriginalRequestor,
881
                                 nsIDocShellTreeItem ** _retval);
882
876
#ifdef DEBUG
883
#ifdef DEBUG
877
    // We're counting the number of |nsDocShells| to help find leaks
884
    // We're counting the number of |nsDocShells| to help find leaks
878
    static unsigned long gNumberOfDocShells;
885
    static unsigned long gNumberOfDocShells;
879
#endif /* DEBUG */
886
#endif /* DEBUG */
880
887
881
public:
888
public:
882
    class InterfaceRequestorProxy : public nsIInterfaceRequestor {
889
    class InterfaceRequestorProxy : public nsIInterfaceRequestor {
883
    public:
890
    public:

Return to bug 838692