Bug 553905 - data parser should parse up to a failure and not scrap the whole path. r=jwatt

This commit is contained in:
Robert Longson 2010-04-08 09:58:04 +01:00
Родитель e795dc9e4c
Коммит 48f9a70c28
10 изменённых файлов: 33 добавлений и 30 удалений

Просмотреть файл

@ -61,8 +61,6 @@
nsresult nsresult
nsSVGDataParser::Parse(const nsAString &aValue) nsSVGDataParser::Parse(const nsAString &aValue)
{ {
nsresult rv = NS_OK;
char *str = ToNewUTF8String(aValue); char *str = ToNewUTF8String(aValue);
if (!str) if (!str)
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
@ -70,7 +68,7 @@ nsSVGDataParser::Parse(const nsAString &aValue)
mInputPos = str; mInputPos = str;
GetNextToken(); GetNextToken();
rv = Match(); nsresult rv = Match();
if (mTokenType != END) if (mTokenType != END)
rv = NS_ERROR_FAILURE; // not all tokens were consumed rv = NS_ERROR_FAILURE; // not all tokens were consumed
@ -85,8 +83,8 @@ nsSVGDataParser::Parse(const nsAString &aValue)
void nsSVGDataParser::GetNextToken() void nsSVGDataParser::GetNextToken()
{ {
mTokenPos = mInputPos; mTokenPos = mInputPos;
mTokenVal = *mInputPos; mTokenVal = *mInputPos;
switch (mTokenVal) { switch (mTokenVal) {
case '0': case '1': case '2': case '3': case '4': case '0': case '1': case '2': case '3': case '4':
@ -129,12 +127,6 @@ void nsSVGDataParser::RewindTo(const char* aPos)
GetNextToken(); GetNextToken();
} }
nsresult nsSVGDataParser::Match()
{
return NS_OK;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
nsresult nsSVGDataParser::MatchNonNegativeNumber(float* aX) nsresult nsSVGDataParser::MatchNonNegativeNumber(float* aX)

Просмотреть файл

@ -63,7 +63,7 @@ protected:
// helpers // helpers
void GetNextToken(); void GetNextToken();
void RewindTo(const char* aPos); void RewindTo(const char* aPos);
virtual nsresult Match(); virtual nsresult Match()=0;
nsresult MatchNonNegativeNumber(float* aX); nsresult MatchNonNegativeNumber(float* aX);
PRBool IsTokenNonNegativeNumberStarter(); PRBool IsTokenNonNegativeNumberStarter();

Просмотреть файл

@ -878,10 +878,8 @@ nsSVGPathDataParserToInternal::Parse(const nsAString &aValue)
mPrevSeg = nsIDOMSVGPathSeg::PATHSEG_UNKNOWN; mPrevSeg = nsIDOMSVGPathSeg::PATHSEG_UNKNOWN;
nsresult rv = nsSVGPathDataParser::Parse(aValue); nsresult rv = nsSVGPathDataParser::Parse(aValue);
NS_ENSURE_SUCCESS(rv, rv);
rv = PathFini(); PathFini();
NS_ENSURE_SUCCESS(rv, rv);
return rv; return rv;
} }
@ -1214,7 +1212,7 @@ nsSVGPathDataParserToInternal::PathClose()
return NS_OK; return NS_OK;
} }
nsresult void
nsSVGPathDataParserToInternal::PathFini() nsSVGPathDataParserToInternal::PathFini()
{ {
// We're done adding data to the arrays - copy to a straight array // We're done adding data to the arrays - copy to a straight array
@ -1226,7 +1224,7 @@ nsSVGPathDataParserToInternal::PathFini()
argArraySize = mArguments.Length() * sizeof(float); argArraySize = mArguments.Length() * sizeof(float);
mPathData->mArguments = (float *)malloc(argArraySize + mCommands.Length()); mPathData->mArguments = (float *)malloc(argArraySize + mCommands.Length());
if (!mPathData->mArguments) if (!mPathData->mArguments)
return NS_ERROR_OUT_OF_MEMORY; return;
memcpy(mPathData->mArguments, mArguments.Elements(), argArraySize); memcpy(mPathData->mArguments, mArguments.Elements(), argArraySize);
memcpy(mPathData->mArguments + mNumArguments, memcpy(mPathData->mArguments + mNumArguments,
@ -1234,8 +1232,6 @@ nsSVGPathDataParserToInternal::PathFini()
mCommands.Length()); mCommands.Length());
mPathData->mNumArguments = mNumArguments; mPathData->mNumArguments = mNumArguments;
mPathData->mNumCommands = mNumCommands; mPathData->mNumCommands = mNumCommands;
return NS_OK;
} }
// --------------------------------------------------------------- // ---------------------------------------------------------------

Просмотреть файл

@ -72,7 +72,7 @@ protected:
virtual nsresult StoreEllipticalArc(PRBool absCoords, float x, float y, virtual nsresult StoreEllipticalArc(PRBool absCoords, float x, float y,
float r1, float r2, float angle, float r1, float r2, float angle,
PRBool largeArcFlag, PRBool sweepFlag) = 0; PRBool largeArcFlag, PRBool sweepFlag) = 0;
nsresult Match(); virtual nsresult Match();
nsresult MatchCoordPair(float* aX, float* aY); nsresult MatchCoordPair(float* aX, float* aY);
PRBool IsTokenCoordPairStarter(); PRBool IsTokenCoordPairStarter();
@ -144,7 +144,7 @@ class nsSVGPathDataParserToInternal : public nsSVGPathDataParser
{ {
public: public:
nsSVGPathDataParserToInternal(nsSVGPathList *data) : mPathData(data) {} nsSVGPathDataParserToInternal(nsSVGPathList *data) : mPathData(data) {}
virtual nsresult Parse(const nsAString &aValue); nsresult Parse(const nsAString &aValue);
protected: protected:
virtual nsresult StoreMoveTo(PRBool absCoords, float x, float y); virtual nsresult StoreMoveTo(PRBool absCoords, float x, float y);
@ -187,7 +187,7 @@ private:
nsresult PathLineTo(float x, float y); nsresult PathLineTo(float x, float y);
nsresult PathCurveTo(float x1, float y1, float x2, float y2, float x3, float y3); nsresult PathCurveTo(float x1, float y1, float x2, float y2, float x3, float y3);
nsresult PathClose(); nsresult PathClose();
nsresult PathFini(); void PathFini();
}; };
class nsSVGPathDataParserToDOM : public nsSVGPathDataParser class nsSVGPathDataParserToDOM : public nsSVGPathDataParser

Просмотреть файл

@ -458,7 +458,10 @@ nsSVGPathElement::BeforeSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
if (aValue) { if (aValue) {
nsSVGPathDataParserToInternal parser(&mPathData); nsSVGPathDataParserToInternal parser(&mPathData);
parser.Parse(*aValue); nsresult rv = parser.Parse(*aValue);
if (NS_FAILED(rv)) {
ReportAttributeParseFailure(GetOwnerDoc(), aName, *aValue);
}
} else { } else {
mPathData.Clear(); mPathData.Clear();
} }

Просмотреть файл

@ -132,12 +132,10 @@ NS_INTERFACE_MAP_END
NS_IMETHODIMP NS_IMETHODIMP
nsSVGPathSegList::SetValueString(const nsAString& aValue) nsSVGPathSegList::SetValueString(const nsAString& aValue)
{ {
nsresult rv;
WillModify(); WillModify();
ReleaseSegments(PR_FALSE); ReleaseSegments(PR_FALSE);
nsSVGPathDataParserToDOM parser(&mSegments); nsSVGPathDataParserToDOM parser(&mSegments);
rv = parser.Parse(aValue); nsresult rv = parser.Parse(aValue);
PRInt32 count = mSegments.Count(); PRInt32 count = mSegments.Count();
for (PRInt32 i=0; i<count; ++i) { for (PRInt32 i=0; i<count; ++i) {

Просмотреть файл

@ -172,12 +172,10 @@ nsSVGTransformList::SetValueString(const nsAString& aValue)
// XXX: we don't implement the _exact_ BNF given in the // XXX: we don't implement the _exact_ BNF given in the
// specs. // specs.
nsresult rv = NS_OK;
// parse transform attribute value // parse transform attribute value
nsCOMArray<nsIDOMSVGTransform> xforms; nsCOMArray<nsIDOMSVGTransform> xforms;
nsSVGTransformListParser parser(&xforms); nsSVGTransformListParser parser(&xforms);
rv = parser.Parse(aValue); nsresult rv = parser.Parse(aValue);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
// there was a parse error. // there was a parse error.

Просмотреть файл

@ -60,7 +60,7 @@ private:
nsCOMArray<nsIDOMSVGTransform> *mTransform; nsCOMArray<nsIDOMSVGTransform> *mTransform;
// helpers // helpers
nsresult Match(); virtual nsresult Match();
nsresult MatchNumberArguments(float *aResult, nsresult MatchNumberArguments(float *aResult,
PRUint32 aMaxNum, PRUint32 aMaxNum,

Просмотреть файл

@ -0,0 +1,15 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/licenses/publicdomain/
-->
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
<title>Testcase for path with errors</title>
<!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=553905 -->
<rect width="100%" height="100%" fill="lime"/>
<g shape-rendering="crispEdges">
<path d="M 20 200 H 80" stroke-width="20%" stroke="red"/>
<path d="M 20 200 H 80#90" stroke-width="20%" stroke="lime"/>
</g>
</svg>

После

Ширина:  |  Высота:  |  Размер: 529 B

Просмотреть файл

@ -115,6 +115,7 @@ fails == inline-in-xul-basic-01.xul pass.svg
== opacity-and-gradient-02.svg opacity-and-gradient-02-ref.svg == opacity-and-gradient-02.svg opacity-and-gradient-02-ref.svg
== opacity-and-pattern-01.svg pass.svg == opacity-and-pattern-01.svg pass.svg
== path-01.svg path-01-ref.svg == path-01.svg path-01-ref.svg
== path-02.svg pass.svg
== pattern-live-01a.svg pattern-live-01-ref.svg == pattern-live-01a.svg pattern-live-01-ref.svg
== pattern-live-01b.svg pattern-live-01-ref.svg == pattern-live-01b.svg pattern-live-01-ref.svg
== pattern-live-01c.svg pattern-live-01-ref.svg == pattern-live-01c.svg pattern-live-01-ref.svg