Bug 672055 - Use nsCharSeparatedTokenizer to parse number-optional-number attributes. r=dholbert sr=jonas

This commit is contained in:
Robert Longson 2011-07-23 09:41:17 +01:00
Родитель 96719c555f
Коммит 0c88b8e318
6 изменённых файлов: 90 добавлений и 73 удалений

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

@ -122,7 +122,7 @@ SVGMotionSMILPathUtils::PathGenerator::
ParseCoordinatePair(const nsAString& aCoordPairStr,
float& aXVal, float& aYVal)
{
nsCharSeparatedTokenizer
nsCharSeparatedTokenizerTemplate<IsSVGWhitespace>
tokenizer(aCoordPairStr, ',',
nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);

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

@ -122,7 +122,8 @@ nsSVGFeatures::MatchesLanguagePreferences(const nsSubstring& aAttribute,
{
const nsDefaultStringComparator defaultComparator;
nsCharSeparatedTokenizer attributeTokenizer(aAttribute, ',');
nsCharSeparatedTokenizerTemplate<IsSVGWhitespace>
attributeTokenizer(aAttribute, ',');
while (attributeTokenizer.hasMoreTokens()) {
const nsSubstring &attributeToken = attributeTokenizer.nextToken();

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

@ -36,8 +36,8 @@
#include "nsSVGIntegerPair.h"
#include "nsSVGUtils.h"
#include "nsTextFormatter.h"
#include "prdtoa.h"
#include "nsCharSeparatedTokenizer.h"
#include "nsDOMError.h"
#ifdef MOZ_SMIL
#include "nsSMILValue.h"
#include "SVGIntegerPairSMILType.h"
@ -64,38 +64,37 @@ static nsresult
ParseIntegerOptionalInteger(const nsAString& aValue,
PRInt32 aValues[2])
{
NS_ConvertUTF16toUTF8 value(aValue);
const char *str = value.get();
if (IsSVGWhitespace(*str))
return NS_ERROR_FAILURE;
char* rest;
PRInt32 x = strtol(str, &rest, 10);
PRInt32 y = x;
if (str == rest) {
// first value was illformed
return NS_ERROR_FAILURE;
}
if (*rest != '\0') {
while (IsSVGWhitespace(*rest)) {
++rest;
}
if (*rest == ',') {
++rest;
}
y = strtol(rest, &rest, 10);
if (*rest != '\0') {
// second value was illformed or there was trailing content
return NS_ERROR_FAILURE;
}
nsCharSeparatedTokenizerTemplate<IsSVGWhitespace>
tokenizer(aValue, ',',
nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
if (tokenizer.firstTokenBeganWithWhitespace()) {
return NS_ERROR_DOM_SYNTAX_ERR;
}
aValues[0] = x;
aValues[1] = y;
PRUint32 i;
for (i = 0; i < 2 && tokenizer.hasMoreTokens(); ++i) {
NS_ConvertUTF16toUTF8 utf8Token(tokenizer.nextToken());
const char *token = utf8Token.get();
if (*token == '\0') {
return NS_ERROR_DOM_SYNTAX_ERR; // empty string (e.g. two commas in a row)
}
char *end;
aValues[i] = strtol(token, &end, 10);
if (*end != '\0' || !NS_FloatIsFinite(aValues[i])) {
return NS_ERROR_DOM_SYNTAX_ERR; // parse error
}
}
if (i == 1) {
aValues[1] = aValues[0];
}
if (i == 0 || // Too few values.
tokenizer.hasMoreTokens() || // Too many values.
tokenizer.lastTokenEndedWithWhitespace() || // Trailing whitespace.
tokenizer.lastTokenEndedWithSeparator()) { // Trailing comma.
return NS_ERROR_DOM_SYNTAX_ERR;
}
return NS_OK;
}

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

@ -36,8 +36,9 @@
#include "nsSVGNumberPair.h"
#include "nsSVGUtils.h"
#include "nsTextFormatter.h"
#include "nsCharSeparatedTokenizer.h"
#include "prdtoa.h"
#include "nsDOMError.h"
#ifdef MOZ_SMIL
#include "nsSMILValue.h"
#include "SVGNumberPairSMILType.h"
@ -64,38 +65,37 @@ static nsresult
ParseNumberOptionalNumber(const nsAString& aValue,
float aValues[2])
{
NS_ConvertUTF16toUTF8 value(aValue);
const char *str = value.get();
if (IsSVGWhitespace(*str))
return NS_ERROR_FAILURE;
char* rest;
float x = float(PR_strtod(str, &rest));
float y = x;
if (str == rest || !NS_FloatIsFinite(x)) {
// first value was illformed
return NS_ERROR_FAILURE;
}
if (*rest != '\0') {
while (IsSVGWhitespace(*rest)) {
++rest;
}
if (*rest == ',') {
++rest;
}
y = float(PR_strtod(rest, &rest));
if (*rest != '\0' || !NS_FloatIsFinite(y)) {
// second value was illformed or there was trailing content
return NS_ERROR_FAILURE;
}
nsCharSeparatedTokenizerTemplate<IsSVGWhitespace>
tokenizer(aValue, ',',
nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
if (tokenizer.firstTokenBeganWithWhitespace()) {
return NS_ERROR_DOM_SYNTAX_ERR;
}
aValues[0] = x;
aValues[1] = y;
PRUint32 i;
for (i = 0; i < 2 && tokenizer.hasMoreTokens(); ++i) {
NS_ConvertUTF16toUTF8 utf8Token(tokenizer.nextToken());
const char *token = utf8Token.get();
if (*token == '\0') {
return NS_ERROR_DOM_SYNTAX_ERR; // empty string (e.g. two commas in a row)
}
char *end;
aValues[i] = float(PR_strtod(token, &end));
if (*end != '\0' || !NS_FloatIsFinite(aValues[i])) {
return NS_ERROR_DOM_SYNTAX_ERR; // parse error
}
}
if (i == 1) {
aValues[1] = aValues[0];
}
if (i == 0 || // Too few values.
tokenizer.hasMoreTokens() || // Too many values.
tokenizer.lastTokenEndedWithWhitespace() || // Trailing whitespace.
tokenizer.lastTokenEndedWithSeparator()) { // Trailing comma.
return NS_ERROR_DOM_SYNTAX_ERR;
}
return NS_OK;
}

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

@ -142,7 +142,7 @@ nsSVGViewBox::SetBaseValue(float aX, float aY, float aWidth, float aHeight,
static nsresult
ToSVGViewBoxRect(const nsAString& aStr, nsSVGViewBoxRect *aViewBox)
{
nsCharSeparatedTokenizer
nsCharSeparatedTokenizerTemplate<IsSVGWhitespace>
tokenizer(aStr, ',',
nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
float vals[NUM_VIEWBOX_COMPONENTS];
@ -165,13 +165,13 @@ ToSVGViewBoxRect(const nsAString& aStr, nsSVGViewBoxRect *aViewBox)
tokenizer.hasMoreTokens() || // Too many values.
tokenizer.lastTokenEndedWithSeparator()) { // Trailing comma.
return NS_ERROR_DOM_SYNTAX_ERR;
} else {
aViewBox->x = vals[0];
aViewBox->y = vals[1];
aViewBox->width = vals[2];
aViewBox->height = vals[3];
}
aViewBox->x = vals[0];
aViewBox->y = vals[1];
aViewBox->width = vals[2];
aViewBox->height = vals[3];
return NS_OK;
}

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

@ -73,7 +73,9 @@ public:
nsCharSeparatedTokenizerTemplate(const nsSubstring& aSource,
PRUnichar aSeparatorChar,
PRUint32 aFlags = 0)
: mLastTokenEndedWithSeparator(PR_FALSE),
: mFirstTokenBeganWithWhitespace(PR_FALSE),
mLastTokenEndedWithWhitespace(PR_FALSE),
mLastTokenEndedWithSeparator(PR_FALSE),
mSeparatorChar(aSeparatorChar),
mFlags(aFlags)
{
@ -82,6 +84,7 @@ public:
// Skip initial whitespace
while (mIter != mEnd && IsWhitespace(*mIter)) {
mFirstTokenBeganWithWhitespace = PR_TRUE;
++mIter;
}
}
@ -97,11 +100,21 @@ public:
return mIter != mEnd;
}
PRBool lastTokenEndedWithSeparator()
PRBool firstTokenBeganWithWhitespace() const
{
return mFirstTokenBeganWithWhitespace;
}
PRBool lastTokenEndedWithSeparator() const
{
return mLastTokenEndedWithSeparator;
}
PRBool lastTokenEndedWithWhitespace() const
{
return mLastTokenEndedWithWhitespace;
}
/**
* Returns the next token.
*/
@ -123,7 +136,9 @@ public:
end = mIter;
// Skip whitespace after current word.
mLastTokenEndedWithWhitespace = PR_FALSE;
while (mIter != mEnd && IsWhitespace(*mIter)) {
mLastTokenEndedWithWhitespace = PR_TRUE;
++mIter;
}
if (mFlags & SEPARATOR_OPTIONAL) {
@ -155,6 +170,8 @@ public:
private:
nsSubstring::const_char_iterator mIter, mEnd;
PRPackedBool mFirstTokenBeganWithWhitespace;
PRPackedBool mLastTokenEndedWithWhitespace;
PRPackedBool mLastTokenEndedWithSeparator;
PRUnichar mSeparatorChar;
PRUint32 mFlags;