Bug 602115: Fix XSLT error handling bugs. r=peterv a=blocker

This commit is contained in:
Jonas Sicking 2010-12-13 14:24:55 -08:00
parent 6b35ad02ad
commit f6326825f7
5 changed files with 55 additions and 53 deletions

View File

@ -0,0 +1,22 @@
<!DOCTYPE html>
<script>
try {
var docType = document.implementation.createDocumentType(undefined, '', '');
var doc = document.implementation.createDocument('', '', null);
var xp = new XSLTProcessor;
xp.importStylesheet(doc);
xp.transformToDocument(docType);
}
catch (ex) {}
try {
docType = document.implementation.createDocumentType(undefined, '', '');
doc = document.implementation.createDocument('', '', null);
xp = new XSLTProcessor;
xp.importStylesheet(doc);
xp.transformToFragment(docType, document);
}
catch (ex) {}
</script>

View File

@ -11,3 +11,4 @@ load 528488.xml
load 528963.xml
load 545927.html
load 601543.html
load 602115.html

View File

@ -90,9 +90,6 @@ txExecutionState::txExecutionState(txStylesheet* aStylesheet,
mNextInstruction(nsnull),
mLocalVariables(nsnull),
mRecursionDepth(0),
mTemplateRules(nsnull),
mTemplateRulesBufferSize(0),
mTemplateRuleCount(0),
mEvalContext(nsnull),
mInitialEvalContext(nsnull),
mGlobalParams(nsnull),
@ -109,12 +106,6 @@ txExecutionState::~txExecutionState()
delete mResultHandler;
delete mLocalVariables;
delete mEvalContext;
PRInt32 i;
for (i = 0; i < mTemplateRuleCount; ++i) {
NS_IF_RELEASE(mTemplateRules[i].mModeLocalName);
}
delete [] mTemplateRules;
txStackIterator varsIter(&mLocalVarsStack);
while (varsIter.hasNext()) {
@ -195,8 +186,7 @@ txExecutionState::init(const txXPathNode& aNode,
txExpandedName nullName;
txInstruction* templ = mStylesheet->findTemplate(aNode, nullName,
this, nsnull, &frame);
rv = pushTemplateRule(frame, nullName, nsnull);
NS_ENSURE_SUCCESS(rv, rv);
pushTemplateRule(frame, nullName, nsnull);
return runTemplate(templ);
}
@ -204,7 +194,11 @@ txExecutionState::init(const txXPathNode& aNode,
nsresult
txExecutionState::end(nsresult aResult)
{
popTemplateRule();
NS_ASSERTION(NS_FAILED(aResult) || mTemplateRules.Length() == 1,
"Didn't clean up template rules properly");
if (NS_SUCCEEDED(aResult)) {
popTemplateRule();
}
return mOutputHandler->endDocument(aResult);
}
@ -293,9 +287,7 @@ txExecutionState::getVariable(PRInt32 aNamespace, nsIAtom* aLName,
rv = runTemplate(var->mFirstInstruction);
NS_ENSURE_SUCCESS(rv, rv);
rv = pushTemplateRule(nsnull, txExpandedName(), nsnull);
NS_ENSURE_SUCCESS(rv, rv);
pushTemplateRule(nsnull, txExpandedName(), nsnull);
rv = txXSLTProcessor::execute(*this);
NS_ENSURE_SUCCESS(rv, rv);
@ -403,40 +395,23 @@ txExecutionState::popResultHandler()
return oldHandler;
}
nsresult
void
txExecutionState::pushTemplateRule(txStylesheet::ImportFrame* aFrame,
const txExpandedName& aMode,
txVariableMap* aParams)
{
if (mTemplateRuleCount == mTemplateRulesBufferSize) {
PRInt32 newSize =
mTemplateRulesBufferSize ? mTemplateRulesBufferSize * 2 : 10;
TemplateRule* newRules = new TemplateRule[newSize];
NS_ENSURE_TRUE(newRules, NS_ERROR_OUT_OF_MEMORY);
memcpy(newRules, mTemplateRules,
mTemplateRuleCount * sizeof(TemplateRule));
delete [] mTemplateRules;
mTemplateRules = newRules;
mTemplateRulesBufferSize = newSize;
}
mTemplateRules[mTemplateRuleCount].mFrame = aFrame;
mTemplateRules[mTemplateRuleCount].mModeNsId = aMode.mNamespaceID;
mTemplateRules[mTemplateRuleCount].mModeLocalName = aMode.mLocalName;
mTemplateRules[mTemplateRuleCount].mParams = aParams;
NS_IF_ADDREF(mTemplateRules[mTemplateRuleCount].mModeLocalName);
++mTemplateRuleCount;
return NS_OK;
TemplateRule* rule = mTemplateRules.AppendElement();
rule->mFrame = aFrame;
rule->mModeNsId = aMode.mNamespaceID;
rule->mModeLocalName = aMode.mLocalName;
rule->mParams = aParams;
}
void
txExecutionState::popTemplateRule()
{
// decrement outside of RELEASE, that would decrement twice
--mTemplateRuleCount;
NS_IF_RELEASE(mTemplateRules[mTemplateRuleCount].mModeLocalName);
NS_PRECONDITION(!mTemplateRules.IsEmpty(), "No rules to pop");
mTemplateRules.RemoveElementAt(mTemplateRules.Length() - 1);
}
txIEvalContext*
@ -497,7 +472,8 @@ txExecutionState::getKeyNodes(const txExpandedName& aKeyName,
txExecutionState::TemplateRule*
txExecutionState::getCurrentTemplateRule()
{
return mTemplateRules + mTemplateRuleCount - 1;
NS_PRECONDITION(!mTemplateRules.IsEmpty(), "No current rule!");
return &mTemplateRules[mTemplateRules.Length() - 1];
}
txInstruction*

View File

@ -112,10 +112,11 @@ public:
/**
* Struct holding information about a current template rule
*/
struct TemplateRule {
class TemplateRule {
public:
txStylesheet::ImportFrame* mFrame;
PRInt32 mModeNsId;
nsIAtom* mModeLocalName;
nsCOMPtr<nsIAtom> mModeLocalName;
txVariableMap* mParams;
};
@ -126,9 +127,9 @@ public:
PRBool popBool();
nsresult pushResultHandler(txAXMLEventHandler* aHandler);
txAXMLEventHandler* popResultHandler();
nsresult pushTemplateRule(txStylesheet::ImportFrame* aFrame,
const txExpandedName& aMode,
txVariableMap* aParams);
void pushTemplateRule(txStylesheet::ImportFrame* aFrame,
const txExpandedName& aMode,
txVariableMap* aParams);
void popTemplateRule();
nsresult pushParamMap(txVariableMap* aParams);
txVariableMap* popParamMap();
@ -181,9 +182,7 @@ private:
nsRefPtr<txAExprResult> mGlobalVarPlaceholderValue;
PRInt32 mRecursionDepth;
TemplateRule* mTemplateRules;
PRInt32 mTemplateRulesBufferSize;
PRInt32 mTemplateRuleCount;
AutoInfallibleTArray<TemplateRule, 10> mTemplateRules;
txIEvalContext* mEvalContext;
txIEvalContext* mInitialEvalContext;

View File

@ -682,10 +682,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);
}
nsresult endRv = es.end(rv);
if (NS_SUCCEEDED(rv)) {
@ -741,10 +743,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
nsresult endRv = es.end(rv);
if (NS_SUCCEEDED(rv)) {