import patches from thunderbird-2.0.0.24-28.el5_7.src.rpm, with following backed out due to broken build:

mozilla-573873-1.8.patch
mozilla-liveconnect-1.9.2.13.patch
mozilla-nsTArray.patch
This commit is contained in:
roytam1 2018-05-01 18:45:19 +08:00
parent 455fb87a48
commit ba7f53c261
177 changed files with 3289 additions and 1179 deletions

View File

@ -328,34 +328,34 @@ if [ -z "$MRE_HOME" ]; then
fi
##
## Set LD_LIBRARY_PATH
LD_LIBRARY_PATH=${MOZ_DIST_BIN}:${MOZ_DIST_BIN}/plugins:${MRE_HOME}${LD_LIBRARY_PATH+":$LD_LIBRARY_PATH"}
LD_LIBRARY_PATH=${MOZ_DIST_BIN}:${MOZ_DIST_BIN}/plugins:${MRE_HOME}${LD_LIBRARY_PATH:+":$LD_LIBRARY_PATH"}
if [ -n "$LD_LIBRARYN32_PATH" ]
then
LD_LIBRARYN32_PATH=${MOZ_DIST_BIN}:${MOZ_DIST_BIN}/plugins:${MRE_HOME}${LD_LIBRARYN32_PATH+":$LD_LIBRARYN32_PATH"}
LD_LIBRARYN32_PATH=${MOZ_DIST_BIN}:${MOZ_DIST_BIN}/plugins:${MRE_HOME}${LD_LIBRARYN32_PATH:+":$LD_LIBRARYN32_PATH"}
fi
if [ -n "$LD_LIBRARYN64_PATH" ]
then
LD_LIBRARYN64_PATH=${MOZ_DIST_BIN}:${MOZ_DIST_BIN}/plugins:${MRE_HOME}${LD_LIBRARYN64_PATH+":$LD_LIBRARYN64_PATH"}
LD_LIBRARYN64_PATH=${MOZ_DIST_BIN}:${MOZ_DIST_BIN}/plugins:${MRE_HOME}${LD_LIBRARYN64_PATH:+":$LD_LIBRARYN64_PATH"}
fi
if [ -n "$LD_LIBRARY_PATH_64" ]; then
LD_LIBRARY_PATH_64=${MOZ_DIST_BIN}:${MOZ_DIST_BIN}/plugins:${MRE_HOME}${LD_LIBRARY_PATH_64+":$LD_LIBRARY_PATH_64"}
LD_LIBRARY_PATH_64=${MOZ_DIST_BIN}:${MOZ_DIST_BIN}/plugins:${MRE_HOME}${LD_LIBRARY_PATH_64:+":$LD_LIBRARY_PATH_64"}
fi
#
#
## Set SHLIB_PATH for HPUX
SHLIB_PATH=${MOZ_DIST_BIN}:${MRE_HOME}${SHLIB_PATH+":$SHLIB_PATH"}
SHLIB_PATH=${MOZ_DIST_BIN}:${MRE_HOME}${SHLIB_PATH:+":$SHLIB_PATH"}
#
## Set LIBPATH for AIX
LIBPATH=${MOZ_DIST_BIN}:${MRE_HOME}${LIBPATH+":$LIBPATH"}
LIBPATH=${MOZ_DIST_BIN}:${MRE_HOME}${LIBPATH:+":$LIBPATH"}
#
## Set DYLD_LIBRARY_PATH for Mac OS X (Darwin)
DYLD_LIBRARY_PATH=${MOZ_DIST_BIN}:${MRE_HOME}${DYLD_LIBRARY_PATH+":$DYLD_LIBRARY_PATH"}
DYLD_LIBRARY_PATH=${MOZ_DIST_BIN}:${MRE_HOME}${DYLD_LIBRARY_PATH:+":$DYLD_LIBRARY_PATH"}
#
## Set LIBRARY_PATH for BeOS
LIBRARY_PATH=${MOZ_DIST_BIN}:${MOZ_DIST_BIN}/components:${MRE_HOME}${LIBRARY_PATH+":$LIBRARY_PATH"}
LIBRARY_PATH=${MOZ_DIST_BIN}:${MOZ_DIST_BIN}/components:${MRE_HOME}${LIBRARY_PATH:+":$LIBRARY_PATH"}
#
## Set ADDON_PATH for BeOS
ADDON_PATH=${MOZ_DIST_BIN}${ADDON_PATH+":$ADDON_PATH"}
ADDON_PATH=${MOZ_DIST_BIN}${ADDON_PATH:+":$ADDON_PATH"}
#
## Solaris Xserver(Xsun) tuning - use shared memory transport if available
if [ "$XSUNTRANSPORT" = "" ]

View File

@ -81,6 +81,7 @@ class nsIJSRuntimeService;
class nsIScriptGlobalObject;
struct JSRuntime;
class nsPIDOMWindow;
class nsPIDOMEventTarget;
#ifdef MOZ_XTF
class nsIXTFService;
#endif
@ -706,6 +707,9 @@ public:
~nsCxPusher() { Pop(); }
// Returns PR_FALSE if something erroneous happened.
PRBool Push(nsISupports *aCurrentTarget);
// If nothing has been pushed to stack, this works like Push.
// Otherwise if context will change, Pop and Push will be called.
PRBool RePush(nsISupports *aCurrentTarget);
void Pop();
private:

View File

@ -997,7 +997,7 @@ nsContentUtils::ReparentContentWrappersInScope(nsIScriptGlobalObject *aOldScope,
NS_ERROR("Weird things are happening in XPConnect");
return NS_ERROR_FAILURE;
}
return xpconnect18->ReparentScopeAwareWrappers(cx, oldScopeObj, newScopeObj);
return xpconnect18->MoveWrappers(cx, oldScopeObj, newScopeObj);
}
nsIDocShell *
@ -2395,6 +2395,47 @@ nsCxPusher::Push(nsISupports *aCurrentTarget)
return PR_TRUE;
}
PRBool
nsCxPusher::RePush(nsISupports *aCurrentTarget)
{
if (!mScx) {
return Push(aCurrentTarget);
}
if (aCurrentTarget) {
nsIScriptContext* scx = nsnull;
nsCOMPtr<nsIScriptGlobalObject> sgo;
nsCOMPtr<nsIContent> content(do_QueryInterface(aCurrentTarget));
if (content) {
nsCOMPtr<nsIDocument> ownerDoc = content->GetOwnerDoc();
if (ownerDoc) {
nsCOMPtr<nsIDocument_MOZILLA_1_8_BRANCH3> branch3doc =
do_QueryInterface(ownerDoc);
NS_ASSERTION(branch3doc,
"Document must implement nsIDocument_MOZILLA_1_8_BRANCH3!!!");
PRBool hasHadScriptObject = PR_TRUE;
sgo = branch3doc->GetScriptHandlingObject(hasHadScriptObject);
}
} else {
sgo = do_QueryInterface(aCurrentTarget);
}
if (sgo) {
scx = sgo->GetContext();
// If we have the same script context and native context is still
// alive, no need to Pop/Push.
if (scx && scx == mScx &&
scx->GetNativeContext()) {
return PR_TRUE;
}
}
}
Pop();
return Push(aCurrentTarget);
}
void
nsCxPusher::Pop()
{

View File

@ -3710,13 +3710,9 @@ nsDocument::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
NS_IMETHODIMP
nsDocument::Normalize()
{
PRInt32 count = mChildren.ChildCount();
for (PRInt32 i = 0; i < count; ++i) {
for (PRInt32 i = 0; i < mChildren.ChildCount(); ++i) {
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(mChildren.ChildAt(i)));
if (node) {
node->Normalize();
}
node->Normalize();
}
return NS_OK;

View File

@ -235,7 +235,9 @@ nsFrameLoader::Destroy()
// Let our window know that we are gone
nsCOMPtr<nsPIDOMWindow> win_private(do_GetInterface(mDocShell));
if (win_private) {
nsIDOMElement* frameElement = win_private->GetFrameElementInternal();
win_private->SetFrameElementInternal(nsnull);
NS_IF_RELEASE(frameElement);
}
nsCOMPtr<nsIBaseWindow> base_win(do_QueryInterface(mDocShell));
@ -402,7 +404,11 @@ nsFrameLoader::EnsureDocShell()
nsCOMPtr<nsPIDOMWindow> win_private(do_GetInterface(mDocShell));
NS_ENSURE_TRUE(win_private, NS_ERROR_UNEXPECTED);
nsIDOMElement* oldFrame = win_private->GetFrameElementInternal();
win_private->SetFrameElementInternal(frame_element);
nsIDOMElement* fe = frame_element.get();
NS_ADDREF(fe);
NS_IF_RELEASE(oldFrame);
nsCOMPtr<nsIBaseWindow> base_win(do_QueryInterface(mDocShell));
NS_ENSURE_TRUE(base_win, NS_ERROR_UNEXPECTED);

View File

@ -2797,15 +2797,16 @@ doInsertChildAt(nsIContent* aKid, PRUint32 aIndex, PRBool aNotify,
NS_PRECONDITION(!aParent || aParent->GetCurrentDoc() == aDocument,
"Incorrect aDocument");
nsMutationGuard::DidMutate();
// Do this before checking the child-count since this could cause mutations
mozAutoDocUpdate updateBatch(aDocument, UPDATE_CONTENT_MODEL, aNotify);
PRUint32 childCount = aChildArray.ChildCount();
NS_ENSURE_TRUE(aIndex <= childCount, NS_ERROR_ILLEGAL_VALUE);
nsMutationGuard::DidMutate();
PRBool isAppend = (aIndex == childCount);
mozAutoDocUpdate updateBatch(aDocument, UPDATE_CONTENT_MODEL, aNotify);
// Note that SetRootContent already deals with binding, so if we plan to call
// it we shouldn't bind ourselves.
// XXXbz this doesn't put aKid in the right spot, really... We really need a

View File

@ -1645,11 +1645,7 @@ nsEventListenerManager::HandleEventSubType(nsListenerStruct* aListenerStruct,
}
}
// nsCxPusher will push and pop (automatically) the current cx onto the
// context stack
nsCxPusher pusher;
if (NS_SUCCEEDED(result) && pusher.Push(aCurrentTarget)) {
if (NS_SUCCEEDED(result)) {
nsCOMPtr<nsIPrivateDOMEvent> aPrivDOMEvent(do_QueryInterface(aDOMEvent));
aPrivDOMEvent->SetCurrentTarget(aCurrentTarget);
result = aListener->HandleEvent(aDOMEvent);
@ -1727,6 +1723,7 @@ nsEventListenerManager::HandleEvent(nsPresContext* aPresContext,
}
if (NS_SUCCEEDED(ret)) {
nsCxPusher pusher;
PRInt32 count = listeners->Count();
nsVoidArray originalListeners(count);
originalListeners = *listeners;
@ -1746,14 +1743,17 @@ nsEventListenerManager::HandleEvent(nsPresContext* aPresContext,
if (eventListener) {
// Try the type-specific listener interface
PRBool hasInterface = PR_FALSE;
if (typeData)
if (typeData) {
pusher.Pop();
DispatchToInterface(*aDOMEvent, eventListener,
dispData->method, *typeData->iid,
&hasInterface);
}
// If it doesn't implement that, call the generic HandleEvent()
if (!hasInterface && (ls->mSubType == NS_EVENT_BITS_NONE ||
ls->mSubType & dispData->bits)) {
if (!hasInterface &&
(ls->mSubType == NS_EVENT_BITS_NONE || ls->mSubType & dispData->bits) &&
pusher.RePush(aCurrentTarget)) {
HandleEventSubType(ls, eventListener, *aDOMEvent, aCurrentTarget,
dispData ? dispData->bits : NS_EVENT_BITS_NONE,
aFlags);

View File

@ -2100,7 +2100,7 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
}
nsIFrame* currFrame = mCurrentTarget;
nsIContent* activeContent = nsnull;
nsCOMPtr<nsIContent> activeContent;
if (mCurrentTarget)
activeContent = mCurrentTarget->GetContent();

View File

@ -65,6 +65,12 @@ struct nsFramesetSpec {
nscoord mValue;
};
/**
* The maximum number of entries allowed in the frame set element row
* or column spec.
*/
#define NS_MAX_FRAMESET_SPEC_COUNT 16000
/**
* This interface is used by the nsFramesetFrame to access the parsed
* values of the "rows" and "cols" attributes

View File

@ -43,6 +43,7 @@
#include "nsIFrameSetElement.h"
#include "nsIHTMLDocument.h"
#include "nsIDocument.h"
#include "nspr.h"
class nsHTMLFrameSetElement : public nsGenericHTMLElement,
public nsIDOMHTMLFrameSetElement,
@ -312,10 +313,11 @@ nsHTMLFrameSetElement::ParseRowCol(const nsAString & aValue,
spec.StripChars(" \n\r\t\"\'");
spec.Trim(",");
// Count the commas
// Count the commas. Don't count more than X commas (bug 576447).
PR_STATIC_ASSERT(NS_MAX_FRAMESET_SPEC_COUNT * sizeof(nsFramesetSpec) < (1 << 30));
PRInt32 commaX = spec.FindChar(sComma);
PRInt32 count = 1;
while (commaX != kNotFound) {
while (commaX != kNotFound && count < NS_MAX_FRAMESET_SPEC_COUNT) {
count++;
commaX = spec.FindChar(sComma, commaX + 1);
}

View File

@ -2944,8 +2944,13 @@ nsHTMLDocument::GetSelection(nsAString& aReturn)
consoleService->LogStringMessage(NS_LITERAL_STRING("Deprecated method document.getSelection() called. Please use window.getSelection() instead.").get());
}
nsIDOMWindow *window = GetWindow();
NS_ENSURE_TRUE(window, NS_OK);
nsCOMPtr<nsIDOMWindow> window = do_QueryInterface(GetScopeObject());
nsCOMPtr<nsPIDOMWindow> pwin = do_QueryInterface(window);
NS_ENSURE_TRUE(pwin, NS_OK);
NS_ASSERTION(pwin->IsInnerWindow(), "Should have inner window here!");
NS_ENSURE_TRUE(pwin->GetOuterWindow() &&
pwin->GetOuterWindow()->GetCurrentInnerWindow() == pwin,
NS_OK);
nsCOMPtr<nsISelection> selection;
nsresult rv = window->GetSelection(getter_AddRefs(selection));

View File

@ -383,6 +383,9 @@ nsBindingManager::SetBinding(nsIContent* aContent, nsXBLBinding* aBinding)
SetWrappedJS(aContent, nsnull);
SetContentListFor(aContent, nsnull);
SetAnonymousNodesFor(aContent, nsnull);
if (oldBinding) {
oldBinding->SetBoundElement(nsnull);
}
}
return result ? NS_OK : NS_ERROR_FAILURE;

View File

@ -1217,7 +1217,7 @@ nsXBLBinding::AllowScripts()
return PR_FALSE;
}
nsIDocument* doc = mBoundElement->GetOwnerDoc();
nsIDocument* doc = mBoundElement ? mBoundElement->GetOwnerDoc() : nsnull;
if (!doc) {
return PR_FALSE;
}

View File

@ -383,6 +383,8 @@ nsXULCommandDispatcher::UpdateCommands(const nsAString& aEventName)
free(actionString);
}
#endif
nsCOMArray<nsIContent> updaters;
for (Updater* updater = mUpdaters; updater != nsnull; updater = updater->mNext) {
nsCOMPtr<nsIDOMElement> element;
@ -401,6 +403,12 @@ nsXULCommandDispatcher::UpdateCommands(const nsAString& aEventName)
NS_ASSERTION(content != nsnull, "not an nsIContent");
if (! content)
return NS_ERROR_UNEXPECTED;
updaters.AppendObject(content);
}
for (PRUint32 u = 0; u < updaters.Count(); u++) {
nsIContent* content = updaters[u];
nsCOMPtr<nsIDocument> document = content->GetDocument();
@ -414,7 +422,7 @@ nsXULCommandDispatcher::UpdateCommands(const nsAString& aEventName)
CopyUTF16toUTF8(aEventName, aeventnameC);
PR_LOG(gLog, PR_LOG_NOTICE,
("xulcmd[%p] update %p event=%s",
this, element.get(),
this, content,
aeventnameC.get()));
}
#endif
@ -500,4 +508,3 @@ nsXULCommandDispatcher::SetSuppressFocusScroll(PRBool aSuppressFocusScroll)
return mFocusController->SetSuppressFocusScroll(aSuppressFocusScroll);
}

View File

@ -96,7 +96,8 @@ FORCE_STATIC_LIB = 1
include $(topsrcdir)/config/rules.mk
LOCAL_INCLUDES = -I$(srcdir)/../../../base/src \
-I$(srcdir)/../../content/src \
$(NULL)
-I$(srcdir)/../../content/src \
-I$(srcdir)/../../../../layout/xul/base/src/tree/src \
$(NULL)
DEFINES += -D_IMPL_NS_LAYOUT

View File

@ -72,6 +72,8 @@
#include "nsUnicharUtils.h"
#include "nsINameSpaceManager.h"
#include "nsIDOMClassInfo.h"
#include "nsTreeContentView.h"
#include "nsDOMError.h"
// For security check
#include "nsIDocument.h"
@ -482,6 +484,9 @@ nsXULTreeBuilder::GetSelection(nsITreeSelection** aSelection)
NS_IMETHODIMP
nsXULTreeBuilder::SetSelection(nsITreeSelection* aSelection)
{
NS_ENSURE_TRUE(!aSelection ||
nsTreeContentView::CanTrustTreeSelection(aSelection),
NS_ERROR_DOM_SECURITY_ERR);
mSelection = aSelection;
return NS_OK;
}

View File

@ -56,6 +56,7 @@
#include "nsPIDOMStorage.h"
#include "nsIDocumentViewer.h"
#include "nsIDocumentLoaderFactory.h"
#include "nsIJARURI.h"
#include "nsCURILoader.h"
#include "nsDocShellCID.h"
#include "nsLayoutCID.h"
@ -639,6 +640,7 @@ nsDocShell::LoadURI(nsIURI * aURI,
nsCOMPtr<nsIInputStream> headersStream;
nsCOMPtr<nsISupports> owner;
PRBool inheritOwner = PR_FALSE;
PRBool ownerIsExplicit = PR_FALSE;
PRBool sendReferrer = PR_TRUE;
nsCOMPtr<nsISHEntry> shEntry;
nsXPIDLString target;
@ -662,6 +664,12 @@ nsDocShell::LoadURI(nsIURI * aURI,
aLoadInfo->GetPostDataStream(getter_AddRefs(postStream));
aLoadInfo->GetHeadersStream(getter_AddRefs(headersStream));
aLoadInfo->GetSendReferrer(&sendReferrer);
nsCOMPtr<nsIDocShellLoadInfo_1_9_0_BRANCH> info19 =
do_QueryInterface(aLoadInfo);
if (info19) {
info19->GetOwnerIsExplicit(&ownerIsExplicit);
}
}
#if defined(PR_LOGGING) && defined(DEBUG)
@ -774,81 +782,98 @@ nsDocShell::LoadURI(nsIURI * aURI,
("nsDocShell[%p]: loading from session history", this));
#endif
rv = LoadHistoryEntry(shEntry, loadType);
return LoadHistoryEntry(shEntry, loadType);
}
// Perform the load...
else {
// We need an owner (a referring principal). 4 possibilities:
// (1) If the system principal was passed in and we're a typeContent
// docshell, inherit the principal from the current document
// instead.
// (2) In all other cases when the principal passed in is not null,
// use that principal.
// (3) If the caller has allowed inheriting from the current
// document, or if we're being called from chrome (if there's
// system JS on the stack), then inheritOwner should be true and
// InternalLoad will get an owner from the current document. If
// none of these things are true, then
// (4) we pass a null owner into the channel, and an owner will be
// created later from the channel's internal data.
nsCOMPtr<nsIScriptSecurityManager> secMan =
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
// Just to compare, not to use!
nsCOMPtr<nsIPrincipal> sysPrin;
rv = secMan->GetSystemPrincipal(getter_AddRefs(sysPrin));
NS_ENSURE_SUCCESS(rv, rv);
if (owner == sysPrin && mItemType != typeChrome) {
// Perform the load...
// We need an owner (a referring principal).
//
// If ownerIsExplicit is not set there are 4 possibilities:
// (1) If the system principal was passed in and we're a typeContent
// docshell, inherit the principal from the current document
// instead.
// (2) In all other cases when the principal passed in is not null,
// use that principal.
// (3) If the caller has allowed inheriting from the current document,
// or if we're being called from system code (eg chrome JS or pure
// C++) then inheritOwner should be true and InternalLoad will get
// an owner from the current document. If none of these things are
// true, then
// (4) we pass a null owner into the channel, and an owner will be
// created later from the channel's internal data.
//
// If ownerIsExplicit *is* set, there are 4 possibilities
// (1) If the system principal was passed in and we're a typeContent
// docshell, return an error.
// (2) In all other cases when the principal passed in is not null,
// use that principal.
// (3) If the caller has allowed inheriting from the current document,
// then inheritOwner should be true and InternalLoad will get an owner
// from the current document. If none of these things are true, then
// (4) we pass a null owner into the channel, and an owner will be
// created later from the channel's internal data.
//
// NOTE: This all only works because the only thing the owner is used
// for in InternalLoad is data:, javascript:, and about:blank
// URIs. For other URIs this would all be dead wrong!
nsCOMPtr<nsIScriptSecurityManager> secMan =
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPrincipal> sysPrin;
rv = secMan->GetSystemPrincipal(getter_AddRefs(sysPrin));
NS_ENSURE_SUCCESS(rv, rv);
if (owner && mItemType != typeChrome) {
nsCOMPtr<nsIPrincipal> ownerPrincipal = do_QueryInterface(owner);
PRBool isSystem = ownerPrincipal == sysPrin;
if (isSystem) {
if (ownerIsExplicit) {
return NS_ERROR_DOM_SECURITY_ERR;
}
owner = nsnull;
inheritOwner = PR_TRUE;
}
else if (!owner && !inheritOwner) {
// See if there's system or chrome JS code running
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIPrincipal> subjectPrin;
rv = secMan->GetSubjectPrincipal(getter_AddRefs(subjectPrin));
// If there's no subject principal, there's no JS running, so
// we're in system code.
if (NS_SUCCEEDED(rv) &&
(!subjectPrin || sysPrin == subjectPrin)) {
inheritOwner = PR_TRUE;
}
}
}
if (!owner && !inheritOwner && !ownerIsExplicit) {
// See if there's system or chrome JS code running
rv = secMan->SubjectPrincipalIsSystem(&inheritOwner);
if (NS_FAILED(rv)) {
// Set it back to false
inheritOwner = PR_FALSE;
}
PRUint32 flags = 0;
if (inheritOwner)
flags |= INTERNAL_LOAD_FLAGS_INHERIT_OWNER;
if (!sendReferrer)
flags |= INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER;
if (aLoadFlags & LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP)
flags |= INTERNAL_LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
if (aLoadFlags & LOAD_FLAGS_FIRST_LOAD)
flags |= INTERNAL_LOAD_FLAGS_FIRST_LOAD;
rv = InternalLoad(aURI,
referrer,
owner,
flags,
target.get(),
nsnull, // No type hint
postStream,
headersStream,
loadType,
nsnull, // No SHEntry
aFirstParty,
nsnull, // No nsIDocShell
nsnull); // No nsIRequest
}
return rv;
PRUint32 flags = 0;
if (inheritOwner)
flags |= INTERNAL_LOAD_FLAGS_INHERIT_OWNER;
if (!sendReferrer)
flags |= INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER;
if (aLoadFlags & LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP)
flags |= INTERNAL_LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
if (aLoadFlags & LOAD_FLAGS_FIRST_LOAD)
flags |= INTERNAL_LOAD_FLAGS_FIRST_LOAD;
return InternalLoad(aURI,
referrer,
owner,
flags,
target.get(),
nsnull, // No type hint
postStream,
headersStream,
loadType,
nsnull, // No SHEntry
aFirstParty,
nsnull, // No nsIDocShell
nsnull); // No nsIRequest
}
NS_IMETHODIMP
@ -3314,6 +3339,12 @@ nsDocShell::Reload(PRUint32 aReloadFlags)
NS_IMETHODIMP
nsDocShell::Stop(PRUint32 aStopFlags)
{
if (mLoadType == LOAD_ERROR_PAGE && mLSHE) {
// Since error page loads never unset mLSHE, do so now
SetHistoryEntry(&mOSHE, mLSHE);
SetHistoryEntry(&mLSHE, nsnull);
}
if (nsIWebNavigation::STOP_CONTENT & aStopFlags) {
// Revoke any pending plevents related to content viewer restoration
nsCOMPtr<nsIEventQueue> uiThreadQueue;
@ -4495,6 +4526,25 @@ nsDocShell::SetupRefreshURIFromHeader(nsIURI * aBaseURI,
rv = securityManager->CheckLoadURI(aBaseURI, uri,
nsIScriptSecurityManager::
DISALLOW_FROM_MAIL);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIURI> innerURI = uri;
nsCOMPtr<nsIJARURI> jarURI(do_QueryInterface(innerURI));
while (jarURI) {
jarURI->GetJARFile(getter_AddRefs(innerURI));
jarURI = do_QueryInterface(innerURI);
}
NS_ENSURE_TRUE(innerURI, NS_ERROR_FAILURE);
PRBool isjs = PR_TRUE;
rv = innerURI->SchemeIs("javascript", &isjs);
NS_ENSURE_SUCCESS(rv, rv);
if (isjs) {
return NS_ERROR_FAILURE;
}
}
if (NS_SUCCEEDED(rv)) {
// Since we can't travel back in time yet, just pretend
// negative numbers do nothing at all.
@ -4831,6 +4881,12 @@ nsDocShell::OnRedirectStateChange(nsIChannel* aOldChannel,
return; // nothing to tell anybody about
AddToGlobalHistory(oldURI, PR_TRUE, aOldChannel);
}
if (!(aStateFlags & nsIChannelEventSink::REDIRECT_INTERNAL) &&
mLoadType & (LOAD_CMD_RELOAD | LOAD_CMD_HISTORY)) {
mLoadType = LOAD_NORMAL_REPLACE;
SetHistoryEntry(&mLSHE, nsnull);
}
}
NS_IMETHODIMP
@ -8781,6 +8837,7 @@ NS_INTERFACE_MAP_BEGIN(nsRefreshTimer)
NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
NS_INTERFACE_MAP_END_THREADSAFE
///*****************************************************************************
// nsRefreshTimer::nsITimerCallback
//*****************************************************************************
@ -8820,46 +8877,46 @@ nsRefreshTimer::Notify(nsITimer * aTimer)
*/
loadInfo->SetReferrer(currURI);
/* Don't ever "guess" on which owner to use to avoid picking
* the current owner.
*/
nsCOMPtr<nsIDocShellLoadInfo_1_9_0_BRANCH> info19 =
do_QueryInterface(loadInfo);
NS_ENSURE_TRUE(info19, NS_ERROR_NO_INTERFACE);
info19->SetOwnerIsExplicit(PR_TRUE);
/* Check if this META refresh causes a redirection
* to another site.
* to another site.
*/
PRBool equalUri = PR_FALSE;
nsresult rv = mURI->Equals(currURI, &equalUri);
if (NS_SUCCEEDED(rv) && (!equalUri) && mMetaRefresh) {
if (NS_SUCCEEDED(rv) && (!equalUri) && mMetaRefresh &&
mDelay <= REFRESH_REDIRECT_TIMER) {
/* It is a META refresh based redirection. Now check if it happened within
* the threshold time we have in mind(15000 ms as defined by REFRESH_REDIRECT_TIMER).
* If so, pass a REPLACE flag to LoadURI().
/* It is a META refresh based redirection within the threshold time
* we have in mind (15000 ms as defined by REFRESH_REDIRECT_TIMER).
* Pass a REPLACE flag to LoadURI().
*/
if (delay <= REFRESH_REDIRECT_TIMER) {
loadInfo->SetLoadType(nsIDocShellLoadInfo::loadNormalReplace);
/* for redirects we mimic HTTP, which passes the
* original referrer
*/
nsCOMPtr<nsIURI> internalReferrer;
nsCOMPtr<nsIWebNavigation> webNav =
do_QueryInterface(mDocShell);
if (webNav) {
webNav->GetReferringURI(getter_AddRefs(internalReferrer));
if (internalReferrer) {
loadInfo->SetReferrer(internalReferrer);
}
}
loadInfo->SetLoadType(nsIDocShellLoadInfo::loadNormalReplace);
/* for redirects we mimic HTTP, which passes the
* original referrer
*/
nsCOMPtr<nsIURI> internalReferrer;
webNav->GetReferringURI(getter_AddRefs(internalReferrer));
if (internalReferrer) {
loadInfo->SetReferrer(internalReferrer);
}
else
loadInfo->SetLoadType(nsIDocShellLoadInfo::loadRefresh);
/*
* LoadURL(...) will cancel all refresh timers... This causes the Timer and
* its refreshData instance to be released...
*/
mDocShell->LoadURI(mURI, loadInfo,
nsIWebNavigation::LOAD_FLAGS_NONE, PR_TRUE);
return NS_OK;
}
else
else {
loadInfo->SetLoadType(nsIDocShellLoadInfo::loadRefresh);
}
/*
* LoadURI(...) will cancel all refresh timers... This causes the
* Timer and its refreshData instance to be released...
*/
mDocShell->LoadURI(mURI, loadInfo, nsIWebNavigation::LOAD_FLAGS_NONE, PR_TRUE);
}
return NS_OK;

View File

@ -43,16 +43,15 @@
nsDocShellEnumerator::nsDocShellEnumerator(PRInt32 inEnumerationDirection)
: mRootItem(nsnull)
, mItemArray(nsnull)
, mCurIndex(0)
, mDocShellType(nsIDocShellTreeItem::typeAll)
, mArrayValid(PR_FALSE)
, mEnumerationDirection(inEnumerationDirection)
{
}
nsDocShellEnumerator::~nsDocShellEnumerator()
{
delete mItemArray;
}
NS_IMPL_ISUPPORTS1(nsDocShellEnumerator, nsISimpleEnumerator)
@ -66,19 +65,15 @@ NS_IMETHODIMP nsDocShellEnumerator::GetNext(nsISupports **outCurItem)
nsresult rv = EnsureDocShellArray();
if (NS_FAILED(rv)) return rv;
if (mCurIndex >= 0 && mCurIndex < mItemArray->Count())
{
nsIDocShellTreeItem* thisItem = NS_REINTERPRET_CAST(nsIDocShellTreeItem*, mItemArray->ElementAt(mCurIndex));
rv = thisItem->QueryInterface(NS_GET_IID(nsISupports), (void **)outCurItem);
if (NS_FAILED(rv)) return rv;
}
else
if (mCurIndex >= mItemArray.Length()) {
return NS_ERROR_FAILURE;
mCurIndex ++;
return NS_OK;
}
// post-increment is important here
nsCOMPtr<nsISupports> item = do_QueryReferent(mItemArray[mCurIndex++], &rv);
item.forget(outCurItem);
return rv;
}
/* boolean hasMoreElements (); */
@ -90,21 +85,21 @@ NS_IMETHODIMP nsDocShellEnumerator::HasMoreElements(PRBool *outHasMore)
nsresult rv = EnsureDocShellArray();
if (NS_FAILED(rv)) return rv;
*outHasMore = (mCurIndex < mItemArray->Count());
*outHasMore = (mCurIndex < mItemArray.Length());
return NS_OK;
}
nsresult nsDocShellEnumerator::GetEnumerationRootItem(nsIDocShellTreeItem * *aEnumerationRootItem)
{
NS_ENSURE_ARG_POINTER(aEnumerationRootItem);
*aEnumerationRootItem = mRootItem;
NS_IF_ADDREF(*aEnumerationRootItem);
nsCOMPtr<nsIDocShellTreeItem> item = do_QueryReferent(mRootItem);
item.forget(aEnumerationRootItem);
return NS_OK;
}
nsresult nsDocShellEnumerator::SetEnumerationRootItem(nsIDocShellTreeItem * aEnumerationRootItem)
{
mRootItem = aEnumerationRootItem;
mRootItem = do_GetWeakReference(aEnumerationRootItem);
ClearState();
return NS_OK;
}
@ -131,12 +126,10 @@ nsresult nsDocShellEnumerator::First()
nsresult nsDocShellEnumerator::EnsureDocShellArray()
{
if (!mItemArray)
if (!mArrayValid)
{
mItemArray = new nsVoidArray;
if (!mItemArray) return NS_ERROR_OUT_OF_MEMORY;
return BuildDocShellArray(*mItemArray);
mArrayValid = PR_TRUE;
return BuildDocShellArray(mItemArray);
}
return NS_OK;
@ -144,21 +137,21 @@ nsresult nsDocShellEnumerator::EnsureDocShellArray()
nsresult nsDocShellEnumerator::ClearState()
{
delete mItemArray;
mItemArray = nsnull;
mItemArray.Clear();
mArrayValid = PR_FALSE;
mCurIndex = 0;
return NS_OK;
}
nsresult nsDocShellEnumerator::BuildDocShellArray(nsVoidArray& inItemArray)
nsresult nsDocShellEnumerator::BuildDocShellArray(nsTArray<nsWeakPtr>& inItemArray)
{
NS_ENSURE_TRUE(mRootItem, NS_ERROR_NOT_INITIALIZED);
inItemArray.Clear();
return BuildArrayRecursive(mRootItem, inItemArray);
nsCOMPtr<nsIDocShellTreeItem> item = do_QueryReferent(mRootItem);
return BuildArrayRecursive(item, inItemArray);
}
nsresult nsDocShellForwardsEnumerator::BuildArrayRecursive(nsIDocShellTreeItem* inItem, nsVoidArray& inItemArray)
nsresult nsDocShellForwardsEnumerator::BuildArrayRecursive(nsIDocShellTreeItem* inItem, nsTArray<nsWeakPtr>& inItemArray)
{
nsresult rv;
nsCOMPtr<nsIDocShellTreeNode> itemAsNode = do_QueryInterface(inItem, &rv);
@ -169,8 +162,8 @@ nsresult nsDocShellForwardsEnumerator::BuildArrayRecursive(nsIDocShellTreeItem*
if ((mDocShellType == nsIDocShellTreeItem::typeAll) ||
(NS_SUCCEEDED(inItem->GetItemType(&itemType)) && (itemType == mDocShellType)))
{
rv = inItemArray.AppendElement((void *)inItem);
if (NS_FAILED(rv)) return rv;
if (!inItemArray.AppendElement(do_GetWeakReference(inItem)))
return NS_ERROR_OUT_OF_MEMORY;
}
PRInt32 numChildren;
@ -191,7 +184,7 @@ nsresult nsDocShellForwardsEnumerator::BuildArrayRecursive(nsIDocShellTreeItem*
}
nsresult nsDocShellBackwardsEnumerator::BuildArrayRecursive(nsIDocShellTreeItem* inItem, nsVoidArray& inItemArray)
nsresult nsDocShellBackwardsEnumerator::BuildArrayRecursive(nsIDocShellTreeItem* inItem, nsTArray<nsWeakPtr>& inItemArray)
{
nsresult rv;
nsCOMPtr<nsIDocShellTreeNode> itemAsNode = do_QueryInterface(inItem, &rv);
@ -216,12 +209,10 @@ nsresult nsDocShellBackwardsEnumerator::BuildArrayRecursive(nsIDocShellTreeItem*
if ((mDocShellType == nsIDocShellTreeItem::typeAll) ||
(NS_SUCCEEDED(inItem->GetItemType(&itemType)) && (itemType == mDocShellType)))
{
rv = inItemArray.AppendElement((void *)inItem);
if (NS_FAILED(rv)) return rv;
if (!inItemArray.AppendElement(do_GetWeakReference(inItem)))
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}

View File

@ -42,7 +42,9 @@
#include "nsIEnumerator.h"
#include "nsCOMPtr.h"
#include "nsVoidArray.h"
#include "nsTArray.h"
#include "nsIWeakReference.h"
#include "nsIWeakReferenceUtils.h"
class nsIDocShellTreeItem;
@ -98,17 +100,18 @@ protected:
nsresult EnsureDocShellArray();
nsresult ClearState();
nsresult BuildDocShellArray(nsVoidArray& inItemArray);
virtual nsresult BuildArrayRecursive(nsIDocShellTreeItem* inItem, nsVoidArray& inItemArray) = 0;
nsresult BuildDocShellArray(nsTArray<nsWeakPtr>& inItemArray);
virtual nsresult BuildArrayRecursive(nsIDocShellTreeItem* inItem, nsTArray<nsWeakPtr>& inItemArray) = 0;
protected:
nsIDocShellTreeItem* mRootItem; // weak ref!
nsWeakPtr mRootItem; // weak ref!
nsVoidArray* mItemArray; // flattened list of items with matching type
PRInt32 mCurIndex;
nsTArray<nsWeakPtr> mItemArray; // flattened list of items with matching type
PRUint32 mCurIndex;
PRInt32 mDocShellType; // only want shells of this type
PRPackedBool mArrayValid; // is mItemArray up to date?
const PRInt8 mEnumerationDirection;
};
@ -125,7 +128,7 @@ public:
protected:
virtual nsresult BuildArrayRecursive(nsIDocShellTreeItem* inItem, nsVoidArray& inItemArray);
virtual nsresult BuildArrayRecursive(nsIDocShellTreeItem* inItem, nsTArray<nsWeakPtr>& inItemArray);
};
@ -139,6 +142,6 @@ public:
}
protected:
virtual nsresult BuildArrayRecursive(nsIDocShellTreeItem* inItem, nsVoidArray& inItemArray);
virtual nsresult BuildArrayRecursive(nsIDocShellTreeItem* inItem, nsTArray<nsWeakPtr>& inItemArray);
};

View File

@ -49,6 +49,7 @@
nsDocShellLoadInfo::nsDocShellLoadInfo()
: mInheritOwner(PR_FALSE),
mOwnerIsExplicit(PR_FALSE),
mSendReferrer(PR_TRUE),
mLoadType(nsIDocShellLoadInfo::loadNormal)
{
@ -68,6 +69,7 @@ NS_IMPL_RELEASE(nsDocShellLoadInfo)
NS_INTERFACE_MAP_BEGIN(nsDocShellLoadInfo)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDocShellLoadInfo)
NS_INTERFACE_MAP_ENTRY(nsIDocShellLoadInfo)
NS_INTERFACE_MAP_ENTRY(nsIDocShellLoadInfo_1_9_0_BRANCH)
NS_INTERFACE_MAP_END
//*****************************************************************************
@ -118,6 +120,18 @@ NS_IMETHODIMP nsDocShellLoadInfo::SetInheritOwner(PRBool aInheritOwner)
return NS_OK;
}
NS_IMETHODIMP nsDocShellLoadInfo::GetOwnerIsExplicit(PRBool* aOwnerIsExplicit)
{
*aOwnerIsExplicit = mOwnerIsExplicit;
return NS_OK;
}
NS_IMETHODIMP nsDocShellLoadInfo::SetOwnerIsExplicit(PRBool aOwnerIsExplicit)
{
mOwnerIsExplicit = aOwnerIsExplicit;
return NS_OK;
}
NS_IMETHODIMP nsDocShellLoadInfo::GetLoadType(nsDocShellInfoLoadType * aLoadType)
{
NS_ENSURE_ARG_POINTER(aLoadType);

View File

@ -51,13 +51,14 @@
#include "nsIInputStream.h"
#include "nsISHEntry.h"
class nsDocShellLoadInfo : public nsIDocShellLoadInfo
class nsDocShellLoadInfo : public nsIDocShellLoadInfo_1_9_0_BRANCH
{
public:
nsDocShellLoadInfo();
NS_DECL_ISUPPORTS
NS_DECL_NSIDOCSHELLLOADINFO
NS_DECL_NSIDOCSHELLLOADINFO_1_9_0_BRANCH
protected:
virtual ~nsDocShellLoadInfo();
@ -66,6 +67,7 @@ protected:
nsCOMPtr<nsIURI> mReferrer;
nsCOMPtr<nsISupports> mOwner;
PRPackedBool mInheritOwner;
PRPackedBool mOwnerIsExplicit;
PRPackedBool mSendReferrer;
nsDocShellInfoLoadType mLoadType;
nsCOMPtr<nsISHEntry> mSHEntry;

View File

@ -103,3 +103,15 @@ interface nsIDocShellLoadInfo : nsISupports
*/
attribute boolean sendReferrer;
};
[scriptable, uuid(b66d94ba-4457-41b1-9507-79c1cd873da0)]
interface nsIDocShellLoadInfo_1_9_0_BRANCH : nsIDocShellLoadInfo
{
/** If this attribute is true only ever use the owner specify by
* the owner and inheritOwner attributes.
* If there are security reasons for why this is unsafe, such
* as trying to use a systemprincipal owner for a content docshell
* the load fails.
*/
attribute boolean ownerIsExplicit;
};

View File

@ -532,6 +532,10 @@ nsWebShell::OnLinkClickSync(nsIContent *aContent,
nsCOMPtr<nsIDOMHTMLAnchorElement> anchor(do_QueryInterface(aContent));
if (anchor) {
anchor->GetType(typeHint);
NS_ConvertUTF16toUTF8 utf8Hint(typeHint);
nsCAutoString type, dummy;
NS_ParseContentType(utf8Hint, type, dummy);
CopyUTF8toUTF16(type, typeHint);
}
switch(aVerb) {

View File

@ -173,6 +173,7 @@ public:
return mFrameElement;
}
// Caller must release the old frame element and addref the new one.
void SetFrameElementInternal(nsIDOMElement *aFrameElement)
{
if (IsOuterWindow()) {

View File

@ -191,7 +191,6 @@ enum nsDOMClassInfoID {
// Crypto classes
eDOMClassInfo_Crypto_id,
eDOMClassInfo_CRMFObject_id,
eDOMClassInfo_Pkcs11_id,
// DOM Traversal classes
eDOMClassInfo_TreeWalker_id,

View File

@ -51,8 +51,11 @@
//
// Basic (virtual) BarProp class implementation
//
nsBarProp::nsBarProp() : mBrowserChrome(nsnull)
nsBarProp::nsBarProp(nsGlobalWindow *aWindow)
{
mDOMWindow = aWindow;
nsISupports *supwin = static_cast<nsIScriptGlobalObject *>(aWindow);
mDOMWindowWeakref = do_GetWeakReference(supwin);
}
nsBarProp::~nsBarProp()
@ -71,25 +74,19 @@ NS_INTERFACE_MAP_END
NS_IMPL_ADDREF(nsBarProp)
NS_IMPL_RELEASE(nsBarProp)
NS_IMETHODIMP
nsBarProp::SetWebBrowserChrome(nsIWebBrowserChrome* aBrowserChrome)
{
mBrowserChrome = aBrowserChrome;
return NS_OK;
}
NS_IMETHODIMP
nsBarProp::GetVisibleByFlag(PRBool *aVisible, PRUint32 aChromeFlag)
{
NS_ENSURE_TRUE(mBrowserChrome, NS_ERROR_FAILURE);
PRUint32 chromeFlags;
*aVisible = PR_FALSE;
NS_ENSURE_SUCCESS(mBrowserChrome->GetChromeFlags(&chromeFlags),
nsCOMPtr<nsIWebBrowserChrome> browserChrome = GetBrowserChrome();
NS_ENSURE_TRUE(browserChrome, NS_OK);
PRUint32 chromeFlags;
NS_ENSURE_SUCCESS(browserChrome->GetChromeFlags(&chromeFlags),
NS_ERROR_FAILURE);
if(chromeFlags & aChromeFlag)
if (chromeFlags & aChromeFlag)
*aVisible = PR_TRUE;
return NS_OK;
@ -98,9 +95,10 @@ nsBarProp::GetVisibleByFlag(PRBool *aVisible, PRUint32 aChromeFlag)
NS_IMETHODIMP
nsBarProp::SetVisibleByFlag(PRBool aVisible, PRUint32 aChromeFlag)
{
NS_ENSURE_TRUE(mBrowserChrome, NS_ERROR_FAILURE);
nsCOMPtr<nsIWebBrowserChrome> browserChrome = GetBrowserChrome();
NS_ENSURE_TRUE(browserChrome, NS_OK);
PRBool enabled = PR_FALSE;
PRBool enabled = PR_FALSE;
nsCOMPtr<nsIScriptSecurityManager>
securityManager(do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID));
@ -111,23 +109,37 @@ nsBarProp::SetVisibleByFlag(PRBool aVisible, PRUint32 aChromeFlag)
PRUint32 chromeFlags;
NS_ENSURE_SUCCESS(mBrowserChrome->GetChromeFlags(&chromeFlags),
NS_ENSURE_SUCCESS(browserChrome->GetChromeFlags(&chromeFlags),
NS_ERROR_FAILURE);
if(aVisible)
if (aVisible)
chromeFlags |= aChromeFlag;
else
chromeFlags &= ~aChromeFlag;
NS_ENSURE_SUCCESS(mBrowserChrome->SetChromeFlags(chromeFlags),
NS_ENSURE_SUCCESS(browserChrome->SetChromeFlags(chromeFlags),
NS_ERROR_FAILURE);
return NS_OK;
}
already_AddRefed<nsIWebBrowserChrome>
nsBarProp::GetBrowserChrome()
{
// Check that the window is still alive.
nsCOMPtr<nsIDOMWindow> domwin(do_QueryReferent(mDOMWindowWeakref));
if (!domwin)
return nsnull;
nsIWebBrowserChrome *browserChrome = nsnull;
mDOMWindow->GetWebBrowserChrome(&browserChrome);
return browserChrome;
}
//
// MenubarProp class implementation
//
nsMenubarProp::nsMenubarProp()
nsMenubarProp::nsMenubarProp(nsGlobalWindow *aWindow)
: nsBarProp(aWindow)
{
}
@ -153,7 +165,8 @@ nsMenubarProp::SetVisible(PRBool aVisible)
// ToolbarProp class implementation
//
nsToolbarProp::nsToolbarProp()
nsToolbarProp::nsToolbarProp(nsGlobalWindow *aWindow)
: nsBarProp(aWindow)
{
}
@ -179,7 +192,8 @@ nsToolbarProp::SetVisible(PRBool aVisible)
// LocationbarProp class implementation
//
nsLocationbarProp::nsLocationbarProp()
nsLocationbarProp::nsLocationbarProp(nsGlobalWindow *aWindow)
: nsBarProp(aWindow)
{
}
@ -207,7 +221,8 @@ nsLocationbarProp::SetVisible(PRBool aVisible)
// PersonalbarProp class implementation
//
nsPersonalbarProp::nsPersonalbarProp()
nsPersonalbarProp::nsPersonalbarProp(nsGlobalWindow *aWindow)
: nsBarProp(aWindow)
{
}
@ -235,7 +250,8 @@ nsPersonalbarProp::SetVisible(PRBool aVisible)
// StatusbarProp class implementation
//
nsStatusbarProp::nsStatusbarProp()
nsStatusbarProp::nsStatusbarProp(nsGlobalWindow *aWindow)
: nsBarProp(aWindow)
{
}
@ -262,10 +278,8 @@ nsStatusbarProp::SetVisible(PRBool aVisible)
//
nsScrollbarsProp::nsScrollbarsProp(nsGlobalWindow *aWindow)
: nsBarProp(aWindow)
{
mDOMWindow = aWindow;
nsISupports *supwin = NS_STATIC_CAST(nsIScriptGlobalObject *, aWindow);
mDOMWindowWeakref = do_GetWeakReference(supwin);
}
nsScrollbarsProp::~nsScrollbarsProp()
@ -339,7 +353,7 @@ nsScrollbarsProp::SetVisible(PRBool aVisible)
}
/* Notably absent is the part where we notify the chrome window using
mBrowserChrome->SetChromeFlags(). Given the possibility of multiple
GetBrowserChrome()->SetChromeFlags(). Given the possibility of multiple
DOM windows (multiple top-level windows, even) within a single
chrome window, the historical concept of a single "has scrollbars"
flag in the chrome is inapplicable, and we can't tell at this level
@ -354,4 +368,3 @@ nsScrollbarsProp::SetVisible(PRBool aVisible)
return NS_OK;
}

View File

@ -56,26 +56,34 @@ class nsIWebBrowserChrome;
class nsBarProp : public nsIDOMBarProp
{
public:
nsBarProp();
explicit nsBarProp(nsGlobalWindow *aWindow);
virtual ~nsBarProp();
NS_DECL_ISUPPORTS
NS_IMETHOD SetWebBrowserChrome(nsIWebBrowserChrome* aBrowserChrome);
NS_IMETHOD GetVisibleByFlag(PRBool *aVisible, PRUint32 aChromeFlag);
NS_IMETHOD SetVisibleByFlag(PRBool aVisible, PRUint32 aChromeFlag);
protected:
// Weak Reference
nsIWebBrowserChrome* mBrowserChrome;
already_AddRefed<nsIWebBrowserChrome> GetBrowserChrome();
nsGlobalWindow *mDOMWindow;
nsCOMPtr<nsIWeakReference> mDOMWindowWeakref;
/* Note the odd double reference to the owning global window.
Since the corresponding DOM window nominally owns this object,
but refcounted ownership of this object can be handed off to
owners unknown, we need a weak ref back to the DOM window.
However we also need access to properties of the DOM Window
that aren't available through interfaces. Then it's either
a weak ref and some skanky casting, or this funky double ref.
Funky beats skanky, so here we are. */
};
// Script "menubar" object
class nsMenubarProp : public nsBarProp
{
public:
nsMenubarProp();
explicit nsMenubarProp(nsGlobalWindow *aWindow);
virtual ~nsMenubarProp();
NS_DECL_NSIDOMBARPROP
@ -85,7 +93,7 @@ public:
class nsToolbarProp : public nsBarProp
{
public:
nsToolbarProp();
explicit nsToolbarProp(nsGlobalWindow *aWindow);
virtual ~nsToolbarProp();
NS_DECL_NSIDOMBARPROP
@ -95,7 +103,7 @@ public:
class nsLocationbarProp : public nsBarProp
{
public:
nsLocationbarProp();
explicit nsLocationbarProp(nsGlobalWindow *aWindow);
virtual ~nsLocationbarProp();
NS_DECL_NSIDOMBARPROP
@ -105,7 +113,7 @@ public:
class nsPersonalbarProp : public nsBarProp
{
public:
nsPersonalbarProp();
explicit nsPersonalbarProp(nsGlobalWindow *aWindow);
virtual ~nsPersonalbarProp();
NS_DECL_NSIDOMBARPROP
@ -115,31 +123,20 @@ public:
class nsStatusbarProp : public nsBarProp
{
public:
nsStatusbarProp();
explicit nsStatusbarProp(nsGlobalWindow *aWindow);
virtual ~nsStatusbarProp();
NS_DECL_NSIDOMBARPROP
};
// Script "scrollbars" object
class nsScrollbarsProp : public nsBarProp {
class nsScrollbarsProp : public nsBarProp
{
public:
nsScrollbarsProp(nsGlobalWindow *aWindow);
explicit nsScrollbarsProp(nsGlobalWindow *aWindow);
virtual ~nsScrollbarsProp();
NS_DECL_NSIDOMBARPROP
private:
nsGlobalWindow *mDOMWindow;
nsCOMPtr<nsIWeakReference> mDOMWindowWeakref;
/* Note the odd double reference to the owning global window.
Since the corresponding DOM window nominally owns this object,
yet refcounted ownership of this object can be handed off to
owners unknown, we need a weak ref to back to the DOM window.
However we also need access to properties of the DOM Window
that aren't available through interfaces. Then it's either
a weak ref and some skanky casting, or this funky double ref.
Funky beats skanky, so here we are. */
};
#endif /* nsBarProps_h___ */

View File

@ -309,7 +309,6 @@
#include "nsIDOMXULCommandDispatcher.h"
#include "nsIDOMCrypto.h"
#include "nsIDOMCRMFObject.h"
#include "nsIDOMPkcs11.h"
#include "nsIControllers.h"
#include "nsISelection.h"
#include "nsIBoxObject.h"
@ -557,8 +556,7 @@ static nsDOMClassInfoData sClassInfoData[] = {
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(DOMException, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(DocumentFragment, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(DocumentFragment, nsNodeSH, NODE_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(Element, nsElementSH,
ELEMENT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(Attr, nsDOMGenericSH,
@ -806,8 +804,6 @@ static nsDOMClassInfoData sClassInfoData[] = {
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(CRMFObject, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(Pkcs11, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
// DOM Traversal classes
NS_DEFINE_CLASSINFO_DATA(TreeWalker, nsDOMGCParticipantSH,
@ -2418,10 +2414,6 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_ENTRY(nsIDOMCRMFObject)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(Pkcs11, nsIDOMPkcs11)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMPkcs11)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(XMLStylesheetProcessingInstruction, nsIDOMProcessingInstruction)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMProcessingInstruction)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMLinkStyle)
@ -6020,13 +6012,61 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
return NS_OK;
}
JSString *str = JSVAL_TO_STRING(id);
if (id == sLocation_id) {
// This must be done even if we're just getting the value of
// window.location (i.e. no checking flags & JSRESOLVE_ASSIGNING
// here) since we must define window.location to prevent the
// getter from being overriden (for security reasons).
nsCOMPtr<nsIDOMLocation> location;
rv = win->GetLocation(getter_AddRefs(location));
NS_ENSURE_SUCCESS(rv, rv);
// Make sure we wrap the location object in the inner window's
// scope if we've got an inner window.
JSObject *scope = nsnull;
if (win->IsOuterWindow()) {
nsGlobalWindow *innerWin = win->GetCurrentInnerWindowInternal();
if (innerWin) {
scope = innerWin->GetGlobalJSObject();
}
}
if (!scope) {
wrapper->GetJSObject(&scope);
}
jsval v;
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
rv = WrapNative(cx, scope, location, NS_GET_IID(nsIDOMLocation), &v,
getter_AddRefs(holder));
NS_ENSURE_SUCCESS(rv, rv);
PRBool doSecurityCheckInAddProperty = sDoSecurityCheckInAddProperty;
sDoSecurityCheckInAddProperty = PR_FALSE;
JSBool ok = ::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str),
::JS_GetStringLength(str), v, nsnull,
nsnull, JSPROP_ENUMERATE);
sDoSecurityCheckInAddProperty = doSecurityCheckInAddProperty;
if (!ok) {
return NS_ERROR_FAILURE;
}
*objp = obj;
return NS_OK;
}
// Hmm, we do an awful lot of QIs here; maybe we should add a
// method on an interface that would let us just call into the
// window code directly...
JSString *str = JSVAL_TO_STRING(id);
// Don't resolve named iframes on native wrappers
if (!ObjectIsNativeWrapper(cx, obj)) {
nsCOMPtr<nsIDocShellTreeNode> dsn(do_QueryInterface(win->GetDocShell()));
@ -6145,55 +6185,6 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
return NS_OK;
}
if (id == sLocation_id) {
// This must be done even if we're just getting the value of
// window.location (i.e. no checking flags & JSRESOLVE_ASSIGNING
// here) since we must define window.location to prevent the
// getter from being overriden (for security reasons).
nsCOMPtr<nsIDOMLocation> location;
rv = win->GetLocation(getter_AddRefs(location));
NS_ENSURE_SUCCESS(rv, rv);
// Make sure we wrap the location object in the inner window's
// scope if we've got an inner window.
JSObject *scope = nsnull;
if (win->IsOuterWindow()) {
nsGlobalWindow *innerWin = win->GetCurrentInnerWindowInternal();
if (innerWin) {
scope = innerWin->GetGlobalJSObject();
}
}
if (!scope) {
wrapper->GetJSObject(&scope);
}
jsval v;
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
rv = WrapNative(cx, scope, location, NS_GET_IID(nsIDOMLocation), &v,
getter_AddRefs(holder));
NS_ENSURE_SUCCESS(rv, rv);
PRBool doSecurityCheckInAddProperty = sDoSecurityCheckInAddProperty;
sDoSecurityCheckInAddProperty = PR_FALSE;
JSBool ok = ::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str),
::JS_GetStringLength(str), v, nsnull,
nsnull, JSPROP_ENUMERATE);
sDoSecurityCheckInAddProperty = doSecurityCheckInAddProperty;
if (!ok) {
return NS_ERROR_FAILURE;
}
*objp = obj;
return NS_OK;
}
if (flags & JSRESOLVE_ASSIGNING) {
if (IsReadonlyReplaceable(id) ||
(!(flags & JSRESOLVE_QUALIFIED) && IsWritableReplaceable(id))) {
@ -6760,17 +6751,6 @@ nsEventReceiverSH::AddEventListenerHelper(JSContext *cx, JSObject *obj,
return JS_FALSE;
}
// Can't use the macro OBJ_TO_INNER_OBJECT here due to it using the
// non-exported function js_GetSlotThreadSafe().
{
JSClass *clasp = JS_GET_CLASS(cx, obj);
if (clasp->flags & JSCLASS_IS_EXTENDED) {
JSExtendedClass *xclasp = (JSExtendedClass*)clasp;
if (xclasp->innerObject)
obj = xclasp->innerObject(cx, obj);
}
}
nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
nsresult rv =
sXPConnect->GetWrappedNativeOfJSObject(cx, obj, getter_AddRefs(wrapper));
@ -6784,6 +6764,26 @@ nsEventReceiverSH::AddEventListenerHelper(JSContext *cx, JSObject *obj,
// event listener.
wrapper->GetJSObject(&obj);
// Can't use the macro OBJ_TO_INNER_OBJECT here due to it using the
// non-exported function js_GetSlotThreadSafe().
{
JSClass *clasp = JS_GET_CLASS(cx, obj);
if (clasp->flags & JSCLASS_IS_EXTENDED) {
JSExtendedClass *xclasp = (JSExtendedClass*)clasp;
if (xclasp->innerObject)
obj = xclasp->innerObject(cx, obj);
}
}
if (!obj) {
return JS_FALSE;
}
rv = sXPConnect->GetWrappedNativeOfJSObject(cx, obj, getter_AddRefs(wrapper));
if (NS_FAILED(rv)) {
nsDOMClassInfo::ThrowJSException(cx, rv);
return JS_FALSE;
}
// Check that the caller has permission to call obj's addEventListener.
if (NS_FAILED(sSecMan->CheckPropertyAccess(cx, obj,
JS_GET_CLASS(cx, obj)->name,

View File

@ -97,7 +97,6 @@
#include "nsIDOMEvent.h"
#include "nsIDOMKeyEvent.h"
#include "nsIDOMPopupBlockedEvent.h"
#include "nsIDOMPkcs11.h"
#include "nsDOMString.h"
#include "nsIEmbeddingSiteWindow2.h"
#include "nsIEventQueueService.h"
@ -444,6 +443,7 @@ nsGlobalWindow::~nsGlobalWindow()
}
}
NS_IF_RELEASE(mFrameElement);
mDocument = nsnull; // Forces Release
NS_ASSERTION(!mArguments, "mArguments wasn't cleaned up properly!");
@ -1539,12 +1539,6 @@ nsGlobalWindow::SetDocShell(nsIDocShell* aDocShell)
mScreen->SetDocShell(aDocShell);
if (mDocShell) {
// tell our member elements about the new browserwindow
if (mMenubar) {
nsCOMPtr<nsIWebBrowserChrome> browserChrome;
GetWebBrowserChrome(getter_AddRefs(browserChrome));
mMenubar->SetWebBrowserChrome(browserChrome);
}
// Get our enclosing chrome shell and retrieve its global window impl, so
// that we can do some forwarding to the chrome document.
@ -2168,15 +2162,10 @@ nsGlobalWindow::GetMenubar(nsIDOMBarProp** aMenubar)
*aMenubar = nsnull;
if (!mMenubar) {
mMenubar = new nsMenubarProp();
mMenubar = new nsMenubarProp(this);
if (!mMenubar) {
return NS_ERROR_OUT_OF_MEMORY;
}
nsCOMPtr<nsIWebBrowserChrome> browserChrome;
GetWebBrowserChrome(getter_AddRefs(browserChrome));
mMenubar->SetWebBrowserChrome(browserChrome);
}
NS_ADDREF(*aMenubar = mMenubar);
@ -2192,15 +2181,10 @@ nsGlobalWindow::GetToolbar(nsIDOMBarProp** aToolbar)
*aToolbar = nsnull;
if (!mToolbar) {
mToolbar = new nsToolbarProp();
mToolbar = new nsToolbarProp(this);
if (!mToolbar) {
return NS_ERROR_OUT_OF_MEMORY;
}
nsCOMPtr<nsIWebBrowserChrome> browserChrome;
GetWebBrowserChrome(getter_AddRefs(browserChrome));
mToolbar->SetWebBrowserChrome(browserChrome);
}
NS_ADDREF(*aToolbar = mToolbar);
@ -2216,15 +2200,10 @@ nsGlobalWindow::GetLocationbar(nsIDOMBarProp** aLocationbar)
*aLocationbar = nsnull;
if (!mLocationbar) {
mLocationbar = new nsLocationbarProp();
mLocationbar = new nsLocationbarProp(this);
if (!mLocationbar) {
return NS_ERROR_OUT_OF_MEMORY;
}
nsCOMPtr<nsIWebBrowserChrome> browserChrome;
GetWebBrowserChrome(getter_AddRefs(browserChrome));
mLocationbar->SetWebBrowserChrome(browserChrome);
}
NS_ADDREF(*aLocationbar = mLocationbar);
@ -2240,15 +2219,10 @@ nsGlobalWindow::GetPersonalbar(nsIDOMBarProp** aPersonalbar)
*aPersonalbar = nsnull;
if (!mPersonalbar) {
mPersonalbar = new nsPersonalbarProp();
mPersonalbar = new nsPersonalbarProp(this);
if (!mPersonalbar) {
return NS_ERROR_OUT_OF_MEMORY;
}
nsCOMPtr<nsIWebBrowserChrome> browserChrome;
GetWebBrowserChrome(getter_AddRefs(browserChrome));
mPersonalbar->SetWebBrowserChrome(browserChrome);
}
NS_ADDREF(*aPersonalbar = mPersonalbar);
@ -2264,15 +2238,10 @@ nsGlobalWindow::GetStatusbar(nsIDOMBarProp** aStatusbar)
*aStatusbar = nsnull;
if (!mStatusbar) {
mStatusbar = new nsStatusbarProp();
mStatusbar = new nsStatusbarProp(this);
if (!mStatusbar) {
return NS_ERROR_OUT_OF_MEMORY;
}
nsCOMPtr<nsIWebBrowserChrome> browserChrome;
GetWebBrowserChrome(getter_AddRefs(browserChrome));
mStatusbar->SetWebBrowserChrome(browserChrome);
}
NS_ADDREF(*aStatusbar = mStatusbar);
@ -2292,11 +2261,6 @@ nsGlobalWindow::GetScrollbars(nsIDOMBarProp** aScrollbars)
if (!mScrollbars) {
return NS_ERROR_OUT_OF_MEMORY;
}
nsCOMPtr<nsIWebBrowserChrome> browserChrome;
GetWebBrowserChrome(getter_AddRefs(browserChrome));
mScrollbars->SetWebBrowserChrome(browserChrome);
}
NS_ADDREF(*aScrollbars = mScrollbars);
@ -2358,14 +2322,7 @@ nsGlobalWindow::GetCrypto(nsIDOMCrypto** aCrypto)
NS_IMETHODIMP
nsGlobalWindow::GetPkcs11(nsIDOMPkcs11** aPkcs11)
{
FORWARD_TO_OUTER(GetPkcs11, (aPkcs11), NS_ERROR_NOT_INITIALIZED);
if (!mPkcs11) {
mPkcs11 = do_CreateInstance(kPkcs11ContractID);
}
NS_IF_ADDREF(*aPkcs11 = mPkcs11);
*aPkcs11 = nsnull;
return NS_OK;
}
@ -3301,6 +3258,9 @@ nsGlobalWindow::EnsureReflowFlushAndPaint()
NS_ASSERTION(mDocShell, "EnsureReflowFlushAndPaint() called with no "
"docshell!");
if (!mDocShell)
return;
nsCOMPtr<nsIPresShell> presShell;
mDocShell->GetPresShell(getter_AddRefs(presShell));
@ -5153,6 +5113,7 @@ nsGlobalWindow::FindInternal(const nsAString& aStr, PRBool caseSensitive,
*aDidFind = PR_FALSE;
nsCOMPtr<nsIWebBrowserFind> finder(do_GetInterface(mDocShell));
NS_ENSURE_TRUE(finder, NS_ERROR_FAILURE);
// Set the options of the search
rv = finder->SetSearchString(PromiseFlatString(aStr).get());
@ -7920,6 +7881,10 @@ nsNavigator::nsNavigator(nsIDocShell *aDocShell)
nsNavigator::~nsNavigator()
{
sPrefInternal_id = JSVAL_VOID;
if (mMimeTypes)
mMimeTypes->Invalidate();
if (mPlugins)
mPlugins->Invalidate();
}
//*****************************************************************************
@ -8464,8 +8429,15 @@ nsNavigator::LoadingNewDocument()
// Release these so that they will be recreated for the
// new document (if requested). The plugins or mime types
// arrays may have changed. See bug 150087.
mMimeTypes = nsnull;
mPlugins = nsnull;
if (mMimeTypes) {
mMimeTypes->Invalidate();
mMimeTypes = nsnull;
}
if (mPlugins) {
mPlugins->Invalidate();
mPlugins = nsnull;
}
}
nsresult

View File

@ -82,7 +82,6 @@
#include "nsIEventListenerManager.h"
#include "nsIDOMDocument.h"
#include "nsIDOMCrypto.h"
#include "nsIDOMPkcs11.h"
#include "nsIPrincipal.h"
#include "nsPluginArray.h"
#include "nsMimeTypeArray.h"
@ -319,6 +318,8 @@ public:
friend class WindowStateHolder;
protected:
friend class nsBarProp;
// Object Management
virtual ~nsGlobalWindow();
void CleanUp();
@ -537,7 +538,6 @@ protected:
nsIScriptGlobalObjectOwner* mGlobalObjectOwner; // Weak Reference
nsIDocShell* mDocShell; // Weak Reference
nsCOMPtr<nsIDOMCrypto> mCrypto;
nsCOMPtr<nsIDOMPkcs11> mPkcs11;
nsCOMPtr<nsIDOMStorageList> gGlobalStorageList;

View File

@ -248,6 +248,13 @@ NS_ScriptErrorReporter(JSContext *cx,
} else {
errorevent.errorMsg = xoriginMsg.get();
errorevent.lineNr = 0;
// FIXME: once the principal of the script is not tied to
// the filename, we can stop using the post-redirect
// filename if we want and remove this line. Note that
// apparently we can't handle null filenames in the error
// event dispatching code.
static PRUnichar nullFilename[] = { PRUnichar(0) };
errorevent.fileName = nullFilename;
}
// HandleDOMEvent() must be synchronous for the recursion block

View File

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 sw=2 et tw=79: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@ -197,6 +198,9 @@ nsresult nsMimeTypeArray::GetMimeTypes()
{
NS_PRECONDITION(!mMimeTypeArray && mMimeTypeCount==0,
"already initialized");
if (!mNavigator) {
return NS_ERROR_NOT_AVAILABLE;
}
nsIDOMPluginArray* pluginArray = nsnull;
nsresult rv = mNavigator->GetPlugins(&pluginArray);
@ -225,14 +229,14 @@ nsresult nsMimeTypeArray::GetMimeTypes()
PRUint32 mimeTypeIndex = 0;
PRUint32 k;
for (k = 0; k < pluginCount; k++) {
nsIDOMPlugin* plugin = nsnull;
if (pluginArray->Item(k, &plugin) == NS_OK) {
nsCOMPtr<nsIDOMPlugin> plugin;
if (NS_SUCCEEDED(pluginArray->Item(k, getter_AddRefs(plugin))) &&
plugin) {
PRUint32 mimeTypeCount = 0;
if (plugin->GetLength(&mimeTypeCount) == NS_OK) {
for (PRUint32 j = 0; j < mimeTypeCount; j++)
plugin->Item(j, &mMimeTypeArray[mimeTypeIndex++]);
}
NS_RELEASE(plugin);
}
}
}

View File

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 sw=2 et tw=79: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@ -45,6 +46,8 @@
class nsIDOMNavigator;
// NB: Due to weak references, nsNavigator has intimate knowledge of our
// members.
class nsMimeTypeArray : public nsIDOMMimeTypeArray
{
public:
@ -58,6 +61,13 @@ public:
NS_IMETHOD NamedItem(const nsAString& aName, nsIDOMMimeType** aReturn);
nsresult Refresh();
void Invalidate()
{
// NB: This will cause GetMimeTypes to fail from now on.
mNavigator = nsnull;
Clear();
}
private:
nsresult GetMimeTypes();
void Clear();

View File

@ -181,11 +181,18 @@ nsPluginArray::GetPluginHost(nsIPluginHost** aPluginHost)
}
void
nsPluginArray::SetDocShell(nsIDocShell* aDocShell)
nsPluginArray::SetDocShell(nsIDocShell *aDocShell)
{
mDocShell = aDocShell;
}
void
nsPluginArray::Invalidate()
{
mDocShell = nsnull;
mNavigator = nsnull;
}
NS_IMETHODIMP
nsPluginArray::Refresh(PRBool aReloadDocuments)
{

View File

@ -47,6 +47,8 @@ class nsNavigator;
class nsIDocShell;
class nsIPluginHost;
// NB: Due to weak references, nsNavigator has intimate knowledge of our
// internals.
class nsPluginArray : public nsIDOMPluginArray,
public nsIDOMJSPluginArray
{
@ -69,7 +71,8 @@ private:
PRBool AllowPlugins();
public:
void SetDocShell(nsIDocShell* aDocShell);
void SetDocShell(nsIDocShell *aDocShell);
void Invalidate();
protected:
nsNavigator* mNavigator;

View File

@ -1125,9 +1125,10 @@ nsEditingSession::EndDocumentLoad(nsIWebProgress *aWebProgress,
if (NS_FAILED(rv)) return rv;
mEditorStatus = eEditorCreationInProgress;
mDocShell = do_GetWeakReference(docShell);
mLoadBlankDocTimer->InitWithFuncCallback(
nsEditingSession::TimerCallback,
(void*)docShell,
static_cast<void*> (mDocShell.get()),
10, nsITimer::TYPE_ONE_SHOT);
}
}
@ -1139,7 +1140,7 @@ nsEditingSession::EndDocumentLoad(nsIWebProgress *aWebProgress,
void
nsEditingSession::TimerCallback(nsITimer* aTimer, void* aClosure)
{
nsCOMPtr<nsIDocShell> docShell = (nsIDocShell*)aClosure;
nsCOMPtr<nsIDocShell> docShell = do_QueryReferent(static_cast<nsIWeakReference*> (aClosure));
if (docShell)
{
nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(docShell));

View File

@ -163,6 +163,9 @@ protected:
PRUint32 mBaseCommandControllerId;
PRUint32 mDocStateControllerId;
PRUint32 mHTMLCommandControllerId;
// Make sure the docshell we use is safe
nsWeakPtr mDocShell;
};

View File

@ -982,12 +982,12 @@ nsEditor::BeginPlaceHolderTransaction(nsIAtom *aName)
mPlaceHolderName = aName;
nsCOMPtr<nsISelection> selection;
nsresult res = GetSelection(getter_AddRefs(selection));
if (NS_FAILED(res)) return res;
mSelState = new nsSelectionState();
if (!mSelState)
return NS_ERROR_OUT_OF_MEMORY;
mSelState->SaveSelection(selection);
if (NS_SUCCEEDED(res)) {
mSelState = new nsSelectionState();
if (mSelState) {
mSelState->SaveSelection(selection);
}
}
}
mPlaceHolderBatch++;

View File

@ -201,6 +201,12 @@ nsTextEditRules::BeforeEdit(PRInt32 action, nsIEditor::EDirection aDirection)
nsAutoLockRulesSniffing lockIt(this);
mDidExplicitlySetInterline = PR_FALSE;
if (!mActionNesting)
{
// let rules remember the top level action
mTheAction = action;
}
mActionNesting++;
// get the selection and cache the position before editing
nsCOMPtr<nsISelection> selection;
@ -211,12 +217,6 @@ nsTextEditRules::BeforeEdit(PRInt32 action, nsIEditor::EDirection aDirection)
selection->GetAnchorNode(getter_AddRefs(mCachedSelectionNode));
selection->GetAnchorOffset(&mCachedSelectionOffset);
if (!mActionNesting)
{
// let rules remember the top level action
mTheAction = action;
}
mActionNesting++;
return NS_OK;
}

View File

@ -652,6 +652,8 @@ nsPromptService::DoDialog(nsIDOMWindow *aParent,
aParent = activeParent;
}
aParamBlock->SetInt(eButtonPressed, 1);
nsCOMPtr<nsISupports> arguments(do_QueryInterface(aParamBlock));
nsCOMPtr<nsIDOMWindow> dialog;
rv = mWatcher->OpenWindow(aParent, aChromeURL, "_blank",

View File

@ -169,7 +169,8 @@ protected:
/*
* Evaluates the given Expression and converts its result to a number.
*/
double evaluateToNumber(Expr* aExpr, txIEvalContext* aContext);
static nsresult evaluateToNumber(Expr* aExpr, txIEvalContext* aContext,
double* aResult);
/*
* Evaluates the given Expression and converts its result to a boolean.

View File

@ -99,15 +99,19 @@ void FunctionCall::evaluateToString(Expr* aExpr, txIEvalContext* aContext,
/*
* Evaluates the given Expression and converts its result to a number.
*/
double FunctionCall::evaluateToNumber(Expr* aExpr, txIEvalContext* aContext)
// static
nsresult
FunctionCall::evaluateToNumber(Expr* aExpr, txIEvalContext* aContext,
double* aResult)
{
NS_ASSERTION(aExpr, "missing expression");
nsRefPtr<txAExprResult> exprResult;
nsresult rv = aExpr->evaluate(aContext, getter_AddRefs(exprResult));
if (NS_FAILED(rv))
return Double::NaN;
NS_ENSURE_SUCCESS(rv, rv);
return exprResult->numberValue();
*aResult = exprResult->numberValue();
return NS_OK;
}
/*

View File

@ -79,7 +79,10 @@ NumberFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
switch (mType) {
case CEILING:
{
double dbl = evaluateToNumber((Expr*)iter.next(), aContext);
double dbl;
nsresult rv = evaluateToNumber((Expr*)iter.next(), aContext, &dbl);
NS_ENSURE_SUCCESS(rv, rv);
if (!Double::isNaN(dbl) && !Double::isInfinite(dbl)) {
if (Double::isNeg(dbl) && dbl > -1) {
dbl *= 0;
@ -93,7 +96,10 @@ NumberFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
}
case FLOOR:
{
double dbl = evaluateToNumber((Expr*)iter.next(), aContext);
double dbl;
nsresult rv = evaluateToNumber((Expr*)iter.next(), aContext, &dbl);
NS_ENSURE_SUCCESS(rv, rv);
if (!Double::isNaN(dbl) &&
!Double::isInfinite(dbl) &&
!(dbl == 0 && Double::isNeg(dbl))) {
@ -104,7 +110,10 @@ NumberFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
}
case ROUND:
{
double dbl = evaluateToNumber((Expr*)iter.next(), aContext);
double dbl;
nsresult rv = evaluateToNumber((Expr*)iter.next(), aContext, &dbl);
NS_ENSURE_SUCCESS(rv, rv);
if (!Double::isNaN(dbl) && !Double::isInfinite(dbl)) {
if (Double::isNeg(dbl) && dbl >= -0.5) {
dbl *= 0;
@ -136,7 +145,8 @@ NumberFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
{
double res;
if (iter.hasNext()) {
res = evaluateToNumber((Expr*)iter.next(), aContext);
nsresult rv = evaluateToNumber((Expr*)iter.next(), aContext, &res);
NS_ENSURE_SUCCESS(rv, rv);
}
else {
nsAutoString resultStr;

View File

@ -193,7 +193,8 @@ StringFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
nsAutoString src;
double start, end;
evaluateToString((Expr*)iter.next(), aContext, src);
start = evaluateToNumber((Expr*)iter.next(), aContext);
rv = evaluateToNumber((Expr*)iter.next(), aContext, &start);
NS_ENSURE_SUCCESS(rv, rv);
// check for NaN or +/-Inf
if (Double::isNaN(start) ||
@ -206,8 +207,10 @@ StringFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
start = floor(start + 0.5) - 1;
if (iter.hasNext()) {
end = start + evaluateToNumber((Expr*)iter.next(),
aContext);
rv = evaluateToNumber((Expr*)iter.next(), aContext, &end);
NS_ENSURE_SUCCESS(rv, rv);
end += start;
if (Double::isNaN(end) || end < 0) {
aContext->recycler()->getEmptyStringResult(aResult);

View File

@ -625,8 +625,8 @@ XFormsFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT;
double result = 0;
double base = evaluateToNumber((Expr*)iter.next(), aContext);
double exponent = evaluateToNumber((Expr*)iter.next(), aContext);
double base = evaluateToNumber((Expr*)iter.next(), aContext, &result);
double exponent = evaluateToNumber((Expr*)iter.next(), aContext, &result);
// If base is negative and exponent is not an integral value, or if base
// is zero and exponent is negative, a domain error occurs, setting the
@ -712,7 +712,8 @@ XFormsFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
if (!requireParams(1, 1, aContext))
return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT;
double days = evaluateToNumber((Expr*)iter.next(), aContext);
double res;
double days = evaluateToNumber((Expr*)iter.next(), aContext, &res);
nsAutoString date;
if (!Double::isNaN(days)) {
@ -745,7 +746,8 @@ XFormsFunctionCall::evaluate(txIEvalContext* aContext, txAExprResult** aResult)
if (!requireParams(1, 1, aContext))
return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT;
double seconds = evaluateToNumber((Expr*)iter.next(), aContext);
double res;
double seconds = evaluateToNumber((Expr*)iter.next(), aContext, &res);
nsAutoString dateTime;
if (!Double::isNaN(seconds)) {

View File

@ -89,7 +89,9 @@ txFormatNumberFunctionCall::evaluate(txIEvalContext* aContext,
nsAutoString formatStr;
txExpandedName formatName;
value = evaluateToNumber((Expr*)iter.next(), aContext);
rv = evaluateToNumber((Expr*)iter.next(), aContext, &value);
NS_ENSURE_SUCCESS(rv, rv);
evaluateToString((Expr*)iter.next(), aContext, formatStr);
if (iter.hasNext()) {
nsAutoString formatQName;

View File

@ -416,10 +416,10 @@ nsresult txXSLKey::testNode(const txXPathNode& aNode,
nsRefPtr<txAExprResult> exprResult;
rv = key->useExpr->evaluate(evalContext,
getter_AddRefs(exprResult));
NS_ENSURE_SUCCESS(rv, rv);
delete aEs.popEvalContext();
NS_ENSURE_SUCCESS(rv, rv);
if (exprResult->getResultType() == txAExprResult::NODESET) {
txNodeSet* res = NS_STATIC_CAST(txNodeSet*,
NS_STATIC_CAST(txAExprResult*,

View File

@ -100,10 +100,13 @@ txExecutionState::txExecutionState(txStylesheet* aStylesheet,
mKeyHash(aStylesheet->getKeyMap()),
mDisableLoads(aDisableLoads)
{
MOZ_COUNT_CTOR(txExecutionState);
}
txExecutionState::~txExecutionState()
{
MOZ_COUNT_DTOR(txExecutionState);
delete mResultHandler;
delete mLocalVariables;
delete mEvalContext;
@ -203,7 +206,11 @@ txExecutionState::init(const txXPathNode& aNode,
nsresult
txExecutionState::end(nsresult aResult)
{
popTemplateRule();
NS_ASSERTION(NS_FAILED(aResult) || mTemplateRuleCount == 1,
"Didn't clean up template rules properly");
if (NS_SUCCEEDED(aResult)) {
popTemplateRule();
}
mOutputHandler->endDocument(aResult);
return NS_OK;
@ -276,9 +283,9 @@ txExecutionState::getVariable(PRInt32 aNamespace, nsIAtom* aLName,
txVariableMap* oldVars = mLocalVariables;
mLocalVariables = nsnull;
rv = var->mExpr->evaluate(getEvalContext(), &aResult);
NS_ENSURE_SUCCESS(rv, rv);
mLocalVariables = oldVars;
NS_ENSURE_SUCCESS(rv, rv);
}
else {
nsAutoPtr<txRtfHandler> rtfHandler(new txRtfHandler);
@ -448,9 +455,12 @@ txExecutionState::pushTemplateRule(txStylesheet::ImportFrame* aFrame,
void
txExecutionState::popTemplateRule()
{
NS_PRECONDITION(mTemplateRuleCount > 0, "No rules to pop");
// decrement outside of RELEASE, that would decrement twice
--mTemplateRuleCount;
NS_IF_RELEASE(mTemplateRules[mTemplateRuleCount].mModeLocalName);
if(mTemplateRuleCount > 0) {
--mTemplateRuleCount;
NS_IF_RELEASE(mTemplateRules[mTemplateRuleCount].mModeLocalName);
}
}
txIEvalContext*
@ -514,7 +524,9 @@ txExecutionState::getKeyNodes(const txExpandedName& aKeyName,
txExecutionState::TemplateRule*
txExecutionState::getCurrentTemplateRule()
{
return mTemplateRules + mTemplateRuleCount - 1;
NS_PRECONDITION(mTemplateRuleCount > 0, "No current rule!");
// better to crash that underrun
return mTemplateRuleCount > 0 ? mTemplateRules + mTemplateRuleCount - 1 : NULL;
}
txInstruction*

View File

@ -634,10 +634,12 @@ txMozillaXSLTProcessor::TransformToDoc(nsIDOMDocument *aOutputDoc,
mObserver);
es.mOutputHandlerFactory = &handlerFactory;
es.init(*sourceNode, &mVariables);
nsresult rv = es.init(*sourceNode, &mVariables);
// Process root of XML source document
nsresult rv = txXSLTProcessor::execute(es);
if (NS_SUCCEEDED(rv)) {
rv = txXSLTProcessor::execute(es);
}
es.end(rv);
if (NS_SUCCEEDED(rv)) {
if (aResult) {
@ -686,10 +688,12 @@ txMozillaXSLTProcessor::TransformToFragment(nsIDOMNode *aSource,
txToFragmentHandlerFactory handlerFactory(*aResult);
es.mOutputHandlerFactory = &handlerFactory;
es.init(*sourceNode, &mVariables);
rv = es.init(*sourceNode, &mVariables);
// Process root of XML source document
rv = txXSLTProcessor::execute(es);
if (NS_SUCCEEDED(rv)) {
rv = txXSLTProcessor::execute(es);
}
// XXX setup exception context, bug 204658
es.end(rv);

View File

@ -64,11 +64,14 @@ inline
txVariableMap::txVariableMap()
: mMap(MB_FALSE)
{
MOZ_COUNT_CTOR(txVariableMap);
}
inline
txVariableMap::~txVariableMap()
{
MOZ_COUNT_DTOR(txVariableMap);
txExpandedNameMap::iterator iter(mMap);
while (iter.next()) {
txAExprResult* res = NS_STATIC_CAST(txAExprResult*, iter.value());

View File

@ -190,7 +190,15 @@ txNodeSorter::sortNodeSet(txNodeSet* aNodes, txExecutionState* aEs,
// Create and set up memoryblock for sort-values and indexarray
PRUint32 len = NS_STATIC_CAST(PRUint32, aNodes->size());
void* mem = PR_Malloc(len * (sizeof(PRUint32) + mNKeys * sizeof(TxObject*)));
// Don't overflow when calculating the length of the sort buffer.
PRUint32 itemSize = sizeof(PRUint32) + mNKeys * sizeof(TxObject*);
if (mNKeys > (PR_UINT32_MAX - sizeof(PRUint32)) / sizeof(TxObject*) ||
len >= PR_UINT32_MAX / itemSize) {
return NS_ERROR_OUT_OF_MEMORY;
}
void* mem = PR_Malloc(len * itemSize);
NS_ENSURE_TRUE(mem, NS_ERROR_OUT_OF_MEMORY);
PRUint32* indexes = NS_STATIC_CAST(PRUint32*, mem);

View File

@ -255,7 +255,8 @@ nsConverterInputStream::Fill(nsresult * aErrorCode)
NS_ASSERTION(srcConsumed <= mByteData->GetLength(),
"Whoa. The converter should have returned NS_OK_UDEC_MOREINPUT before this point!");
} while (mReplacementChar &&
NS_FAILED(*aErrorCode));
NS_FAILED(*aErrorCode) &&
mUnicharData->GetBufferSize() > mUnicharDataLength);
mLeftOverBytes = mByteData->GetLength() - srcConsumed;

View File

@ -64,6 +64,15 @@ NS_IMETHODIMP NS_NewUTF8ToUnicode(nsISupports* aOuter,
return res;
}
static PRUnichar* EmitSurrogatePair(PRUint32 ucs4, PRUnichar* aDest)
{
NS_ASSERTION(ucs4 > 0xFFFF, "Should be a supplementary character");
ucs4 -= 0x00010000;
*aDest++ = 0xD800 | (0x000003FF & (ucs4 >> 10));
*aDest++ = 0xDC00 | (0x000003FF & ucs4);
return aDest;
}
//----------------------------------------------------------------------
// Class nsUTF8ToUnicode [implementation]
@ -136,12 +145,28 @@ NS_IMETHODIMP nsUTF8ToUnicode::Convert(const char * aSrc,
nsresult res = NS_OK; // conversion result
out = aDest;
if (mState == 0xFF) {
// Emit supplementary character left over from previous iteration. If the
// buffer size is insufficient, treat it as an illegal character.
if (aDestLen < 2) {
NS_ERROR("Output buffer insufficient to hold supplementary character");
mState = 0;
return NS_ERROR_ILLEGAL_INPUT;
}
out = EmitSurrogatePair(mUcs4, out);
mUcs4 = 0;
mState = 0;
mBytes = 1;
mFirst = PR_FALSE;
}
// Set mFirst to PR_FALSE now so we don't have to every time through the ASCII
// branch within the loop.
if (mFirst && aSrcLen && (0 == (0x80 & (*aSrc))))
mFirst = PR_FALSE;
for (in = aSrc, out = aDest; ((in < inend) && (out < outend)); ++in) {
for (in = aSrc; ((in < inend) && (out < outend)); ++in) {
if (0 == mState) {
// When mState is zero we expect either a US-ASCII character or a
// multi-octet sequence.
@ -227,9 +252,15 @@ NS_IMETHODIMP nsUTF8ToUnicode::Convert(const char * aSrc,
}
if (mUcs4 > 0xFFFF) {
// mUcs4 is in the range 0x10000 - 0x10FFFF. Output a UTF-16 pair
mUcs4 -= 0x00010000;
*out++ = 0xD800 | (0x000003FF & (mUcs4 >> 10));
*out++ = 0xDC00 | (0x000003FF & mUcs4);
if (out + 2 > outend) {
// insufficient space left in the buffer. Keep mUcs4 for the
// next iteration.
mState = 0xFF;
++in;
res = NS_OK_UDEC_MOREOUTPUT;
break;
}
out = EmitSurrogatePair(mUcs4, out);
} else if (UNICODE_BYTE_ORDER_MARK != mUcs4 || !mFirst) {
// Don't output the BOM only if it is the first character
*out++ = mUcs4;

View File

@ -206,8 +206,7 @@ NS_IMETHODIMP nsGBKToUnicode::ConvertNoBuff(const char* aSrc,
*aDest = UCS2_NO_MAPPING;
} else {
// let's try supplement mapping
NS_ASSERTION(( (iDestlen+1) <= (*aDestLength) ), "no enouth output memory");
if ( (iDestlen+1) <= (*aDestLength) )
if ( (iDestlen+1) < (*aDestLength) )
{
if(DecodeToSurrogate(aSrc, aDest))
{
@ -218,7 +217,13 @@ NS_IMETHODIMP nsGBKToUnicode::ConvertNoBuff(const char* aSrc,
*aDest = UCS2_NO_MAPPING;
}
} else {
*aDest = UCS2_NO_MAPPING;
if (*aDestLength < 2) {
NS_ERROR("insufficient space in output buffer");
*aDest = UCS2_NO_MAPPING;
} else {
rv = NS_OK_UDEC_MOREOUTPUT;
break;
}
}
}
} else {

View File

@ -50,6 +50,8 @@ static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CI
#define SJIS_INDEX mMapIndex[0]
#define JIS0208_INDEX mMapIndex[1]
#define JIS0212_INDEX gJIS0212Index
#define SJIS_UNMAPPED 0x30FB
#define UNICODE_REPLACEMENT_CHARACTER 0xfffd
void nsJapaneseToUnicode::setMapMode()
{
@ -153,7 +155,7 @@ NS_IMETHODIMP nsShiftJISToUnicode::Convert(
break;
default:
*dest++ = 0x30FB;
*dest++ = SJIS_UNMAPPED;
}
if(dest >= destEnd)
goto error1;
@ -176,13 +178,20 @@ NS_IMETHODIMP nsShiftJISToUnicode::Convert(
case 1: // Index to table
{
// Error handling: in the case where the second octet is not in the
// valid ranges 0x40-0x7E 0x80-0xFC, unconsume the invalid octet and
// interpret it as the ASCII value. In the case where the second
// octet is in the valid range but there is no mapping for the
// 2-octet sequence, do not unconsume.
PRUint8 off = sbIdx[*src];
if(0xFF == off) {
*dest++ = 0x30FB;
src--;
*dest++ = UNICODE_REPLACEMENT_CHARACTER;
} else {
PRUnichar ch = gJapaneseMap[mData+off];
if(ch == 0xfffd)
ch = 0x30fb;
ch = SJIS_UNMAPPED;
*dest++ = ch;
}
mState = 0;
@ -194,8 +203,10 @@ NS_IMETHODIMP nsShiftJISToUnicode::Convert(
case 2: // EUDC
{
PRUint8 off = sbIdx[*src];
// Error handling as in case 1
if(0xFF == off) {
*dest++ = 0x30fb;
src--;
*dest++ = UNICODE_REPLACEMENT_CHARACTER;
} else {
*dest++ = mData + off;
}
@ -322,10 +333,10 @@ NS_IMETHODIMP nsEUCJPToUnicodeV2::Convert(
if(0xFF == off) {
*dest++ = 0xFFFD;
// if the first byte is valid for EUC-JP but the second
// is not while being a valid US-ASCII(i.e. < 0xc0), save it
// is not while being a valid US-ASCII, save it
// instead of eating it up !
if ( ! (*src & 0xc0) )
*dest++ = (PRUnichar) *src;;
if ( (PRUint8)*src < (PRUint8)0x7f )
--src;
} else {
*dest++ = gJapaneseMap[mData+off];
}
@ -344,7 +355,7 @@ NS_IMETHODIMP nsEUCJPToUnicodeV2::Convert(
// if 0x8e is not followed by a valid JIS X 0201 byte
// but by a valid US-ASCII, save it instead of eating it up.
if ( (PRUint8)*src < (PRUint8)0x7f )
*dest++ = (PRUnichar) *src;
--src;
}
mState = 0;
if(dest >= destEnd)

View File

@ -42,14 +42,16 @@
#include <string.h>
#include "prtypes.h"
#define STATE_NORMAL 0
#define STATE_HALF_CODE_POINT 1
#define STATE_FIRST_CALL 2
#define STATE_FOUND_BOM 3
#define STATE_NORMAL 0
#define STATE_HALF_CODE_POINT 1
#define STATE_FIRST_CALL 2
#define STATE_FOUND_BOM 3
#define STATE_ODD_SURROGATE_PAIR 4
static nsresult
UTF16ConvertToUnicode(PRUint8& aState, PRUint8& aOddByte,
PRUnichar& aOddHighSurrogate, const char * aSrc,
PRUnichar& aOddHighSurrogate, PRUnichar& aOddLowSurrogate,
const char * aSrc,
PRInt32 * aSrcLength, PRUnichar * aDest,
PRInt32 * aDestLength,
PRBool aSwapBytes)
@ -59,32 +61,47 @@ UTF16ConvertToUnicode(PRUint8& aState, PRUint8& aOddByte,
PRUnichar* dest = aDest;
PRUnichar* destEnd = aDest + *aDestLength;
if(STATE_FOUND_BOM == aState) // caller found a BOM
{
if (*aSrcLength < 2)
return NS_ERROR_ILLEGAL_INPUT;
src+=2;
aState = STATE_NORMAL;
} else if(STATE_FIRST_CALL == aState) { // first time called
if (*aSrcLength < 2)
return NS_ERROR_ILLEGAL_INPUT;
// Eliminate BOM (0xFEFF). Note that different endian case is taken care of
// in |Convert| of LE and BE converters. Here, we only have to
// deal with the same endian case. That is, 0xFFFE (byte-swapped BOM) is
// illegal.
if(0xFEFF == *((PRUnichar*)src)) {
switch(aState) {
case STATE_FOUND_BOM:
NS_ASSERTION(*aSrcLength > 1, "buffer too short");
src+=2;
} else if(0xFFFE == *((PRUnichar*)src)) {
*aSrcLength=0;
*aDestLength=0;
return NS_ERROR_ILLEGAL_INPUT;
}
aState = STATE_NORMAL;
aState = STATE_NORMAL;
break;
case STATE_FIRST_CALL: // first time called
NS_ASSERTION(*aSrcLength > 1, "buffer too short");
// Eliminate BOM (0xFEFF). Note that different endian case is taken care
// of in |Convert| of LE and BE converters. Here, we only have to
// deal with the same endian case. That is, 0xFFFE (byte-swapped BOM) is
// illegal.
if(0xFEFF == *((PRUnichar*)src)) {
src+=2;
} else if(0xFFFE == *((PRUnichar*)src)) {
*aSrcLength=0;
*aDestLength=0;
return NS_ERROR_ILLEGAL_INPUT;
}
aState = STATE_NORMAL;
break;
case STATE_ODD_SURROGATE_PAIR:
if (*aDestLength < 2)
*dest++ = UCS2_REPLACEMENT_CHAR;
else {
*dest++ = aOddHighSurrogate;
*dest++ = aOddLowSurrogate;
aOddHighSurrogate = aOddLowSurrogate = 0;
aState = STATE_NORMAL;
}
break;
case STATE_NORMAL:
case STATE_HALF_CODE_POINT:
default:
break;
}
if (src == srcEnd) {
*aDestLength = 0;
*aDestLength = dest - aDest;
return NS_OK;
}
@ -136,17 +153,19 @@ have_codepoint:
oddHighSurrogate = u;
}
else /* if (IS_LOW_SURROGATE(u)) */ {
if (oddHighSurrogate) {
if (dest == destEnd - 1) {
*dest++ = UCS2_REPLACEMENT_CHAR;
if (oddHighSurrogate && *aDestLength > 1) {
if (dest + 1 >= destEnd) {
aOddLowSurrogate = u;
aOddHighSurrogate = oddHighSurrogate;
aState = STATE_ODD_SURROGATE_PAIR;
goto error;
}
*dest++ = oddHighSurrogate;
*dest++ = u;
oddHighSurrogate = 0;
} else {
*dest++ = UCS2_REPLACEMENT_CHAR;
}
oddHighSurrogate = 0;
}
}
if (src != srcEnd) {
@ -173,6 +192,7 @@ nsUTF16ToUnicodeBase::Reset()
mState = STATE_FIRST_CALL;
mOddByte = 0;
mOddHighSurrogate = 0;
mOddLowSurrogate = 0;
return NS_OK;
}
@ -181,9 +201,11 @@ nsUTF16ToUnicodeBase::GetMaxLength(const char * aSrc, PRInt32 aSrcLength,
PRInt32 * aDestLength)
{
// the left-over data of the previous run have to be taken into account.
*aDestLength = (aSrcLength +
((STATE_HALF_CODE_POINT == mState) ? 1 : 0)) / 2 +
((mOddHighSurrogate != 0) ? 1 : 0);
*aDestLength = (aSrcLength + ((STATE_HALF_CODE_POINT == mState) ? 1 : 0)) / 2;
if (mOddHighSurrogate)
(*aDestLength)++;
if (mOddLowSurrogate)
(*aDestLength)++;
return NS_OK;
}
@ -192,14 +214,19 @@ NS_IMETHODIMP
nsUTF16BEToUnicode::Convert(const char * aSrc, PRInt32 * aSrcLength,
PRUnichar * aDest, PRInt32 * aDestLength)
{
if(STATE_FIRST_CALL == mState && *aSrcLength < 2)
{
nsresult res = (*aSrcLength == 0) ? NS_OK : NS_ERROR_ILLEGAL_INPUT;
*aSrcLength=0;
*aDestLength=0;
return res;
}
#ifdef IS_LITTLE_ENDIAN
// Remove the BOM if we're little-endian. The 'same endian' case with the
// leading BOM will be taken care of by |UTF16ConvertToUnicode|.
if(STATE_FIRST_CALL == mState) // Called for the first time.
{
mState = STATE_NORMAL;
if (*aSrcLength < 2)
return NS_ERROR_ILLEGAL_INPUT;
if(0xFFFE == *((PRUnichar*)aSrc)) {
// eliminate BOM (on LE machines, BE BOM is 0xFFFE)
mState = STATE_FOUND_BOM;
@ -212,6 +239,7 @@ nsUTF16BEToUnicode::Convert(const char * aSrc, PRInt32 * aSrcLength,
#endif
nsresult rv = UTF16ConvertToUnicode(mState, mOddByte, mOddHighSurrogate,
mOddLowSurrogate,
aSrc, aSrcLength, aDest, aDestLength,
#ifdef IS_LITTLE_ENDIAN
PR_TRUE
@ -226,14 +254,19 @@ NS_IMETHODIMP
nsUTF16LEToUnicode::Convert(const char * aSrc, PRInt32 * aSrcLength,
PRUnichar * aDest, PRInt32 * aDestLength)
{
if(STATE_FIRST_CALL == mState && *aSrcLength < 2)
{
nsresult res = (*aSrcLength == 0) ? NS_OK : NS_ERROR_ILLEGAL_INPUT;
*aSrcLength=0;
*aDestLength=0;
return res;
}
#ifdef IS_BIG_ENDIAN
// Remove the BOM if we're big-endian. The 'same endian' case with the
// leading BOM will be taken care of by |UTF16ConvertToUnicode|.
if(STATE_FIRST_CALL == mState) // first time called
{
mState = STATE_NORMAL;
if (*aSrcLength < 2)
return NS_ERROR_ILLEGAL_INPUT;
if(0xFFFE == *((PRUnichar*)aSrc)) {
// eliminate BOM (on BE machines, LE BOM is 0xFFFE)
mState = STATE_FOUND_BOM;
@ -246,6 +279,7 @@ nsUTF16LEToUnicode::Convert(const char * aSrc, PRInt32 * aSrcLength,
#endif
nsresult rv = UTF16ConvertToUnicode(mState, mOddByte, mOddHighSurrogate,
mOddLowSurrogate,
aSrc, aSrcLength, aDest, aDestLength,
#ifdef IS_BIG_ENDIAN
PR_TRUE
@ -268,12 +302,16 @@ NS_IMETHODIMP
nsUTF16ToUnicode::Convert(const char * aSrc, PRInt32 * aSrcLength,
PRUnichar * aDest, PRInt32 * aDestLength)
{
if(STATE_FIRST_CALL == mState && *aSrcLength < 2)
{
nsresult res = (*aSrcLength == 0) ? NS_OK : NS_ERROR_ILLEGAL_INPUT;
*aSrcLength=0;
*aDestLength=0;
return res;
}
if(STATE_FIRST_CALL == mState) // first time called
{
mState = STATE_NORMAL;
if (*aSrcLength < 2)
return NS_ERROR_ILLEGAL_INPUT;
// check if BOM (0xFEFF) is at the beginning, remove it if found, and
// set mEndian accordingly.
if(0xFF == PRUint8(aSrc[0]) && 0xFE == PRUint8(aSrc[1])) {
@ -304,6 +342,7 @@ nsUTF16ToUnicode::Convert(const char * aSrc, PRInt32 * aSrcLength,
}
nsresult rv = UTF16ConvertToUnicode(mState, mOddByte, mOddHighSurrogate,
mOddLowSurrogate,
aSrc, aSrcLength, aDest, aDestLength,
#ifdef IS_BIG_ENDIAN
(mEndian == kLittleEndian)

View File

@ -62,6 +62,8 @@ protected:
PRUint8 mOddByte;
// to store an odd high surrogate left over between runs
PRUnichar mOddHighSurrogate;
// to store an odd low surrogate left over between runs
PRUnichar mOddLowSurrogate;
};
// UTF-16 big endian

View File

@ -4829,7 +4829,7 @@ JS_SetRegExpInput(JSContext *cx, JSString *input, JSBool multiline)
CHECK_REQUEST(cx);
/* No locking required, cx is thread-private and input must be live. */
res = &cx->regExpStatics;
res->input = input;
res->pendingInput = input;
res->multiline = multiline;
cx->runtime->gcPoke = JS_TRUE;
}
@ -4841,11 +4841,7 @@ JS_ClearRegExpStatics(JSContext *cx)
/* No locking required, cx is thread-private and input must be live. */
res = &cx->regExpStatics;
res->input = NULL;
res->multiline = JS_FALSE;
res->parenCount = 0;
res->lastMatch = res->lastParen = js_EmptySubString;
res->leftContext = res->rightContext = js_EmptySubString;
js_RegExpStatics_clear(cx, res);
cx->runtime->gcPoke = JS_TRUE;
}
@ -4857,6 +4853,7 @@ JS_ClearRegExpRoots(JSContext *cx)
/* No locking required, cx is thread-private and input must be live. */
res = &cx->regExpStatics;
res->input = NULL;
res->pendingInput = NULL;
cx->runtime->gcPoke = JS_TRUE;
}

View File

@ -190,6 +190,25 @@ js_FloorLog2wImpl(JSUword n);
#endif
/*
* Macros for rotate left. There is no rotate operation in the C Language so
* the construct (a << 4) | (a >> 28) is used instead. Most compilers convert
* this to a rotate instruction but some versions of MSVC don't without a
* little help. To get MSVC to generate a rotate instruction, we have to use
* the _rotl intrinsic and use a pragma to make _rotl inline.
*
* MSVC in VS2005 will do an inline rotate instruction on the above construct.
*/
#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || \
defined(_M_X64))
#include <stdlib.h>
#pragma intrinsic(_rotl)
#define JS_ROTATE_LEFT32(a, bits) _rotl(a, bits)
#else
#define JS_ROTATE_LEFT32(a, bits) (((a) << (bits)) | ((a) >> (32 - (bits))))
#endif
JS_END_EXTERN_C
#endif /* jsbit_h___ */

View File

@ -912,7 +912,7 @@ typedef enum JSErrNum {
JSErr_Limit
} JSErrNum;
extern const JSErrorFormatString *
extern JS_PUBLIC_API(const JSErrorFormatString *)
js_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber);
#ifdef va_start

View File

@ -587,21 +587,23 @@ JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsval id,
attrs = sprop->attrs;
flags = sprop->flags;
shortid = sprop->shortid;
JS_UNLOCK_OBJ(cx, pobj);
} else {
if (!OBJ_GET_PROPERTY(cx, pobj, id, &value) ||
!OBJ_GET_ATTRIBUTES(cx, pobj, id, prop, &attrs)) {
OBJ_DROP_PROPERTY(cx, pobj, prop);
OBJ_DROP_PROPERTY(cx, pobj, prop);
if (!OBJ_GET_PROPERTY(cx, pobj, propid, &value) ||
!OBJ_GET_ATTRIBUTES(cx, pobj, propid, NULL, &attrs)) {
return JS_FALSE;
}
getter = setter = NULL;
flags = 0;
shortid = 0;
}
OBJ_DROP_PROPERTY(cx, pobj, prop);
/* Recall that obj is native, whether or not pobj is native. */
if (!js_DefineNativeProperty(cx, obj, propid, value, getter, setter,
attrs, flags, shortid, &prop)) {
if (!js_DefineNativeProperty(cx, obj, propid, value,
getter, setter, attrs, flags,
shortid, &prop)) {
return JS_FALSE;
}
sprop = (JSScopeProperty *) prop;

View File

@ -431,9 +431,7 @@ MarkSharpObjects(JSContext *cx, JSObject *obj, JSIdArray **idap)
#if JS_HAS_GETTER_SETTER
JSObject *obj2;
JSProperty *prop;
uintN attrs;
#endif
jsval val;
int stackDummy;
if (!JS_CHECK_STACK_SIZE(cx, stackDummy)) {
@ -469,44 +467,60 @@ MarkSharpObjects(JSContext *cx, JSObject *obj, JSIdArray **idap)
ok = JS_TRUE;
for (i = 0, length = ida->length; i < length; i++) {
JSTempValueRooter v;
JSTempValueRooter setter;
PRBool hasGetter, hasSetter;
id = ida->vector[i];
JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_VOID, &v);
#if JS_HAS_GETTER_SETTER
ok = OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop);
if (!ok)
break;
goto brk;
if (!prop)
continue;
ok = OBJ_GET_ATTRIBUTES(cx, obj2, id, prop, &attrs);
if (ok) {
if (OBJ_IS_NATIVE(obj2) &&
(attrs & (JSPROP_GETTER | JSPROP_SETTER))) {
val = JSVAL_NULL;
if (attrs & JSPROP_GETTER)
val = (jsval) ((JSScopeProperty*)prop)->getter;
if (attrs & JSPROP_SETTER) {
if (val != JSVAL_NULL) {
/* Mark the getter, then set val to setter. */
ok = (MarkSharpObjects(cx, JSVAL_TO_OBJECT(val),
NULL)
!= NULL);
}
val = (jsval) ((JSScopeProperty*)prop)->setter;
}
} else {
ok = OBJ_GET_PROPERTY(cx, obj, id, &val);
}
goto cont;
JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_VOID, &setter);
if (!OBJ_IS_NATIVE(obj2)) {
OBJ_DROP_PROPERTY(cx, obj2, prop);
hasGetter = hasSetter = PR_FALSE;
} else {
JSScopeProperty *sprop = (JSScopeProperty *) prop;
uintN attrs = sprop->attrs;
hasGetter = (attrs & JSPROP_GETTER);
hasSetter = (attrs & JSPROP_SETTER);
if (hasGetter)
v.u.value = (jsval) ((JSScopeProperty*)sprop)->getter;
if (hasSetter)
setter.u.value = (jsval) ((JSScopeProperty*)sprop)->setter;
JS_UNLOCK_OBJ(cx, obj2);
}
OBJ_DROP_PROPERTY(cx, obj2, prop);
if (hasSetter) {
/* Mark the getter, then set value to setter. */
if (hasGetter && !JSVAL_IS_PRIMITIVE(v.u.value)) {
ok = !!MarkSharpObjects(cx, JSVAL_TO_OBJECT(v.u.value), NULL);
}
if (ok)
v.u.value = setter.u.value;
} else if (!hasGetter) {
ok = OBJ_GET_PROPERTY(cx, obj, id, &(v.u.value));
}
JS_POP_TEMP_ROOT(cx, &setter);
#else
ok = OBJ_GET_PROPERTY(cx, obj, id, &val);
ok = OBJ_GET_PROPERTY(cx, obj, id, &(v.u.value));
#endif
if (!ok)
break;
if (!JSVAL_IS_PRIMITIVE(val) &&
!MarkSharpObjects(cx, JSVAL_TO_OBJECT(val), NULL)) {
goto brk;
if (!JSVAL_IS_PRIMITIVE(v.u.value) &&
!MarkSharpObjects(cx, JSVAL_TO_OBJECT(v.u.value), NULL)) {
ok = JS_FALSE;
break;
goto brk;
}
cont:
JS_POP_TEMP_ROOT(cx, &v);
continue;
brk:
JS_POP_TEMP_ROOT(cx, &v);
break;
}
if (!ok || !idap)
JS_DestroyIdArray(cx, ida);
@ -866,13 +880,9 @@ js_obj_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
valcnt = 0;
if (prop) {
ok = OBJ_GET_ATTRIBUTES(cx, obj2, id, prop, &attrs);
if (!ok) {
OBJ_DROP_PROPERTY(cx, obj2, prop);
goto error;
}
if (OBJ_IS_NATIVE(obj2) &&
(attrs & (JSPROP_GETTER | JSPROP_SETTER))) {
if (OBJ_IS_NATIVE(obj2)) {
JSScopeProperty *sprop = (JSScopeProperty *) prop;
attrs = sprop->attrs;
if (attrs & JSPROP_GETTER) {
val[valcnt] = (jsval) ((JSScopeProperty *)prop)->getter;
gsopold[valcnt] =
@ -889,13 +899,18 @@ js_obj_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
ATOM_TO_STRING(cx->runtime->atomState.setAtom);
valcnt++;
}
JS_UNLOCK_OBJ(cx, obj2);
} else {
OBJ_DROP_PROPERTY(cx, obj2, prop);
}
if (!valcnt) {
valcnt = 1;
gsop[0] = NULL;
gsopold[0] = NULL;
ok = OBJ_GET_PROPERTY(cx, obj, id, &val[0]);
if (!ok)
goto error;
}
OBJ_DROP_PROPERTY(cx, obj2, prop);
}
#else /* !JS_HAS_GETTER_SETTER */
@ -911,11 +926,11 @@ js_obj_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
gsopold[0] = NULL;
ok = OBJ_GET_PROPERTY(cx, obj, id, &val[0]);
#endif /* !JS_HAS_GETTER_SETTER */
if (!ok)
goto error;
#endif /* !JS_HAS_GETTER_SETTER */
/*
* If id is a string that's not an identifier, then it needs to be
* quoted. Also, negative integer ids must be quoted.
@ -3204,6 +3219,7 @@ js_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN flags,
const JSCodeSpec *cs;
uint32 format;
JSBool ok;
JSTempValueRooter tvr, tvr2;
/*
* Handle old bug that took empty string as zero index. Also convert
@ -3296,7 +3312,9 @@ js_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN flags,
if (!MAP_IS_NATIVE(&scope->map)) {
/* Whoops, newresolve handed back a foreign obj2. */
JS_ASSERT(obj2 != obj);
JS_PUSH_SINGLE_TEMP_ROOT(cx, OBJECT_TO_JSVAL(obj2), &tvr);
ok = OBJ_LOOKUP_PROPERTY(cx, obj2, id, objp, propp);
JS_POP_TEMP_ROOT(cx, &tvr);
if (!ok || *propp)
goto cleanup;
JS_LOCK_OBJ(cx, obj2);
@ -3356,8 +3374,13 @@ js_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN flags,
JS_UNLOCK_OBJ(cx, obj);
if (!proto)
break;
if (!OBJ_IS_NATIVE(proto))
return OBJ_LOOKUP_PROPERTY(cx, proto, id, objp, propp);
if (!OBJ_IS_NATIVE(proto)) {
JSBool ret;
JS_PUSH_SINGLE_TEMP_ROOT(cx, OBJECT_TO_JSVAL(proto), &tvr2);
ret = OBJ_LOOKUP_PROPERTY(cx, proto, id, objp, propp);
JS_POP_TEMP_ROOT(cx, &tvr2);
return ret;
}
obj = proto;
}
@ -4601,7 +4624,7 @@ js_ValueToObject(JSContext *cx, jsval v, JSObject **objp)
obj = JSVAL_TO_OBJECT(v);
if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_OBJECT, &v))
return JS_FALSE;
if (JSVAL_IS_OBJECT(v))
if (!JSVAL_IS_PRIMITIVE(v))
obj = JSVAL_TO_OBJECT(v);
} else {
if (JSVAL_IS_STRING(v)) {
@ -4983,6 +5006,12 @@ js_SetRequiredSlot(JSContext *cx, JSObject *obj, uint32 slot, jsval v)
return JS_TRUE;
}
JS_FRIEND_API(void)
js_SetObjectWeakRoot(JSContext *cx, JSObject *obj)
{
cx->weakRoots.newborn[GCX_OBJECT] = obj;
}
#ifdef DEBUG
/* Routines to print out values during debugging. */

View File

@ -597,6 +597,9 @@ extern const char *
js_ComputeFilename(JSContext *cx, JSStackFrame *caller,
JSPrincipals *principals, uintN *linenop);
JS_FRIEND_API(void)
js_SetObjectWeakRoot(JSContext *cx, JSObject *obj);
JS_END_EXTERN_C
#endif /* jsobj_h___ */

View File

@ -2684,7 +2684,7 @@ ExecuteREBytecode(REGlobalData *gData, REMatchState *x)
jsbytecode *nextpc, *testpc;
REOp nextop;
RECapture *cap;
REProgState *curState;
REProgState *curState=NULL;
const jschar *startcp;
size_t parenIndex, k;
size_t parenSoFar = 0;
@ -2809,7 +2809,8 @@ ExecuteREBytecode(REGlobalData *gData, REMatchState *x)
* Occurs at (successful) end of REOP_ALT,
*/
case REOP_JUMP:
--gData->stateStackTop;
if(gData->stateStackTop)
--gData->stateStackTop;
pc += GET_OFFSET(pc);
op = (REOp) *pc++;
continue;
@ -2818,7 +2819,8 @@ ExecuteREBytecode(REGlobalData *gData, REMatchState *x)
* Occurs at last (successful) end of REOP_ALT,
*/
case REOP_ENDALT:
--gData->stateStackTop;
if(gData->stateStackTop)
--gData->stateStackTop;
op = (REOp) *pc++;
continue;
@ -2895,7 +2897,8 @@ ExecuteREBytecode(REGlobalData *gData, REMatchState *x)
continue;
case REOP_ASSERTTEST:
--gData->stateStackTop;
if(gData->stateStackTop)
--gData->stateStackTop;
--curState;
x->cp = gData->cpbegin + curState->index;
gData->backTrackSP =
@ -2907,7 +2910,8 @@ ExecuteREBytecode(REGlobalData *gData, REMatchState *x)
break;
case REOP_ASSERTNOTTEST:
--gData->stateStackTop;
if(gData->stateStackTop)
--gData->stateStackTop;
--curState;
x->cp = gData->cpbegin + curState->index;
gData->backTrackSP =
@ -2987,7 +2991,8 @@ ExecuteREBytecode(REGlobalData *gData, REMatchState *x)
CHECK_BRANCH();
--curState;
do {
--gData->stateStackTop;
if(gData->stateStackTop)
--gData->stateStackTop;
if (!result) {
/* Failed, see if we have enough children. */
if (curState->u.quantifier.min == 0)
@ -3075,7 +3080,8 @@ ExecuteREBytecode(REGlobalData *gData, REMatchState *x)
pc, x, x->cp, 0, 0)) {
return NULL;
}
--gData->stateStackTop;
if(gData->stateStackTop)
--gData->stateStackTop;
pc = pc + GET_OFFSET(pc);
op = (REOp) *pc++;
}
@ -3083,7 +3089,8 @@ ExecuteREBytecode(REGlobalData *gData, REMatchState *x)
case REOP_MINIMALREPEAT:
CHECK_BRANCH();
--gData->stateStackTop;
if(gData->stateStackTop)
--gData->stateStackTop;
--curState;
if (!result) {
@ -3135,7 +3142,8 @@ ExecuteREBytecode(REGlobalData *gData, REMatchState *x)
parenSoFar - curState->parenSoFar)) {
return NULL;
}
--gData->stateStackTop;
if(gData->stateStackTop)
--gData->stateStackTop;
pc = pc + GET_OFFSET(pc);
op = (REOp) *pc++;
continue;
@ -3162,6 +3170,7 @@ ExecuteREBytecode(REGlobalData *gData, REMatchState *x)
pc = backTrackData->backtrack_pc;
op = backTrackData->backtrack_op;
gData->stateStackTop = backTrackData->saveStateStackTop;
JS_ASSERT(gData->stateStackTop);
memcpy(gData->stateStack, backTrackData + 1,
@ -3270,6 +3279,21 @@ bad:
return NULL;
}
void
js_RegExpStatics_clear(JSContext *cx, JSRegExpStatics *res)
{
res->input = NULL;
res->pendingInput = NULL;
res->multiline = JS_FALSE;
res->parenCount = 0;
res->lastMatch = res->lastParen = js_EmptySubString;
res->leftContext = res->rightContext = js_EmptySubString;
if (res->moreParens) {
JS_free(cx, res->moreParens);
res->moreParens = NULL;
}
}
JSBool
js_ExecuteRegExp(JSContext *cx, JSRegExp *re, JSString *str, size_t *indexp,
JSBool test, jsval *rval)
@ -3375,7 +3399,7 @@ js_ExecuteRegExp(JSContext *cx, JSRegExp *re, JSString *str, size_t *indexp,
}
res = &cx->regExpStatics;
res->input = str;
res->pendingInput = res->input = str;
res->parenCount = re->parenCount;
if (re->parenCount == 0) {
res->lastParen = js_EmptySubString;
@ -3478,6 +3502,8 @@ js_ExecuteRegExp(JSContext *cx, JSRegExp *re, JSString *str, size_t *indexp,
res->rightContext.length = gData.cpend - ep;
out:
if (!ok)
js_RegExpStatics_clear(cx,res);
JS_FinishArenaPool(&gData.pool);
return ok;
}
@ -3580,8 +3606,11 @@ enum regexp_static_tinyid {
JSBool
js_InitRegExpStatics(JSContext *cx, JSRegExpStatics *res)
{
JSBool in, pd;
JS_ClearRegExpStatics(cx);
return js_AddRoot(cx, &res->input, "res->input");
in = js_AddRoot(cx, &res->input, "res->input");
pd = js_AddRoot(cx, &res->pendingInput, "res->input");
return in && pd;
}
void
@ -3592,6 +3621,7 @@ js_FreeRegExpStatics(JSContext *cx, JSRegExpStatics *res)
res->moreParens = NULL;
}
js_RemoveRoot(cx->runtime, &res->input);
js_RemoveRoot(cx->runtime, &res->pendingInput);
}
static JSBool
@ -3608,8 +3638,8 @@ regexp_static_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
slot = JSVAL_TO_INT(id);
switch (slot) {
case REGEXP_STATIC_INPUT:
*vp = res->input ? STRING_TO_JSVAL(res->input)
: JS_GetEmptyStringValue(cx);
*vp = res->pendingInput ? STRING_TO_JSVAL(res->pendingInput)
: JS_GetEmptyStringValue(cx);
return JS_TRUE;
case REGEXP_STATIC_MULTILINE:
*vp = BOOLEAN_TO_JSVAL(res->multiline);
@ -3651,7 +3681,7 @@ regexp_static_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
!JS_ConvertValue(cx, *vp, JSTYPE_STRING, vp)) {
return JS_FALSE;
}
res->input = JSVAL_TO_STRING(*vp);
res->pendingInput = JSVAL_TO_STRING(*vp);
} else if (JSVAL_TO_INT(id) == REGEXP_STATIC_MULTILINE) {
if (!JSVAL_IS_BOOLEAN(*vp) &&
!JS_ConvertValue(cx, *vp, JSTYPE_BOOLEAN, vp)) {
@ -4018,7 +4048,7 @@ regexp_exec_sub(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
/* Now that obj is unlocked, it's safe to (potentially) grab the GC lock. */
if (argc == 0) {
str = cx->regExpStatics.input;
str = cx->regExpStatics.pendingInput;
if (!str) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_NO_INPUT,

View File

@ -52,6 +52,7 @@
struct JSRegExpStatics {
JSString *input; /* input string to match (perl $_, GC root) */
JSString *pendingInput; /* pending input string to match */
JSBool multiline; /* whether input contains newlines (perl $*) */
uint16 parenCount; /* number of valid elements in parens[] */
uint16 moreLength; /* number of allocated elements in moreParens */
@ -63,6 +64,9 @@ struct JSRegExpStatics {
JSSubString rightContext; /* input to right of last match (perl $') */
};
void
js_RegExpStatics_clear(JSContext *cx, JSRegExpStatics *res);
/*
* This struct holds a bitmap representation of a class from a regexp.
* There's a list of these referenced by the classList field in the JSRegExp

View File

@ -6028,7 +6028,8 @@ xml_elements(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
nameqn = ToXMLName(cx, name, &funid);
if (!nameqn)
return JS_FALSE;
argv[0] = OBJECT_TO_JSVAL(nameqn->object);
if (argc)
argv[0] = OBJECT_TO_JSVAL(nameqn->object);
list = xml_list_helper(cx, xml, rval);
if (!list)

View File

@ -254,6 +254,7 @@ JavaArray_lookupProperty(JSContext *cx, JSObject *obj, jsid id,
if (access_java_array_element(cx, jEnv, obj, id, NULL, JS_FALSE)) {
*objp = obj;
*propp = (JSProperty*)1;
js_SetObjectWeakRoot(cx, obj);
} else {
*objp = NULL;
*propp = NULL;

View File

@ -321,6 +321,7 @@ JavaClass_lookupProperty(JSContext *cx, JSObject *obj, jsid id,
if (lookup_static_member_by_id(cx, jEnv, obj, NULL, id, NULL)) {
*objp = obj;
*propp = (JSProperty*)1;
js_SetObjectWeakRoot(cx, obj);
} else {
*objp = NULL;
*propp = NULL;

View File

@ -832,6 +832,7 @@ JavaObject_lookupProperty(JSContext *cx, JSObject *obj, jsid id,
*objp = obj;
*propp = (JSProperty*)1;
}
js_SetObjectWeakRoot(cx, *objp);
} else {
*objp = NULL;
*propp = NULL;

View File

@ -688,9 +688,9 @@ interface nsIXPConnect : nsISupports
interface nsIXPConnect_MOZILLA_1_8_BRANCH : nsIXPConnect
{
void
reparentScopeAwareWrappers(in JSContextPtr aJSContext,
in JSObjectPtr aOldScope,
in JSObjectPtr aNewScope);
moveWrappers(in JSContextPtr aJSContext,
in JSObjectPtr aOldScope,
in JSObjectPtr aNewScope);
/**
* Create a sandbox for evaluating code in isolation using

View File

@ -65,6 +65,7 @@ REQUIRES = xpcom \
caps \
necko \
dom \
widget \
$(NULL)
CPPSRCS = \

View File

@ -1127,9 +1127,16 @@ MirrorWrappedNativeParent(JSContext *cx, XPCWrappedNative *wrapper,
XPCWrappedNative *parent_wrapper =
XPCWrappedNative::GetWrappedNativeOfJSObject(cx, wn_parent);
*result = XPCNativeWrapper::GetNewOrUsed(cx, parent_wrapper, nsnull, nsnull);
if (!*result)
return JS_FALSE;
// parent_wrapper can be null if we're in a Components.utils.evalInSandbox
// scope. In that case, the best we can do is just use the
// non-native-wrapped sandbox global object for our parent.
if (parent_wrapper) {
*result = XPCNativeWrapper::GetNewOrUsed(cx, parent_wrapper, nsnull, nsnull);
if (!*result)
return JS_FALSE;
} else {
*result = nsnull;
}
}
return JS_TRUE;
}

View File

@ -779,11 +779,11 @@ MoveableWrapperFinder(JSDHashTable *table, JSDHashEntryHdr *hdr,
return JS_DHASH_NEXT;
}
/* void reparentScopeAwareWrappers(in JSContextPtr aJSContext, in JSObjectPtr aOldScope, in JSObjectPtr aNewScope); */
/* void moveWrappers(in JSContextPtr aJSContext, in JSObjectPtr aOldScope, in JSObjectPtr aNewScope); */
NS_IMETHODIMP
nsXPConnect::ReparentScopeAwareWrappers(JSContext *aJSContext,
JSObject *aOldScope,
JSObject *aNewScope)
nsXPConnect::MoveWrappers(JSContext *aJSContext,
JSObject *aOldScope,
JSObject *aNewScope)
{
XPCCallContext ccx(NATIVE_CALLER, aJSContext);
if(!ccx.IsValid())
@ -840,35 +840,41 @@ nsXPConnect::ReparentScopeAwareWrappers(JSContext *aJSContext,
if(NS_FAILED(rv))
return NS_ERROR_FAILURE;
JSObject *newParent = aOldScope;
// If the wrapper doesn't want precreate, then we don't need to
// worry about reparenting it.
if(!sciWrapper.GetFlags().WantPreCreate())
continue;
JSObject *newParent = aOldScope;
rv = sciWrapper.GetCallback()->PreCreate(identity, ccx, aOldScope,
&newParent);
if(NS_FAILED(rv))
return rv;
if(newParent != aOldScope)
if(newParent == aOldScope)
{
// The wrapper returned a new parent. If the new parent is in
// a different scope, then we need to reparent it, otherwise,
// the old scope is fine.
// The old scope still works for this wrapper. We have to assume
// that the wrapper will continue to return the old scope from
// PreCreate, so don't move it.
continue;
}
XPCWrappedNativeScope *betterScope =
XPCWrappedNativeScope::FindInJSObjectScope(ccx, newParent);
if(betterScope == oldScope)
continue;
NS_ASSERTION(betterScope == newScope, "Weird scope returned");
}
else
{
// The old scope still works for this wrapper.
continue;
}
// The wrapper returned a new parent. If the new parent is in
// a different scope, then we need to reparent it, otherwise,
// the old scope is fine.
XPCWrappedNativeScope *betterScope =
XPCWrappedNativeScope::FindInJSObjectScope(ccx, newParent);
if(betterScope == oldScope)
{
// The wrapper asked for a different object, but that object
// was in the same scope. We assume here that the new parent
// simply hasn't been reparented yet.
newParent = nsnull;
}
else
NS_ASSERTION(betterScope == newScope, "Weird scope returned");
// Now, reparent the wrapper, since we know that it wants to be
// reparented.

View File

@ -1910,7 +1910,14 @@ nsXPCComponents_Utils::LookupMethod()
return NS_ERROR_XPC_BAD_CONVERT_JS;
JSObject* obj = JSVAL_TO_OBJECT(argv[0]);
{
XPCWrappedNative *wn =
XPCWrappedNative::GetWrappedNativeOfJSObject(cx, obj);
if(!wn)
return NS_ERROR_XPC_BAD_CONVERT_JS;
obj = wn->GetFlatJSObject();
}
// Can't use the macro OBJ_TO_INNER_OBJECT here due to it using
// the non-exported function js_GetSlotThreadSafe().
{
@ -1921,6 +1928,8 @@ nsXPCComponents_Utils::LookupMethod()
obj = xclasp->innerObject(cx, obj);
}
}
if(!obj)
return NS_ERROR_XPC_BAD_CONVERT_JS;
// second param must be a string
if(!JSVAL_IS_STRING(argv[1]))

View File

@ -42,6 +42,8 @@
/* Implement global service to track stack of JSContext per thread. */
#include "xpcprivate.h"
#include "nsIScriptGlobalObject.h"
#include "nsIScriptContext.h"
/***************************************************************************/
@ -117,6 +119,20 @@ XPCJSContextStack::Pop(JSContext * *_retval)
return NS_OK;
}
static nsIPrincipal*
GetPrincipalFromCx(JSContext *cx)
{
nsIScriptContext* scriptContext = GetScriptContextFromJSContext(cx);
if (scriptContext)
{
nsCOMPtr<nsIScriptObjectPrincipal> globalData =
do_QueryInterface(scriptContext->GetGlobalObject());
if (globalData)
return globalData->GetPrincipal();
}
return nsnull;
}
/* void push (in JSContext cx); */
NS_IMETHODIMP
XPCJSContextStack::Push(JSContext * cx)
@ -126,8 +142,33 @@ XPCJSContextStack::Push(JSContext * cx)
if(mStack.Length() > 1)
{
JSContextAndFrame & e = mStack[mStack.Length() - 2];
if(e.cx && e.cx != cx)
e.frame = JS_SaveFrameChain(e.cx);
if(e.cx)
{
if (e.cx == cx)
{ nsresult rv;
nsCOMPtr<nsIScriptSecurityManager> ssm =
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv) && ssm)
{
nsIPrincipal* globalObjectPrincipal =
GetPrincipalFromCx(cx);
if (globalObjectPrincipal)
{
nsCOMPtr<nsIPrincipal> subjectPrincipal;
ssm->GetSubjectPrincipal(getter_AddRefs(subjectPrincipal));
PRBool equals = PR_FALSE;
globalObjectPrincipal->Equals(subjectPrincipal, &equals);
if (equals)
{
return NS_OK;
}
}
}
}
e.frame = JS_SaveFrameChain(e.cx);
}
}
return NS_OK;
}

View File

@ -239,6 +239,13 @@ XPCArrayHomogenizer::GetTypeForArray(XPCCallContext& ccx, JSObject* array,
JSBool XPCVariant::InitializeData(XPCCallContext& ccx)
{
int stackDummy;
if (!JS_CHECK_STACK_SIZE(ccx.GetJSContext(), stackDummy)) {
JS_ReportErrorNumber(ccx.GetJSContext(), js_GetErrorMessage, NULL, JSMSG_OVER_RECURSED);
return JS_FALSE;
}
if(JSVAL_IS_INT(mJSVal))
return NS_SUCCEEDED(nsVariant::SetFromInt32(&mData,
JSVAL_TO_INT(mJSVal)));
@ -763,5 +770,3 @@ NS_IMETHODIMP XPCVariant::GetAsWStringWithSize(PRUint32 *size, PRUnichar **str)
{
return nsVariant::ConvertToWStringWithSize(mData, size, str);
}

View File

@ -238,6 +238,29 @@ nsXPCWrappedJSClass::CallQueryInterfaceOnJSObject(XPCCallContext& ccx,
jsid funid;
jsval fun;
// Don't call the actual function on a content object. We'll determine
// whether or not a content object is capable of implementing the
// interface (i.e. whether the interface is scriptable) and most content
// objects don't have QI implementations anyway. Also see bug 503926.
if(!JS_IsSystemObject(ccx, jsobj))
{
nsCOMPtr<nsIPrincipal> objPrin;
nsXPConnect *xpc = nsXPConnect::GetXPConnect();
nsCOMPtr<nsIScriptSecurityManager> ssm =
do_QueryInterface(xpc->GetDefaultSecurityManager());
if(ssm)
{
nsresult rv = ssm->GetObjectPrincipal(ccx, jsobj, getter_AddRefs(objPrin));
NS_ENSURE_SUCCESS(rv, nsnull);
nsCOMPtr<nsIPrincipal> systemPrin;
rv = ssm->GetSystemPrincipal(getter_AddRefs(systemPrin));
if(systemPrin != objPrin)
return nsnull;
}
}
// check upfront for the existence of the function property
funid = mRuntime->GetStringID(XPCJSRuntime::IDX_QUERY_INTERFACE);
if(!OBJ_GET_PROPERTY(cx, jsobj, funid, &fun) || JSVAL_IS_PRIMITIVE(fun))

View File

@ -1143,7 +1143,7 @@ XPCWrappedNative::ReparentWrapperIfFound(XPCCallContext& ccx,
// Now we can just fix up the parent and return the wrapper
if(!JS_SetParent(ccx, wrapper->GetFlatJSObject(), aNewParent))
if(aNewParent && !JS_SetParent(ccx, wrapper->GetFlatJSObject(), aNewParent))
{
NS_RELEASE(wrapper);
return NS_ERROR_FAILURE;

View File

@ -8572,6 +8572,32 @@ nsCSSFrameConstructor::FindNextSibling(nsIContent* aContainer,
return nsnull;
}
#ifdef MOZ_XUL
static
nsIListBoxObject*
MaybeGetListBoxBodyFrame(nsIContent* aContainer, nsIContent* aChild)
{
NS_PRECONDITION(aContainer, "Must have container here");
if (aContainer->IsContentOfType(nsIContent::eXUL) &&
aChild->IsContentOfType(nsIContent::eXUL) &&
aContainer->Tag() == nsXULAtoms::listbox &&
aChild->Tag() == nsXULAtoms::listitem) {
nsCOMPtr<nsIDOMXULElement> xulElement = do_QueryInterface(aContainer);
nsCOMPtr<nsIBoxObject> boxObject;
xulElement->GetBoxObject(getter_AddRefs(boxObject));
nsCOMPtr<nsPIListBoxObject_MOZILLA_1_8_BRANCH> listBoxObject = do_QueryInterface(boxObject);
if (listBoxObject) {
return listBoxObject->GetListBoxBody(PR_FALSE);
}
}
return nsnull;
}
#endif
inline PRBool
ShouldIgnoreSelectChild(nsIContent* aContainer)
{
@ -8727,6 +8753,20 @@ nsCSSFrameConstructor::ContentAppended(nsIContent* aContainer,
PRUint32 containerCount = aContainer->GetChildCount();
for (PRUint32 i = aNewIndexInContainer; i < containerCount; i++) {
nsIContent *child = aContainer->GetChildAt(i);
nsIFrame* primaryFrame = nsnull;
mPresShell->GetPrimaryFrameFor(child,&primaryFrame);
if (primaryFrame
#ifdef MOZ_XUL
// Except listboxes suck, so do NOT skip anything here if
// we plan to notify a listbox.
&& !MaybeGetListBoxBodyFrame(aContainer, child)
#endif
) {
// Already have a frame for this content; a previous ContentInserted
// in this loop must have reconstructed its insertion parent. Skip
// it.
continue;
}
if (multiple) {
// Filters are in effect, so the insertion point needs to be refetched for
// each child.
@ -9203,37 +9243,28 @@ PRBool NotifyListBoxBody(nsPresContext* aPresContext,
PRBool aUseXBLForms,
content_operation aOperation)
{
if (!aContainer)
if (!aContainer) {
return PR_FALSE;
}
if (aContainer->IsContentOfType(nsIContent::eXUL) &&
aChild->IsContentOfType(nsIContent::eXUL) &&
aContainer->Tag() == nsXULAtoms::listbox &&
aChild->Tag() == nsXULAtoms::listitem) {
nsCOMPtr<nsIDOMXULElement> xulElement = do_QueryInterface(aContainer);
nsCOMPtr<nsIBoxObject> boxObject;
xulElement->GetBoxObject(getter_AddRefs(boxObject));
nsCOMPtr<nsPIListBoxObject_MOZILLA_1_8_BRANCH> listBoxObject = do_QueryInterface(boxObject);
if (listBoxObject) {
nsIListBoxObject* listboxBody = listBoxObject->GetListBoxBody(PR_FALSE);
if (listboxBody) {
nsListBoxBodyFrame *listBoxBodyFrame = NS_STATIC_CAST(nsListBoxBodyFrame*, listboxBody);
if (aOperation == CONTENT_REMOVED) {
// Except if we have an aChildFrame and its parent is not the right
// thing, then we don't do this. Pseudo frames are so much fun....
if (!aChildFrame || aChildFrame->GetParent() == listBoxBodyFrame) {
listBoxBodyFrame->OnContentRemoved(aPresContext, aChildFrame,
aIndexInContainer);
return PR_TRUE;
}
} else {
listBoxBodyFrame->OnContentInserted(aPresContext, aChild);
return PR_TRUE;
}
nsIListBoxObject* listboxBody = MaybeGetListBoxBodyFrame(aContainer, aChild);
if (listboxBody) {
nsListBoxBodyFrame *listBoxBodyFrame = static_cast<nsListBoxBodyFrame*>(listboxBody);
if (aOperation == CONTENT_REMOVED) {
// Except if we have an aChildFrame and its parent is not the right
// thing, then we don't do this. Pseudo frames are so much fun....
if (!aChildFrame || aChildFrame->GetParent() == listBoxBodyFrame) {
listBoxBodyFrame->OnContentRemoved(aPresContext, aChildFrame,
aIndexInContainer);
return PR_TRUE;
}
} else {
listBoxBodyFrame->OnContentInserted(aPresContext, aChild);
return PR_TRUE;
}
}
nsCOMPtr<nsIAtom> tag;
PRInt32 namespaceID;
aDocument->BindingManager()->ResolveTag(aContainer, &namespaceID,

View File

@ -220,8 +220,6 @@ nsPresContext::nsPresContext(nsPresContextType aType)
nsPresContext::~nsPresContext()
{
mImageLoaders.Enumerate(destroy_loads);
NS_PRECONDITION(!mShell, "Presshell forgot to clear our mShell pointer");
SetShell(nsnull);
@ -775,6 +773,13 @@ nsPresContext::SetShell(nsIPresShell* aShell)
UpdateCharSet(doc->GetDocumentCharacterSet());
}
}
} else {
// Destroy image loaders now that the presshell is going away.
// This is important since imageloaders can have pointers to frames and
// we don't want those pointers to outlive the destruction of the frame
// arena.
mImageLoaders.Enumerate(destroy_loads, nsnull);
}
}
@ -1037,6 +1042,8 @@ nsPresContext::SetTextZoomExternal(float aZoom)
imgIRequest*
nsPresContext::LoadImage(imgIRequest* aImage, nsIFrame* aTargetFrame)
{
NS_ASSERTION(mShell, "Shouldn't load image after the shell is gone");
// look and see if we have a loader for the target frame.
nsVoidKey key(aTargetFrame);

View File

@ -3236,6 +3236,8 @@ NS_IMETHODIMP
PresShell::NotifyDestroyingFrame(nsIFrame* aFrame)
{
if (!mIgnoreFrameDestruction) {
mPresContext->StopImagesFor(aFrame);
mFrameConstructor->NotifyDestroyingFrame(aFrame);
// Cancel any pending reflow commands targeted at this frame

View File

@ -752,17 +752,7 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext,
// and we may even delete the line with the line cursor.
ClearLineCursor();
if (IsFrameTreeTooDeep(aReflowState, aMetrics)) {
#ifdef DEBUG_kipp
{
extern char* nsPresShell_ReflowStackPointerTop;
char marker;
char* newsp = (char*) &marker;
printf("XXX: frame tree is too deep; approx stack size = %d\n",
nsPresShell_ReflowStackPointerTop - newsp);
}
#endif
aStatus = NS_FRAME_COMPLETE;
if (IsFrameTreeTooDeep(aReflowState, aMetrics, aStatus)) {
return NS_OK;
}

View File

@ -645,10 +645,6 @@ nsFrame::Destroy(nsPresContext* aPresContext)
}
}
//XXX Why is this done in nsFrame instead of some frame class
// that actually loads images?
aPresContext->StopImagesFor(this);
if (view) {
// Break association between view and frame
view->SetClientData(nsnull);
@ -2703,9 +2699,11 @@ nsFrame::CheckInvalidateSizeChange(nsPresContext* aPresContext,
PRBool
nsFrame::IsFrameTreeTooDeep(const nsHTMLReflowState& aReflowState,
nsHTMLReflowMetrics& aMetrics)
nsHTMLReflowMetrics& aMetrics,
nsReflowStatus& aStatus)
{
if (aReflowState.mReflowDepth > MAX_FRAME_DEPTH) {
NS_WARNING("frame tree too deep; setting zero size and returning");
mState |= NS_FRAME_IS_UNFLOWABLE;
mState &= ~NS_FRAME_OUTSIDE_CHILDREN;
aMetrics.width = 0;
@ -2720,6 +2718,16 @@ nsFrame::IsFrameTreeTooDeep(const nsHTMLReflowState& aReflowState,
if (aMetrics.mComputeMEW) {
aMetrics.mMaxElementWidth = 0;
}
if (GetNextInFlow()) {
// Reflow depth might vary between reflows, so we might have
// successfully reflowed and split this frame before. If so, we
// shouldn't delete its continuations.
aStatus = NS_FRAME_NOT_COMPLETE;
} else {
aStatus = NS_FRAME_COMPLETE;
}
return PR_TRUE;
}
mState &= ~NS_FRAME_IS_UNFLOWABLE;

View File

@ -350,13 +350,14 @@ public:
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState);
// Helper function that tests if the frame tree is too deep; if it
// is it marks the frame as "unflowable" and zeros out the metrics
// and returns PR_TRUE. Otherwise, the frame is unmarked
// "unflowable" and the metrics are not touched and PR_FALSE is
// returned.
// Helper function that tests if the frame tree is too deep; if it is
// it marks the frame as "unflowable", zeroes out the metrics, sets
// the reflow status, and returns PR_TRUE. Otherwise, the frame is
// unmarked "unflowable" and the metrics and reflow status are not
// touched and PR_FALSE is returned.
PRBool IsFrameTreeTooDeep(const nsHTMLReflowState& aReflowState,
nsHTMLReflowMetrics& aMetrics);
nsHTMLReflowMetrics& aMetrics,
nsReflowStatus& aStatus);
// Do the work for getting the parent style context frame so that
// other frame's |GetParentStyleContextFrame| methods can call this

View File

@ -767,26 +767,6 @@ nsSubDocumentFrame::ShowDocShell()
baseWindow->SetVisibility(PR_TRUE);
}
// Trigger editor re-initialization if midas is turned on in the
// sub-document. This shouldn't be necessary, but given the way our
// editor works, it is. See
// https://bugzilla.mozilla.org/show_bug.cgi?id=284245
docShell->GetPresShell(getter_AddRefs(presShell));
if (presShell) {
nsCOMPtr<nsIDOMNSHTMLDocument> doc =
do_QueryInterface(presShell->GetDocument());
if (doc) {
nsAutoString designMode;
doc->GetDesignMode(designMode);
if (designMode.EqualsLiteral("on")) {
doc->SetDesignMode(NS_LITERAL_STRING("off"));
doc->SetDesignMode(NS_LITERAL_STRING("on"));
}
}
}
return NS_OK;
}

View File

@ -355,13 +355,19 @@ nsHTMLFramesetFrame::Init(nsPresContext* aPresContext,
NS_ENSURE_SUCCESS(result, result);
result = ourContent->GetColSpec(&mNumCols, &colSpecs);
NS_ENSURE_SUCCESS(result, result);
// Maximum value of mNumRows and mNumCols is NS_MAX_FRAMESET_SPEC_COUNT
PR_STATIC_ASSERT(NS_MAX_FRAMESET_SPEC_COUNT < UINT_MAX / sizeof(nscoord));
mRowSizes = new nscoord[mNumRows];
mColSizes = new nscoord[mNumCols];
if (!mRowSizes || !mColSizes)
return NS_ERROR_OUT_OF_MEMORY;
// Ensure we can't overflow numCells
PR_STATIC_ASSERT(NS_MAX_FRAMESET_SPEC_COUNT < PR_INT32_MAX / NS_MAX_FRAMESET_SPEC_COUNT);
PRInt32 numCells = mNumRows*mNumCols;
PR_STATIC_ASSERT(NS_MAX_FRAMESET_SPEC_COUNT < UINT_MAX / sizeof(nsHTMLFramesetBorderFrame*));
mVerBorders = new nsHTMLFramesetBorderFrame*[mNumCols]; // 1 more than number of ver borders
if (!mVerBorders)
return NS_ERROR_OUT_OF_MEMORY;
@ -375,7 +381,13 @@ nsHTMLFramesetFrame::Init(nsPresContext* aPresContext,
for (int horX = 0; horX < mNumRows; horX++)
mHorBorders[horX] = nsnull;
PR_STATIC_ASSERT(NS_MAX_FRAMESET_SPEC_COUNT
< UINT_MAX / sizeof(PRInt32) / NS_MAX_FRAMESET_SPEC_COUNT);
PR_STATIC_ASSERT(NS_MAX_FRAMESET_SPEC_COUNT
< UINT_MAX / sizeof(nsFrameborder) / NS_MAX_FRAMESET_SPEC_COUNT);
PR_STATIC_ASSERT(NS_MAX_FRAMESET_SPEC_COUNT
< UINT_MAX / sizeof(nsBorderColor) / NS_MAX_FRAMESET_SPEC_COUNT);
mChildTypes = new PRInt32[numCells];
mChildFrameborder = new nsFrameborder[numCells];
mChildBorderColors = new nsBorderColor[numCells];
@ -550,6 +562,9 @@ void nsHTMLFramesetFrame::CalculateRowCol(nsPresContext* aPresContext,
const nsFramesetSpec* aSpecs,
nscoord* aValues)
{
// aNumSpecs maximum value is NS_MAX_FRAMESET_SPEC_COUNT
PR_STATIC_ASSERT(NS_MAX_FRAMESET_SPEC_COUNT < UINT_MAX / sizeof(PRInt32));
PRInt32 fixedTotal = 0;
PRInt32 numFixed = 0;
PRInt32* fixed = new PRInt32[aNumSpecs];
@ -1045,6 +1060,11 @@ nsHTMLFramesetFrame::Reflow(nsPresContext* aPresContext,
nsFrameborder frameborder = GetFrameBorder();
if (firstTime) {
// Check for overflow in memory allocations using mNumCols and mNumRows
// which have a maxium value of NS_MAX_FRAMESET_SPEC_COUNT.
PR_STATIC_ASSERT(NS_MAX_FRAMESET_SPEC_COUNT < UINT_MAX / sizeof(PRBool));
PR_STATIC_ASSERT(NS_MAX_FRAMESET_SPEC_COUNT < UINT_MAX / sizeof(nscolor));
verBordersVis = new PRBool[mNumCols];
verBorderColors = new nscolor[mNumCols];
for (int verX = 0; verX < mNumCols; verX++) {
@ -1360,7 +1380,10 @@ nsHTMLFramesetFrame::RecalculateBorderResize()
return;
}
PR_STATIC_ASSERT(NS_MAX_FRAMESET_SPEC_COUNT < PR_INT32_MAX / NS_MAX_FRAMESET_SPEC_COUNT);
PRInt32 numCells = mNumRows * mNumCols; // max number of cells
PR_STATIC_ASSERT(NS_MAX_FRAMESET_SPEC_COUNT
< UINT_MAX / sizeof(PRInt32) / NS_MAX_FRAMESET_SPEC_COUNT);
PRInt32* childTypes = new PRInt32[numCells];
PRUint32 childIndex, frameOrFramesetChildIndex = 0;

View File

@ -457,17 +457,7 @@ nsInlineFrame::Reflow(nsPresContext* aPresContext,
}
}
if (IsFrameTreeTooDeep(aReflowState, aMetrics)) {
#ifdef DEBUG_kipp
{
extern char* nsPresShell_ReflowStackPointerTop;
char marker;
char* newsp = (char*) &marker;
printf("XXX: frame tree is too deep; approx stack size = %d\n",
nsPresShell_ReflowStackPointerTop - newsp);
}
#endif
aStatus = NS_FRAME_COMPLETE;
if (IsFrameTreeTooDeep(aReflowState, aMetrics, aStatus)) {
return NS_OK;
}

View File

@ -3293,12 +3293,13 @@ nsresult nsPluginInstanceOwner::EnsureCachedAttrParamArrays()
// Nav 4.x would simply replace the "data" with "src". Because some plugins correctly
// look for "data", lets instead copy the "data" attribute and add another entry
// to the bottom of the array if there isn't already a "src" specified.
PRInt16 numRealAttrs = mNumCachedAttrs;
PRUint16 numRealAttrs = mNumCachedAttrs;
nsAutoString data;
nsIAtom *tag = content->Tag();
if (nsHTMLAtoms::object == tag
&& !content->HasAttr(kNameSpaceID_None, nsHTMLAtoms::src)
&& NS_CONTENT_ATTR_NOT_THERE != content->GetAttr(kNameSpaceID_None, nsHTMLAtoms::data, data)) {
&& NS_CONTENT_ATTR_NOT_THERE != content->GetAttr(kNameSpaceID_None, nsHTMLAtoms::data, data)
&& !data.IsEmpty()) {
mNumCachedAttrs++;
}
@ -3309,7 +3310,7 @@ nsresult nsPluginInstanceOwner::EnsureCachedAttrParamArrays()
NS_ENSURE_TRUE(mCachedAttrParamValues, NS_ERROR_OUT_OF_MEMORY);
// let's fill in our attributes
PRInt16 c = 0;
PRUint32 nextAttrParamIndex = 0;
// Some plugins (eg Flash, see bug 234675.) are actually sensitive to the
// attribute order. So we want to make sure we give the plugin the
@ -3317,7 +3318,7 @@ nsresult nsPluginInstanceOwner::EnsureCachedAttrParamArrays()
// other browsers. Now in HTML, the storage order is the reverse of the
// source order, while in XML and XHTML it's the same as the source order
// (see the AddAttributes functions in the HTML and XML content sinks).
PRInt16 start, end, increment;
PRInt32 start, end, increment;
if (content->IsContentOfType(nsIContent::eHTML) &&
content->GetNodeInfo()->NamespaceEquals(kNameSpaceID_None)) {
// HTML. Walk attributes in reverse order.
@ -3330,7 +3331,7 @@ nsresult nsPluginInstanceOwner::EnsureCachedAttrParamArrays()
end = numRealAttrs;
increment = 1;
}
for (PRInt16 index = start; index != end; index += increment) {
for (PRInt32 index = start; index != end; index += increment) {
PRInt32 nameSpaceID;
nsCOMPtr<nsIAtom> atom;
nsCOMPtr<nsIAtom> prefix;
@ -3344,25 +3345,26 @@ nsresult nsPluginInstanceOwner::EnsureCachedAttrParamArrays()
mOwner->FixUpURLS(name, value);
mCachedAttrParamNames [c] = ToNewUTF8String(name);
mCachedAttrParamValues[c] = ToNewUTF8String(value);
c++;
mCachedAttrParamNames [nextAttrParamIndex] = ToNewUTF8String(name);
mCachedAttrParamValues[nextAttrParamIndex] = ToNewUTF8String(value);
nextAttrParamIndex++;
}
}
// if the conditions above were met, copy the "data" attribute to a "src" array entry
if (data.Length()) {
mCachedAttrParamNames [mNumCachedAttrs-1] = ToNewUTF8String(NS_LITERAL_STRING("SRC"));
mCachedAttrParamValues[mNumCachedAttrs-1] = ToNewUTF8String(data);
if (!data.IsEmpty()) {
mCachedAttrParamNames [nextAttrParamIndex] = ToNewUTF8String(NS_LITERAL_STRING("SRC"));
mCachedAttrParamValues[nextAttrParamIndex] = ToNewUTF8String(data);
nextAttrParamIndex++;
}
// add our PARAM and null separator
mCachedAttrParamNames [mNumCachedAttrs] = ToNewUTF8String(NS_LITERAL_STRING("PARAM"));
mCachedAttrParamValues[mNumCachedAttrs] = nsnull;
mCachedAttrParamNames [nextAttrParamIndex] = ToNewUTF8String(NS_LITERAL_STRING("PARAM"));
mCachedAttrParamValues[nextAttrParamIndex] = nsnull;
nextAttrParamIndex++;
// now fill in the PARAM name/value pairs from the cached DOM nodes
c = 0;
for (PRInt16 idx = 0; idx < mNumCachedParams; idx++) {
for (PRUint16 idx = 0; idx < mNumCachedParams; idx++) {
nsCOMPtr<nsIDOMElement> param = do_QueryElementAt(ourParams, idx);
if (param) {
nsAutoString name;
@ -3384,9 +3386,9 @@ nsresult nsPluginInstanceOwner::EnsureCachedAttrParamArrays()
*/
name.Trim(" \n\r\t\b", PR_TRUE, PR_TRUE, PR_FALSE);
value.Trim(" \n\r\t\b", PR_TRUE, PR_TRUE, PR_FALSE);
mCachedAttrParamNames [mNumCachedAttrs + 1 + c] = ToNewUTF8String(name);
mCachedAttrParamValues[mNumCachedAttrs + 1 + c] = ToNewUTF8String(value);
c++; // rules!
mCachedAttrParamNames [nextAttrParamIndex] = ToNewUTF8String(name);
mCachedAttrParamValues[nextAttrParamIndex] = ToNewUTF8String(value);
nextAttrParamIndex++;
}
}

View File

@ -6312,6 +6312,9 @@ nsTypedSelection::Collapse(nsIDOMNode* aParentNode, PRInt32 aOffset)
return NS_ERROR_INVALID_ARG;
if (!mFrameSelection)
return NS_ERROR_NOT_INITIALIZED; // Can't do selection
nsCOMPtr<nsIDOMNode> kungfuDeathGrip = aParentNode;
mFrameSelection->InvalidateDesiredX();
if (!IsValidSelectionPoint(mFrameSelection, aParentNode))
return NS_ERROR_FAILURE;

View File

@ -1495,10 +1495,11 @@ CSSLoaderImpl::SheetComplete(SheetLoadData* aLoadData, PRBool aSucceeded)
data = data->mNext;
}
// Now that it's marked complete, put the sheet in our cache
// Now that it's marked complete, put the sheet in our cache, but
// only if we parsed it case-sensitively.
if (aSucceeded && aLoadData->mURI) {
#ifdef MOZ_XUL
if (IsChromeURI(aLoadData->mURI)) {
if (IsChromeURI(aLoadData->mURI) && mCaseSensitive) {
nsCOMPtr<nsIXULPrototypeCache> cache(do_GetService("@mozilla.org/xul/xul-prototype-cache;1"));
if (cache) {
PRBool enabled;

View File

@ -324,7 +324,9 @@ nsTableCellMap::Synchronize(nsTableFrame* aTableFrame)
if (map) {
if (!maps.AppendElement(map)) {
delete map;
map = nsnull;
NS_WARNING("Could not AppendElement");
break;
}
}
}

View File

@ -1194,6 +1194,9 @@ nsListBoxBodyFrame::GetNextItemBox(nsIBox* aBox, PRInt32 aOffset,
nsIFrame* existingFrame = nsnull;
mPresContext->GetPresShell()->GetPrimaryFrameFor(nextContent, &existingFrame);
if (existingFrame && existingFrame->GetParent() != this)
return GetNextItemBox(aBox, ++aOffset, aCreated);
if (!existingFrame) {
// Either append the new frame, or insert it after the current frame
@ -1450,14 +1453,14 @@ void
nsListBoxBodyFrame::RemoveChildFrame(nsBoxLayoutState &aState,
nsIFrame *aFrame)
{
if (!mFrames.ContainsFrame(aFrame)) {
NS_ERROR("tried to remove a child frame which isn't our child");
return;
}
mFrameConstructor->RemoveMappingsForFrameSubtree(aFrame, nsnull);
#ifdef DEBUG
PRBool removed =
#endif
mFrames.RemoveFrame(aFrame);
NS_ASSERTION(removed,
"Going to destroy a frame we didn't remove. Prepare to crash");
mFrames.RemoveFrame(aFrame);
if (mLayoutManager)
mLayoutManager->ChildrenRemoved(this, aState, aFrame);
aFrame->Destroy(mPresContext);

View File

@ -144,3 +144,14 @@ interface nsITreeSelection : nsISupports
*/
readonly attribute long shiftSelectPivot;
};
/**
* The following interface is not scriptable and MUST NEVER BE MADE scriptable.
* Native treeselections implement it, and we use this to check whether a
* treeselection is native (and therefore suitable for use by untrusted content).
*/
[uuid(1bd59678-5cb3-4316-b246-31a91b19aabe)]
interface nsINativeTreeSelection : nsITreeSelection
{
[noscript] void ensureNative();
};

View File

@ -47,6 +47,8 @@
#include "nsIDOMClassInfo.h"
#include "nsIEventStateManager.h"
#include "nsINodeInfo.h"
#include "nsContentUtils.h"
#include "nsDOMError.h"
// A content model view implementation for the tree.
@ -185,9 +187,22 @@ nsTreeContentView::GetSelection(nsITreeSelection** aSelection)
return NS_OK;
}
PRBool
nsTreeContentView::CanTrustTreeSelection(nsISupports* aValue)
{
// Untrusted content is only allowed to specify known-good views
if (nsContentUtils::IsCallerTrustedForWrite())
return PR_TRUE;
nsCOMPtr<nsINativeTreeSelection> nativeTreeSel = do_QueryInterface(aValue);
return nativeTreeSel && NS_SUCCEEDED(nativeTreeSel->EnsureNative());
}
NS_IMETHODIMP
nsTreeContentView::SetSelection(nsITreeSelection* aSelection)
{
NS_ENSURE_TRUE(!aSelection || CanTrustTreeSelection(aSelection),
NS_ERROR_DOM_SECURITY_ERR);
mSelection = aSelection;
if (mUpdateSelection) {
@ -969,9 +984,14 @@ nsTreeContentView::ContentInserted(nsIDocument *aDocument,
}
else if (childTag == nsHTMLAtoms::option) {
PRInt32 parentIndex = FindContent(aContainer);
PRInt32 count = InsertRow(parentIndex, aIndexInContainer, aChild);
if (mBoxObject)
mBoxObject->RowCountChanged(parentIndex + aIndexInContainer + 1, count);
if (parentIndex >= 0) {
PRInt32 index = 0;
GetIndexInSubtree(aContainer, aChild, &index);
PRInt32 count = InsertRow(parentIndex, index, aChild);
if (mBoxObject)
mBoxObject->RowCountChanged(parentIndex + index + 1, count);
}
}
}

View File

@ -88,6 +88,8 @@ class nsTreeContentView : public nsINativeTreeView,
nsIContent* aChild, PRInt32 aIndexInContainer);
virtual void DocumentWillBeDestroyed(nsIDocument *aDocument);
static PRBool CanTrustTreeSelection(nsISupports* aValue);
protected:
// Recursive methods which deal with serializing of nested content.
void Serialize(nsIContent* aContent, PRInt32 aParentIndex, PRInt32* aIndex, nsVoidArray& aRows);

View File

@ -54,6 +54,7 @@
#include "nsINameSpaceManager.h"
#include "nsXULAtoms.h"
#include "nsPLDOMEvent.h"
#include "nsTArray.h"
// A helper class for managing our ranges of selection.
struct nsTreeRange
@ -212,17 +213,39 @@ struct nsTreeRange
return total;
};
static void CollectRanges(nsTreeRange* aRange, nsTArray<PRInt32>& aRanges)
{
nsTreeRange* cur = aRange;
while (cur) {
aRanges.AppendElement(cur->mMin);
aRanges.AppendElement(cur->mMax);
cur = cur->mNext;
}
}
static void InvalidateRanges(nsITreeBoxObject* aTree,
nsTArray<PRInt32>& aRanges)
{
if (aTree) {
nsCOMPtr<nsITreeBoxObject> tree = aTree;
for (PRUint32 i = 0; i < aRanges.Length(); i += 2) {
aTree->InvalidateRange(aRanges[i], aRanges[i + 1]);
}
}
}
void Invalidate() {
mSelection->mTree->InvalidateRange(mMin, mMax);
if (mNext)
mNext->Invalidate();
nsTArray<PRInt32> ranges;
CollectRanges(this, ranges);
InvalidateRanges(mSelection->mTree, ranges);
};
void RemoveAllBut(PRInt32 aIndex) {
if (aIndex >= mMin && aIndex <= mMax) {
// Invalidate everything in this list.
mSelection->mFirstRange->Invalidate();
nsTArray<PRInt32> ranges;
CollectRanges(mSelection->mFirstRange, ranges);
mMin = aIndex;
mMax = aIndex;
@ -238,6 +261,7 @@ struct nsTreeRange
delete mSelection->mFirstRange;
mSelection->mFirstRange = this;
}
InvalidateRanges(mSelection->mTree, ranges);
}
else if (mNext)
mNext->RemoveAllBut(aIndex);
@ -272,6 +296,7 @@ nsTreeSelection::~nsTreeSelection()
// QueryInterface implementation for nsBoxObject
NS_INTERFACE_MAP_BEGIN(nsTreeSelection)
NS_INTERFACE_MAP_ENTRY(nsITreeSelection)
NS_INTERFACE_MAP_ENTRY(nsINativeTreeSelection)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_ENTRY_DOM_CLASSINFO(TreeSelection)
NS_INTERFACE_MAP_END
@ -281,8 +306,7 @@ NS_IMPL_RELEASE(nsTreeSelection)
NS_IMETHODIMP nsTreeSelection::GetTree(nsITreeBoxObject * *aTree)
{
NS_IF_ADDREF(mTree);
*aTree = mTree;
NS_IF_ADDREF(*aTree = mTree);
return NS_OK;
}
@ -292,13 +316,20 @@ NS_IMETHODIMP nsTreeSelection::SetTree(nsITreeBoxObject * aTree)
mSelectTimer->Cancel();
mSelectTimer = nsnull;
}
mTree = aTree; // WEAK
// Make sure aTree really implements nsITreeBoxObject!
mTree = do_QueryInterface(aTree);
NS_ENSURE_STATE(mTree || !aTree);
return NS_OK;
}
NS_IMETHODIMP nsTreeSelection::GetSingle(PRBool* aSingle)
{
if (!mTree)
return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIBoxObject> boxObject = do_QueryInterface(mTree);
NS_ENSURE_STATE(boxObject);
nsCOMPtr<nsIDOMElement> element;
boxObject->GetElement(getter_AddRefs(element));
nsCOMPtr<nsIContent> content = do_QueryInterface(element);
@ -399,8 +430,8 @@ NS_IMETHODIMP nsTreeSelection::ToggleSelect(PRInt32 aIndex)
else {
if (!mFirstRange->Contains(aIndex)) {
PRBool single;
GetSingle(&single);
if (!single)
rv = GetSingle(&single);
if (NS_SUCCEEDED(rv) && !single)
rv = mFirstRange->Add(aIndex);
}
else
@ -418,7 +449,10 @@ NS_IMETHODIMP nsTreeSelection::ToggleSelect(PRInt32 aIndex)
NS_IMETHODIMP nsTreeSelection::RangedSelect(PRInt32 aStartIndex, PRInt32 aEndIndex, PRBool aAugment)
{
PRBool single;
GetSingle(&single);
nsresult rv = GetSingle(&single);
if (NS_FAILED(rv))
return rv;
if ((mFirstRange || (aStartIndex != aEndIndex)) && single)
return NS_OK;
@ -427,6 +461,7 @@ NS_IMETHODIMP nsTreeSelection::RangedSelect(PRInt32 aStartIndex, PRInt32 aEndInd
if (mFirstRange) {
mFirstRange->Invalidate();
delete mFirstRange;
mFirstRange = nsnull;
}
}
@ -503,6 +538,10 @@ NS_IMETHODIMP nsTreeSelection::InvertSelection()
NS_IMETHODIMP nsTreeSelection::SelectAll()
{
if (!mTree) {
return NS_OK;
}
nsCOMPtr<nsITreeView> view;
mTree->GetView(getter_AddRefs(view));
if (!view)
@ -511,7 +550,10 @@ NS_IMETHODIMP nsTreeSelection::SelectAll()
PRInt32 rowCount;
view->GetRowCount(&rowCount);
PRBool single;
GetSingle(&single);
nsresult rv = GetSingle(&single);
if (NS_FAILED(rv))
return rv;
if (rowCount == 0 || (rowCount > 1 && single))
return NS_OK;
@ -592,6 +634,9 @@ NS_IMETHODIMP nsTreeSelection::GetCurrentIndex(PRInt32 *aCurrentIndex)
NS_IMETHODIMP nsTreeSelection::SetCurrentIndex(PRInt32 aIndex)
{
if (!mTree)
return NS_ERROR_NULL_POINTER;
if (mCurrentIndex == aIndex) {
return NS_OK;
}
@ -633,7 +678,12 @@ NS_IMETHODIMP nsTreeSelection::SetCurrentIndex(PRInt32 aIndex)
#define ADD_NEW_RANGE(macro_range, macro_selection, macro_start, macro_end) \
{ \
nsTreeRange* macro_new_range = new nsTreeRange(macro_selection, (macro_start), (macro_end)); \
PRInt32 start = macro_start; \
PRInt32 end = macro_end; \
if (start > end) { \
end = start; \
} \
nsTreeRange* macro_new_range = new nsTreeRange(macro_selection, start, end); \
if (macro_range) \
macro_range->Insert(macro_new_range); \
else \
@ -671,27 +721,27 @@ nsTreeSelection::AdjustSelection(PRInt32 aIndex, PRInt32 aCount)
// no selection, so nothing to do.
if (!mFirstRange) return NS_OK;
nsTreeRange* newRange = nsnull;
PRBool selChanged = PR_FALSE;
nsTreeRange* oldFirstRange = mFirstRange;
nsTreeRange* curr = mFirstRange;
mFirstRange = nsnull;
while (curr) {
if (aCount > 0) {
// inserting
if (aIndex > curr->mMax) {
// adjustment happens after the range, so no change
ADD_NEW_RANGE(newRange, this, curr->mMin, curr->mMax);
ADD_NEW_RANGE(mFirstRange, this, curr->mMin, curr->mMax);
}
else if (aIndex <= curr->mMin) {
// adjustment happens before the start of the range, so shift down
ADD_NEW_RANGE(newRange, this, curr->mMin + aCount, curr->mMax + aCount);
ADD_NEW_RANGE(mFirstRange, this, curr->mMin + aCount, curr->mMax + aCount);
selChanged = PR_TRUE;
}
else {
// adjustment happen inside the range.
// break apart the range and create two ranges
ADD_NEW_RANGE(newRange, this, curr->mMin, aIndex - 1);
ADD_NEW_RANGE(newRange, this, aIndex + aCount, curr->mMax + aCount);
ADD_NEW_RANGE(mFirstRange, this, curr->mMin, aIndex - 1);
ADD_NEW_RANGE(mFirstRange, this, aIndex + aCount, curr->mMax + aCount);
selChanged = PR_TRUE;
}
}
@ -699,7 +749,7 @@ nsTreeSelection::AdjustSelection(PRInt32 aIndex, PRInt32 aCount)
// deleting
if (aIndex > curr->mMax) {
// adjustment happens after the range, so no change
ADD_NEW_RANGE(newRange, this, curr->mMin, curr->mMax);
ADD_NEW_RANGE(mFirstRange, this, curr->mMin, curr->mMax);
}
else {
// remember, aCount is negative
@ -708,31 +758,30 @@ nsTreeSelection::AdjustSelection(PRInt32 aIndex, PRInt32 aCount)
if (aIndex <= curr->mMin) {
if (lastIndexOfAdjustment < curr->mMin) {
// adjustment happens before the start of the range, so shift up
ADD_NEW_RANGE(newRange, this, curr->mMin + aCount, curr->mMax + aCount);
ADD_NEW_RANGE(mFirstRange, this, curr->mMin + aCount, curr->mMax + aCount);
}
else if (lastIndexOfAdjustment >= curr->mMax) {
// adjustment contains the range. remove the range by not adding it to the newRange
}
else {
// adjustment starts before the range, and ends in the middle of it, so trim the range
ADD_NEW_RANGE(newRange, this, aIndex, curr->mMax + aCount)
ADD_NEW_RANGE(mFirstRange, this, aIndex, curr->mMax + aCount)
}
}
else if (lastIndexOfAdjustment >= curr->mMax) {
// adjustment starts in the middle of the current range, and contains the end of the range, so trim the range
ADD_NEW_RANGE(newRange, this, curr->mMin, aIndex - 1)
ADD_NEW_RANGE(mFirstRange, this, curr->mMin, aIndex - 1)
}
else {
// range contains the adjustment, so shorten the range
ADD_NEW_RANGE(newRange, this, curr->mMin, curr->mMax + aCount)
ADD_NEW_RANGE(mFirstRange, this, curr->mMin, curr->mMax + aCount)
}
}
}
curr = curr->mNext;
}
delete mFirstRange;
mFirstRange = newRange;
delete oldFirstRange;
// Fire the select event
if (selChanged)
@ -760,7 +809,7 @@ nsTreeSelection::GetShiftSelectPivot(PRInt32* aIndex)
nsresult
nsTreeSelection::FireOnSelectHandler()
{
if (mSuppressed)
if (mSuppressed || !mTree)
return NS_OK;
nsCOMPtr<nsIBoxObject> boxObject = do_QueryInterface(mTree);

View File

@ -48,7 +48,7 @@
class nsITreeBoxObject;
struct nsTreeRange;
class nsTreeSelection : public nsITreeSelection
class nsTreeSelection : public nsINativeTreeSelection
{
public:
nsTreeSelection(nsITreeBoxObject* aTree);
@ -57,6 +57,9 @@ public:
NS_DECL_ISUPPORTS
NS_DECL_NSITREESELECTION
// nsINativeTreeSelection: Untrusted code can use us
NS_IMETHOD EnsureNative() { return NS_OK; }
friend struct nsTreeRange;
protected:
@ -65,7 +68,7 @@ protected:
protected:
// Members
nsITreeBoxObject* mTree; // [Weak]. The tree will hold on to us through the view and let go when it dies.
nsCOMPtr<nsITreeBoxObject> mTree; // The tree will hold on to us through the view and let go when it dies.
PRBool mSuppressed; // Whether or not we should be firing onselect events.
PRInt32 mCurrentIndex; // The item to draw the rect around. The last one clicked, etc.

View File

@ -3153,19 +3153,19 @@ nsresult nsAddrDatabase::GetListFromDB(nsIAbDirectory *newList, nsIMdbRow* listR
return err;
}
class nsAddrDBEnumerator : public nsIEnumerator
class nsAddrDBEnumerator : public nsIEnumerator, public nsIAddrDBListener
{
public:
NS_DECL_ISUPPORTS
// nsIEnumerator methods:
NS_DECL_NSIENUMERATOR
NS_DECL_NSIADDRDBLISTENER
// nsAddrDBEnumerator methods:
nsAddrDBEnumerator(nsAddrDatabase* db);
virtual ~nsAddrDBEnumerator();
void Clear();
protected:
nsCOMPtr<nsAddrDatabase> mDB;
nsCOMPtr<nsIAbDirectory> mResultList;
@ -3183,14 +3183,25 @@ nsAddrDBEnumerator::nsAddrDBEnumerator(nsAddrDatabase* db)
{
mDbTable = mDB->GetPabTable();
mCurrentRowIsList = PR_FALSE;
if (mDB)
mDB->AddListener(this);
}
nsAddrDBEnumerator::~nsAddrDBEnumerator()
{
NS_IF_RELEASE(mRowCursor);
Clear();
}
NS_IMPL_ISUPPORTS1(nsAddrDBEnumerator, nsIEnumerator)
void nsAddrDBEnumerator::Clear()
{
NS_IF_RELEASE(mRowCursor);
mCurrentRow = nsnull;
mDbTable = nsnull;
if (mDB)
mDB->RemoveListener(this);
}
NS_IMPL_ISUPPORTS2(nsAddrDBEnumerator, nsIEnumerator, nsIAddrDBListener)
NS_IMETHODIMP nsAddrDBEnumerator::First(void)
{
@ -3277,6 +3288,30 @@ NS_IMETHODIMP nsAddrDBEnumerator::IsDone(void)
return mDone ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP nsAddrDBEnumerator::OnCardAttribChange(PRUint32 abCode)
{
return NS_OK;
}
/* void onCardEntryChange (in unsigned long aAbCode, in nsIAbCard aCard, in nsIAbDirectory aParent); */
NS_IMETHODIMP nsAddrDBEnumerator::OnCardEntryChange(PRUint32 aAbCode, nsIAbCard *aCard)
{
return NS_OK;
}
/* void onListEntryChange (in unsigned long abCode, in nsIAbDirectory list); */
NS_IMETHODIMP nsAddrDBEnumerator::OnListEntryChange(PRUint32 abCode, nsIAbDirectory *list)
{
return NS_OK;
}
/* void onAnnouncerGoingAway (); */
NS_IMETHODIMP nsAddrDBEnumerator::OnAnnouncerGoingAway()
{
Clear();
return NS_OK;
}
class nsListAddressEnumerator : public nsIEnumerator
{
public:

View File

@ -553,6 +553,7 @@ nsMsgFilter::MatchHdr(nsIMsgDBHdr *msgHdr, nsIMsgFolder *folder,
PRUint32 headersSize, PRBool *pResult)
{
NS_ENSURE_ARG_POINTER(folder);
NS_ENSURE_ARG_POINTER(msgHdr);
// use offlineMail because
nsXPIDLCString folderCharset;
folder->GetCharset(getter_Copies(folderCharset));

View File

@ -427,6 +427,8 @@ nsresult nsMsgQuickSearchDBView::SortThreads(nsMsgViewSortTypeValue sortType, ns
continue;
// it would be nice if GetInsertIndexHelper always found the hdr, but it doesn't.
threadHdr->GetChildHdrAt(0, getter_AddRefs(rootHdr));
if (!rootHdr)
continue;
threadRootIndex = GetInsertIndexHelper(rootHdr, &threadRootIds, nsMsgViewSortOrder::ascending, nsMsgViewSortType::byId);
threadRootIds.InsertAt(threadRootIndex, rootKey);
}

Some files were not shown because too many files have changed in this diff Show More