mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-28 05:10:49 +00:00
Bug 919319 - Simplify number parsing. r=dholbert
This commit is contained in:
parent
c67563512e
commit
3f45013a54
@ -9,13 +9,14 @@
|
||||
|
||||
// Keep others in (case-insensitive) order:
|
||||
#include "gfxMatrix.h"
|
||||
#include "mozilla/dom/SVGSVGElement.h"
|
||||
#include "mozilla/RangedPtr.h"
|
||||
#include "nsComputedDOMStyle.h"
|
||||
#include "nsFontMetrics.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "SVGAnimationElement.h"
|
||||
#include "mozilla/dom/SVGSVGElement.h"
|
||||
#include "SVGAnimatedPreserveAspectRatio.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
@ -366,3 +367,191 @@ SVGContentUtils::GetViewBoxTransform(float aViewportWidth, float aViewportHeight
|
||||
|
||||
return gfxMatrix(a, 0.0f, 0.0f, d, e, f);
|
||||
}
|
||||
|
||||
/**
|
||||
* True if 'aCh' is a decimal digit.
|
||||
*/
|
||||
static inline bool
|
||||
IsDigit(PRUnichar aCh)
|
||||
{
|
||||
return aCh >= '0' && aCh <= '9';
|
||||
}
|
||||
|
||||
/**
|
||||
* Assuming that 'aCh' is a decimal digit, return its numeric value.
|
||||
*/
|
||||
static inline uint32_t
|
||||
DecimalDigitValue(PRUnichar aCh)
|
||||
{
|
||||
MOZ_ASSERT(IsDigit(aCh), "Digit expected");
|
||||
return aCh - '0';
|
||||
}
|
||||
|
||||
template<class floatType>
|
||||
bool
|
||||
SVGContentUtils::ParseNumber(const nsAString& aString,
|
||||
floatType& aValue,
|
||||
nsAString& aLeftOver)
|
||||
{
|
||||
mozilla::RangedPtr<const PRUnichar> iter(aString.Data(), aString.Length());
|
||||
const mozilla::RangedPtr<const PRUnichar> end(aString.Data() + aString.Length(),
|
||||
aString.Data(), aString.Length());
|
||||
|
||||
if (iter == end) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Sign of the mantissa (-1 or 1).
|
||||
int32_t sign = *iter == '-' ? -1 : 1;
|
||||
|
||||
if (*iter == '-' || *iter == '+') {
|
||||
++iter;
|
||||
if (iter == end) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Absolute value of the integer part of the mantissa.
|
||||
floatType intPart = floatType(0);
|
||||
|
||||
bool gotDot = *iter == '.';
|
||||
|
||||
if (!gotDot) {
|
||||
if (!IsDigit(*iter)) {
|
||||
return false;
|
||||
}
|
||||
do {
|
||||
intPart = floatType(10) * intPart + DecimalDigitValue(*iter);
|
||||
++iter;
|
||||
} while (iter != end && IsDigit(*iter));
|
||||
|
||||
if (iter != end) {
|
||||
gotDot = *iter == '.';
|
||||
}
|
||||
}
|
||||
|
||||
// Fractional part of the mantissa.
|
||||
floatType fracPart = floatType(0);
|
||||
|
||||
if (gotDot) {
|
||||
++iter;
|
||||
if (iter == end || !IsDigit(*iter)) {
|
||||
return false;
|
||||
}
|
||||
// Power of ten by which we need to divide our next digit
|
||||
floatType divisor = floatType(10);
|
||||
do {
|
||||
fracPart += DecimalDigitValue(*iter) / divisor;
|
||||
divisor *= 10;
|
||||
++iter;
|
||||
} while (iter != end && IsDigit(*iter));
|
||||
}
|
||||
|
||||
bool gotE = false;
|
||||
int32_t exponent = 0;
|
||||
int32_t expSign;
|
||||
|
||||
if (iter != end && (*iter == 'e' || *iter == 'E')) {
|
||||
|
||||
mozilla::RangedPtr<const PRUnichar> expIter(iter);
|
||||
|
||||
++expIter;
|
||||
if (expIter != end) {
|
||||
expSign = *expIter == '-' ? -1 : 1;
|
||||
if (*expIter == '-' || *expIter == '+') {
|
||||
++expIter;
|
||||
if (expIter != end && IsDigit(*expIter)) {
|
||||
// At this point we're sure this is an exponent
|
||||
// and not the start of a unit such as em or ex.
|
||||
gotE = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gotE) {
|
||||
iter = expIter;
|
||||
do {
|
||||
exponent = 10 * exponent + DecimalDigitValue(*iter);
|
||||
++iter;
|
||||
} while (iter != end && IsDigit(*iter));
|
||||
}
|
||||
}
|
||||
|
||||
// Assemble the number
|
||||
aValue = sign * (intPart + fracPart);
|
||||
if (gotE) {
|
||||
aValue *= pow(floatType(10), floatType(expSign * exponent));
|
||||
}
|
||||
|
||||
aLeftOver = Substring(iter.get(), end.get());
|
||||
return NS_finite(aValue);
|
||||
}
|
||||
|
||||
template bool
|
||||
SVGContentUtils::ParseNumber<float>(const nsAString& aString,
|
||||
float& aValue,
|
||||
nsAString& aLeftOver);
|
||||
template bool
|
||||
SVGContentUtils::ParseNumber<double>(const nsAString& aString,
|
||||
double& aValue,
|
||||
nsAString& aLeftOver);
|
||||
|
||||
template<class floatType>
|
||||
bool
|
||||
SVGContentUtils::ParseNumber(const nsAString& aString,
|
||||
floatType& aValue)
|
||||
{
|
||||
nsAutoString leftOver;
|
||||
|
||||
if (!ParseNumber(aString, aValue, leftOver)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return leftOver.IsEmpty();
|
||||
}
|
||||
|
||||
template bool
|
||||
SVGContentUtils::ParseNumber<float>(const nsAString& aString,
|
||||
float& aValue);
|
||||
template bool
|
||||
SVGContentUtils::ParseNumber<double>(const nsAString& aString,
|
||||
double& aValue);
|
||||
|
||||
bool
|
||||
SVGContentUtils::ParseInteger(const nsAString& aString,
|
||||
int32_t& aValue)
|
||||
{
|
||||
mozilla::RangedPtr<const PRUnichar> iter(aString.Data(), aString.Length());
|
||||
const mozilla::RangedPtr<const PRUnichar> end(aString.Data() + aString.Length(),
|
||||
aString.Data(), aString.Length());
|
||||
|
||||
if (iter == end) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t sign = *iter == '-' ? -1 : 1;
|
||||
|
||||
if (*iter == '-' || *iter == '+') {
|
||||
++iter;
|
||||
if (iter == end) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t value = 0;
|
||||
|
||||
do {
|
||||
if (!IsDigit(*iter)) {
|
||||
return false;
|
||||
}
|
||||
if (value <= std::numeric_limits<int32_t>::max()) {
|
||||
value = 10 * value + DecimalDigitValue(*iter);
|
||||
}
|
||||
++iter;
|
||||
} while (iter != end);
|
||||
|
||||
aValue = int32_t(clamped(sign * value,
|
||||
int64_t(std::numeric_limits<int32_t>::min()),
|
||||
int64_t(std::numeric_limits<int32_t>::max())));
|
||||
return true;
|
||||
}
|
||||
|
@ -132,6 +132,34 @@ public:
|
||||
float aViewboxWidth, float aViewboxHeight,
|
||||
const SVGPreserveAspectRatio &aPreserveAspectRatio);
|
||||
|
||||
/**
|
||||
* Parse a number of the form:
|
||||
* number ::= integer ([Ee] integer)? | [+-]? [0-9]* "." [0-9]+ ([Ee] integer)?
|
||||
* Parsing fails if the number cannot be represented by a floatType.
|
||||
* Anything after the number is returned in aLeftOver.
|
||||
*/
|
||||
template<class floatType>
|
||||
static bool
|
||||
ParseNumber(const nsAString& aString, floatType& aValue,
|
||||
nsAString& aLeftOver);
|
||||
|
||||
/**
|
||||
* Parse a number of the form:
|
||||
* number ::= integer ([Ee] integer)? | [+-]? [0-9]* "." [0-9]+ ([Ee] integer)?
|
||||
* Parsing fails if there is anything left over after the number,
|
||||
* or the number cannot be represented by a floatType.
|
||||
*/
|
||||
template<class floatType>
|
||||
static bool
|
||||
ParseNumber(const nsAString& aString, floatType& aValue);
|
||||
|
||||
/**
|
||||
* Parse an integer of the form:
|
||||
* integer ::= [+-]? [0-9]+
|
||||
* Parsing fails if the number cannot be represented by an int32_t.
|
||||
*/
|
||||
static bool
|
||||
ParseInteger(const nsAString& aString, int32_t& aValue);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -8,10 +8,7 @@
|
||||
#include "SVGLength.h"
|
||||
#include "nsSVGElement.h"
|
||||
#include "mozilla/dom/SVGSVGElement.h"
|
||||
#include "nsString.h"
|
||||
#include "nsTextFormatter.h"
|
||||
#include "prdtoa.h"
|
||||
#include "nsMathUtils.h"
|
||||
#include "SVGContentUtils.h"
|
||||
#include <limits>
|
||||
#include <algorithm>
|
||||
@ -37,40 +34,22 @@ SVGLength::GetValueAsString(nsAString &aValue) const
|
||||
}
|
||||
|
||||
bool
|
||||
SVGLength::SetValueFromString(const nsAString &aValue)
|
||||
SVGLength::SetValueFromString(const nsAString &aValueAsString)
|
||||
{
|
||||
float tmpValue;
|
||||
uint16_t tmpUnit;
|
||||
nsAutoString units;
|
||||
float value;
|
||||
|
||||
NS_ConvertUTF16toUTF8 value(aValue);
|
||||
const char *str = value.get();
|
||||
if (!SVGContentUtils::ParseNumber(aValueAsString, value, units)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (*str != '\0' && IsSVGWhitespace(*str)) {
|
||||
++str;
|
||||
uint16_t unitType = GetUnitTypeForString(units);
|
||||
if (!IsValidUnitType(unitType)) {
|
||||
return false;
|
||||
}
|
||||
char *unit;
|
||||
tmpValue = float(PR_strtod(str, &unit));
|
||||
if (unit != str && NS_finite(tmpValue)) {
|
||||
char *theRest = unit;
|
||||
while (*theRest != '\0' && !IsSVGWhitespace(*theRest)) {
|
||||
++theRest;
|
||||
}
|
||||
tmpUnit = GetUnitTypeForString(
|
||||
Substring(aValue, unit - str, theRest - unit));
|
||||
if (tmpUnit == nsIDOMSVGLength::SVG_LENGTHTYPE_UNKNOWN) {
|
||||
// SVGContentUtils::ReportToConsole
|
||||
return false;
|
||||
}
|
||||
while (*theRest && IsSVGWhitespace(*theRest)) {
|
||||
++theRest;
|
||||
}
|
||||
if (!*theRest) {
|
||||
mValue = tmpValue;
|
||||
mUnit = tmpUnit;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
mValue = value;
|
||||
mUnit = uint8_t(unitType);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline static bool
|
||||
|
@ -49,8 +49,6 @@ SVGLengthList::SetValueFromString(const nsAString& aValue)
|
||||
nsCharSeparatedTokenizerTemplate<IsSVGWhitespace>
|
||||
tokenizer(aValue, ',', nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
|
||||
|
||||
nsAutoCString str; // outside loop to minimize memory churn
|
||||
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
SVGLength length;
|
||||
if (!length.SetValueFromString(tokenizer.nextToken())) {
|
||||
|
@ -7,11 +7,8 @@
|
||||
|
||||
#include "SVGNumberList.h"
|
||||
#include "nsCharSeparatedTokenizer.h"
|
||||
#include "nsError.h"
|
||||
#include "nsMathUtils.h"
|
||||
#include "nsString.h"
|
||||
#include "nsTextFormatter.h"
|
||||
#include "prdtoa.h"
|
||||
#include "SVGContentUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
@ -55,17 +52,9 @@ SVGNumberList::SetValueFromString(const nsAString& aValue)
|
||||
nsCharSeparatedTokenizerTemplate<IsSVGWhitespace>
|
||||
tokenizer(aValue, ',', nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
|
||||
|
||||
nsAutoCString str; // outside loop to minimize memory churn
|
||||
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
CopyUTF16toUTF8(tokenizer.nextToken(), str); // NS_ConvertUTF16toUTF8
|
||||
const char *token = str.get();
|
||||
if (*token == '\0') {
|
||||
return NS_ERROR_DOM_SYNTAX_ERR; // nothing between commas
|
||||
}
|
||||
char *end;
|
||||
float num = float(PR_strtod(token, &end));
|
||||
if (*end != '\0' || !NS_finite(num)) {
|
||||
float num;
|
||||
if (!SVGContentUtils::ParseNumber(tokenizer.nextToken(), num)) {
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
if (!temp.AppendItem(num)) {
|
||||
|
@ -6,12 +6,8 @@
|
||||
#include "mozilla/Util.h"
|
||||
|
||||
#include "SVGPointList.h"
|
||||
#include "nsError.h"
|
||||
#include "nsCharSeparatedTokenizer.h"
|
||||
#include "nsMathUtils.h"
|
||||
#include "nsString.h"
|
||||
#include "nsTextFormatter.h"
|
||||
#include "prdtoa.h"
|
||||
#include "SVGContentUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
@ -62,45 +58,30 @@ SVGPointList::SetValueFromString(const nsAString& aValue)
|
||||
nsCharSeparatedTokenizerTemplate<IsSVGWhitespace>
|
||||
tokenizer(aValue, ',', nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
|
||||
|
||||
nsAutoCString str1, str2; // outside loop to minimize memory churn
|
||||
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
CopyUTF16toUTF8(tokenizer.nextToken(), str1);
|
||||
const char *token1 = str1.get();
|
||||
if (*token1 == '\0') {
|
||||
|
||||
float x;
|
||||
nsAutoString leftOver;
|
||||
if (!SVGContentUtils::ParseNumber(tokenizer.nextToken(), x, leftOver)) {
|
||||
rv = NS_ERROR_DOM_SYNTAX_ERR;
|
||||
break;
|
||||
}
|
||||
char *end;
|
||||
float x = float(PR_strtod(token1, &end));
|
||||
if (end == token1 || !NS_finite(x)) {
|
||||
rv = NS_ERROR_DOM_SYNTAX_ERR;
|
||||
break;
|
||||
}
|
||||
const char *token2;
|
||||
if (*end == '-') {
|
||||
|
||||
float y;
|
||||
if (leftOver.IsEmpty()) {
|
||||
if (!tokenizer.hasMoreTokens() ||
|
||||
!SVGContentUtils::ParseNumber(tokenizer.nextToken(), y)) {
|
||||
rv = NS_ERROR_DOM_SYNTAX_ERR;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// It's possible for the token to be 10-30 which has
|
||||
// no separator but needs to be parsed as 10, -30
|
||||
token2 = end;
|
||||
} else {
|
||||
if (!tokenizer.hasMoreTokens()) {
|
||||
rv = NS_ERROR_DOM_SYNTAX_ERR;
|
||||
break;
|
||||
}
|
||||
CopyUTF16toUTF8(tokenizer.nextToken(), str2);
|
||||
token2 = str2.get();
|
||||
if (*token2 == '\0') {
|
||||
if (leftOver[0] != '-' || !SVGContentUtils::ParseNumber(leftOver, y)) {
|
||||
rv = NS_ERROR_DOM_SYNTAX_ERR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
float y = float(PR_strtod(token2, &end));
|
||||
if (*end != '\0' || !NS_finite(y)) {
|
||||
rv = NS_ERROR_DOM_SYNTAX_ERR;
|
||||
break;
|
||||
}
|
||||
|
||||
temp.AppendItem(SVGPoint(x, y));
|
||||
}
|
||||
if (tokenizer.separatorAfterCurrentToken()) {
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "nsSMILValue.h"
|
||||
#include "nsSVGAttrTearoffTable.h"
|
||||
#include "nsTextFormatter.h"
|
||||
#include "prdtoa.h"
|
||||
#include "SVGAngle.h"
|
||||
#include "SVGAnimatedAngle.h"
|
||||
#include "SVGOrientSMILType.h"
|
||||
@ -94,28 +93,19 @@ GetValueString(nsAString &aValueAsString, float aValue, uint16_t aUnitType)
|
||||
aValueAsString.Append(unitString);
|
||||
}
|
||||
|
||||
static nsresult
|
||||
GetValueFromString(const nsAString &aValueAsString,
|
||||
float *aValue,
|
||||
uint16_t *aUnitType)
|
||||
static bool
|
||||
GetValueFromString(const nsAString& aValueAsString,
|
||||
float& aValue,
|
||||
uint16_t* aUnitType)
|
||||
{
|
||||
NS_ConvertUTF16toUTF8 value(aValueAsString);
|
||||
const char *str = value.get();
|
||||
nsAutoString units;
|
||||
|
||||
if (IsSVGWhitespace(*str))
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
|
||||
char *rest;
|
||||
*aValue = float(PR_strtod(str, &rest));
|
||||
if (rest != str && NS_finite(*aValue)) {
|
||||
*aUnitType = GetUnitTypeForString(
|
||||
Substring(aValueAsString, rest - str));
|
||||
if (IsValidUnitType(*aUnitType)) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (!SVGContentUtils::ParseNumber(aValueAsString, aValue, units)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
|
||||
*aUnitType = GetUnitTypeForString(units);
|
||||
return IsValidUnitType(*aUnitType);
|
||||
}
|
||||
|
||||
/* static */ float
|
||||
@ -258,12 +248,11 @@ nsSVGAngle::SetBaseValueString(const nsAString &aValueAsString,
|
||||
nsSVGElement *aSVGElement,
|
||||
bool aDoSetAttr)
|
||||
{
|
||||
float value = 0;
|
||||
uint16_t unitType = 0;
|
||||
float value;
|
||||
uint16_t unitType;
|
||||
|
||||
nsresult rv = GetValueFromString(aValueAsString, &value, &unitType);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
if (!GetValueFromString(aValueAsString, value, &unitType)) {
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
if (mBaseVal == value && mBaseValUnit == uint8_t(unitType)) {
|
||||
return NS_OK;
|
||||
@ -382,9 +371,8 @@ nsSVGAngle::SMILOrient::ValueFromString(const nsAString& aStr,
|
||||
} else {
|
||||
float value;
|
||||
uint16_t unitType;
|
||||
nsresult rv = GetValueFromString(aStr, &value, &unitType);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
if (!GetValueFromString(aStr, value, &unitType)) {
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
val.mU.mOrient.mAngle = value;
|
||||
val.mU.mOrient.mUnit = unitType;
|
||||
|
@ -6,10 +6,10 @@
|
||||
#include "nsSVGAnimatedTransformList.h"
|
||||
#include "mozilla/dom/SVGAnimatedTransformList.h"
|
||||
#include "mozilla/dom/SVGAnimationElement.h"
|
||||
#include "nsSMILValue.h"
|
||||
#include "prdtoa.h"
|
||||
#include "SVGContentUtils.h"
|
||||
#include "nsCharSeparatedTokenizer.h"
|
||||
#include "nsSVGTransform.h"
|
||||
#include "nsSMILValue.h"
|
||||
#include "SVGContentUtils.h"
|
||||
#include "SVGTransformListSMILType.h"
|
||||
|
||||
namespace mozilla {
|
||||
@ -235,54 +235,27 @@ nsSVGAnimatedTransformList::SMILAnimatedTransformList::ParseValue(
|
||||
aResult.Swap(val);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
inline void
|
||||
SkipWsp(nsACString::const_iterator& aIter,
|
||||
const nsACString::const_iterator& aIterEnd)
|
||||
{
|
||||
while (aIter != aIterEnd && IsSVGWhitespace(*aIter))
|
||||
++aIter;
|
||||
}
|
||||
} // end anonymous namespace block
|
||||
|
||||
int32_t
|
||||
nsSVGAnimatedTransformList::SMILAnimatedTransformList::ParseParameterList(
|
||||
const nsAString& aSpec,
|
||||
float* aVars,
|
||||
int32_t aNVars)
|
||||
{
|
||||
NS_ConvertUTF16toUTF8 spec(aSpec);
|
||||
|
||||
nsACString::const_iterator start, end;
|
||||
spec.BeginReading(start);
|
||||
spec.EndReading(end);
|
||||
|
||||
SkipWsp(start, end);
|
||||
nsCharSeparatedTokenizerTemplate<IsSVGWhitespace>
|
||||
tokenizer(aSpec, ',', nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
|
||||
|
||||
int numArgsFound = 0;
|
||||
|
||||
while (start != end) {
|
||||
char const *arg = start.get();
|
||||
char *argend;
|
||||
float f = float(PR_strtod(arg, &argend));
|
||||
if (arg == argend || argend > end.get() || !NS_finite(f))
|
||||
return -1;
|
||||
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
float f;
|
||||
if (!SVGContentUtils::ParseNumber(tokenizer.nextToken(), f)) {
|
||||
return -1;
|
||||
}
|
||||
if (numArgsFound < aNVars) {
|
||||
aVars[numArgsFound] = f;
|
||||
}
|
||||
|
||||
start.advance(argend - arg);
|
||||
numArgsFound++;
|
||||
|
||||
SkipWsp(start, end);
|
||||
if (*start == ',') {
|
||||
++start;
|
||||
SkipWsp(start, end);
|
||||
}
|
||||
}
|
||||
|
||||
return numArgsFound;
|
||||
}
|
||||
|
||||
|
@ -24,19 +24,19 @@ SVGAnimatedBooleanTearoffTable()
|
||||
return sSVGAnimatedBooleanTearoffTable;
|
||||
}
|
||||
|
||||
static nsresult
|
||||
GetValueFromString(const nsAString &aValueAsString,
|
||||
bool *aValue)
|
||||
static bool
|
||||
GetValueFromString(const nsAString& aValueAsString,
|
||||
bool& aValue)
|
||||
{
|
||||
if (aValueAsString.EqualsLiteral("true")) {
|
||||
*aValue = true;
|
||||
return NS_OK;
|
||||
aValue = true;
|
||||
return true;
|
||||
}
|
||||
if (aValueAsString.EqualsLiteral("false")) {
|
||||
*aValue = false;
|
||||
return NS_OK;
|
||||
aValue = false;
|
||||
return true;
|
||||
}
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
return false;
|
||||
}
|
||||
|
||||
static nsresult
|
||||
@ -141,9 +141,8 @@ nsSVGBoolean::SMILBool::ValueFromString(const nsAString& aStr,
|
||||
bool& aPreventCachingOfSandwich) const
|
||||
{
|
||||
bool value;
|
||||
nsresult rv = GetValueFromString(aStr, &value);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
if (!GetValueFromString(aStr, value)) {
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
|
||||
nsSMILValue val(SMILBoolType::Singleton());
|
||||
|
@ -18,36 +18,14 @@ using namespace mozilla::dom;
|
||||
static nsSVGAttrTearoffTable<nsSVGInteger, nsSVGInteger::DOMAnimatedInteger>
|
||||
sSVGAnimatedIntegerTearoffTable;
|
||||
|
||||
static nsresult
|
||||
GetValueFromString(const nsAString &aValueAsString,
|
||||
int32_t *aValue)
|
||||
{
|
||||
NS_ConvertUTF16toUTF8 value(aValueAsString);
|
||||
const char *str = value.get();
|
||||
|
||||
if (IsSVGWhitespace(*str))
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
|
||||
char *rest;
|
||||
*aValue = strtol(str, &rest, 10);
|
||||
if (rest == str || *rest != '\0') {
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
if (*rest == '\0') {
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSVGInteger::SetBaseValueString(const nsAString &aValueAsString,
|
||||
nsSVGElement *aSVGElement)
|
||||
{
|
||||
int32_t value;
|
||||
|
||||
nsresult rv = GetValueFromString(aValueAsString, &value);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
if (!SVGContentUtils::ParseInteger(aValueAsString, value)) {
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
|
||||
mIsBaseSet = true;
|
||||
@ -133,9 +111,8 @@ nsSVGInteger::SMILInteger::ValueFromString(const nsAString& aStr,
|
||||
{
|
||||
int32_t val;
|
||||
|
||||
nsresult rv = GetValueFromString(aStr, &val);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
if (!SVGContentUtils::ParseInteger(aStr, val)) {
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
|
||||
nsSMILValue smilVal(SMILIntegerType::Singleton());
|
||||
|
@ -35,16 +35,8 @@ ParseIntegerOptionalInteger(const nsAString& aValue,
|
||||
|
||||
uint32_t 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_finite(aValues[i])) {
|
||||
return NS_ERROR_DOM_SYNTAX_ERR; // parse error
|
||||
if (!SVGContentUtils::ParseInteger(tokenizer.nextToken(), aValues[i])) {
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
}
|
||||
if (i == 1) {
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include "nsSVGAttrTearoffTable.h"
|
||||
#include "nsSVGIntegrationUtils.h"
|
||||
#include "nsTextFormatter.h"
|
||||
#include "prdtoa.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
@ -122,28 +121,17 @@ GetValueString(nsAString &aValueAsString, float aValue, uint16_t aUnitType)
|
||||
aValueAsString.Append(unitString);
|
||||
}
|
||||
|
||||
static nsresult
|
||||
GetValueFromString(const nsAString &aValueAsString,
|
||||
float *aValue,
|
||||
uint16_t *aUnitType)
|
||||
static bool
|
||||
GetValueFromString(const nsAString& aValueAsString,
|
||||
float& aValue,
|
||||
uint16_t* aUnitType)
|
||||
{
|
||||
NS_ConvertUTF16toUTF8 value(aValueAsString);
|
||||
const char *str = value.get();
|
||||
|
||||
if (IsSVGWhitespace(*str))
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
|
||||
char *rest;
|
||||
*aValue = float(PR_strtod(str, &rest));
|
||||
if (rest != str && NS_finite(*aValue)) {
|
||||
*aUnitType = GetUnitTypeForString(
|
||||
Substring(aValueAsString, rest - str));
|
||||
if (IsValidUnitType(*aUnitType)) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsAutoString units;
|
||||
if (!SVGContentUtils::ParseNumber(aValueAsString, aValue, units)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
*aUnitType = GetUnitTypeForString(units);
|
||||
return IsValidUnitType(*aUnitType);
|
||||
}
|
||||
|
||||
static float
|
||||
@ -399,12 +387,11 @@ nsSVGLength2::SetBaseValueString(const nsAString &aValueAsString,
|
||||
float value;
|
||||
uint16_t unitType;
|
||||
|
||||
nsresult rv = GetValueFromString(aValueAsString, &value, &unitType);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
if (!GetValueFromString(aValueAsString, value, &unitType)) {
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
|
||||
if (mIsBaseSet && mBaseVal == value &&
|
||||
if (mIsBaseSet && mBaseVal == float(value) &&
|
||||
mSpecifiedUnitType == uint8_t(unitType)) {
|
||||
return NS_OK;
|
||||
}
|
||||
@ -503,9 +490,8 @@ nsSVGLength2::SMILLength::ValueFromString(const nsAString& aStr,
|
||||
float value;
|
||||
uint16_t unitType;
|
||||
|
||||
nsresult rv = GetValueFromString(aStr, &value, &unitType);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
if (!GetValueFromString(aStr, value, &unitType)) {
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
|
||||
nsSMILValue val(nsSMILFloatType::Singleton());
|
||||
|
@ -6,12 +6,10 @@
|
||||
#include "nsSVGNumber2.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsContentUtils.h" // NS_ENSURE_FINITE
|
||||
#include "nsError.h"
|
||||
#include "nsIDOMSVGNumber.h"
|
||||
#include "nsSMILFloatType.h"
|
||||
#include "nsSMILValue.h"
|
||||
#include "nsSVGAttrTearoffTable.h"
|
||||
#include "prdtoa.h"
|
||||
#include "SVGContentUtils.h"
|
||||
|
||||
using namespace mozilla;
|
||||
@ -50,30 +48,23 @@ NS_INTERFACE_MAP_END
|
||||
static nsSVGAttrTearoffTable<nsSVGNumber2, nsSVGNumber2::DOMAnimatedNumber>
|
||||
sSVGAnimatedNumberTearoffTable;
|
||||
|
||||
static nsresult
|
||||
GetValueFromString(const nsAString &aValueAsString,
|
||||
static bool
|
||||
GetValueFromString(const nsAString& aValueAsString,
|
||||
bool aPercentagesAllowed,
|
||||
float *aValue)
|
||||
float& aValue)
|
||||
{
|
||||
NS_ConvertUTF16toUTF8 value(aValueAsString);
|
||||
const char *str = value.get();
|
||||
nsAutoString units;
|
||||
|
||||
if (IsSVGWhitespace(*str))
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
|
||||
char *rest;
|
||||
*aValue = float(PR_strtod(str, &rest));
|
||||
if (rest == str || !NS_finite(*aValue)) {
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
if (!SVGContentUtils::ParseNumber(aValueAsString, aValue, units)) {
|
||||
return false;
|
||||
}
|
||||
if (*rest == '%' && aPercentagesAllowed) {
|
||||
*aValue /= 100;
|
||||
++rest;
|
||||
|
||||
if (aPercentagesAllowed && units.EqualsLiteral("%")) {
|
||||
aValue /= 100;
|
||||
return true;
|
||||
}
|
||||
if (*rest == '\0') {
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
|
||||
return units.IsEmpty();
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -82,11 +73,10 @@ nsSVGNumber2::SetBaseValueString(const nsAString &aValueAsString,
|
||||
{
|
||||
float val;
|
||||
|
||||
nsresult rv = GetValueFromString(
|
||||
aValueAsString, aSVGElement->NumberAttrAllowsPercentage(mAttrEnum), &val);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
if (!GetValueFromString(aValueAsString,
|
||||
aSVGElement->NumberAttrAllowsPercentage(mAttrEnum),
|
||||
val)) {
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
|
||||
mBaseVal = val;
|
||||
@ -172,11 +162,10 @@ nsSVGNumber2::SMILNumber::ValueFromString(const nsAString& aStr,
|
||||
{
|
||||
float value;
|
||||
|
||||
nsresult rv = GetValueFromString(
|
||||
aStr, mSVGElement->NumberAttrAllowsPercentage(mVal->mAttrEnum), &value);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
if (!GetValueFromString(aStr,
|
||||
mSVGElement->NumberAttrAllowsPercentage(mVal->mAttrEnum),
|
||||
value)) {
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
|
||||
nsSMILValue val(nsSMILFloatType::Singleton());
|
||||
|
@ -6,9 +6,6 @@
|
||||
#include "nsSVGNumberPair.h"
|
||||
#include "nsSVGAttrTearoffTable.h"
|
||||
#include "nsCharSeparatedTokenizer.h"
|
||||
#include "prdtoa.h"
|
||||
#include "nsError.h"
|
||||
#include "nsMathUtils.h"
|
||||
#include "nsSMILValue.h"
|
||||
#include "SVGContentUtils.h"
|
||||
#include "SVGNumberPairSMILType.h"
|
||||
@ -34,16 +31,8 @@ ParseNumberOptionalNumber(const nsAString& aValue,
|
||||
|
||||
uint32_t 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_finite(aValues[i])) {
|
||||
return NS_ERROR_DOM_SYNTAX_ERR; // parse error
|
||||
if (!SVGContentUtils::ParseNumber(tokenizer.nextToken(), aValues[i])) {
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
}
|
||||
if (i == 1) {
|
||||
|
@ -4,10 +4,9 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsSVGViewBox.h"
|
||||
#include "prdtoa.h"
|
||||
#include "nsTextFormatter.h"
|
||||
#include "nsCharSeparatedTokenizer.h"
|
||||
#include "nsSMILValue.h"
|
||||
#include "nsTextFormatter.h"
|
||||
#include "SVGContentUtils.h"
|
||||
#include "SVGViewBoxSMILType.h"
|
||||
|
||||
@ -122,16 +121,8 @@ ToSVGViewBoxRect(const nsAString& aStr, nsSVGViewBoxRect *aViewBox)
|
||||
float vals[NUM_VIEWBOX_COMPONENTS];
|
||||
uint32_t i;
|
||||
for (i = 0; i < NUM_VIEWBOX_COMPONENTS && 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;
|
||||
vals[i] = float(PR_strtod(token, &end));
|
||||
if (*end != '\0' || !NS_finite(vals[i])) {
|
||||
return NS_ERROR_DOM_SYNTAX_ERR; // parse error
|
||||
if (!SVGContentUtils::ParseNumber(tokenizer.nextToken(), vals[i])) {
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -97,10 +97,10 @@ function runTests()
|
||||
is(blur.getAttribute("stdDeviation"), "8.5", "number-optional-number attribute");
|
||||
|
||||
blur.setStdDeviation(24.5, 0.5);
|
||||
is(blur.stdDeviationX.baseVal, 24.5, "integer-optional-integer first baseVal");
|
||||
is(blur.stdDeviationX.animVal, 24.5, "integer-optional-integer first animVal");
|
||||
is(blur.stdDeviationY.baseVal, 0.5, "integer-optional-integer second baseVal");
|
||||
is(blur.stdDeviationY.animVal, 0.5, "integer-optional-integer second animVal");
|
||||
is(blur.stdDeviationX.baseVal, 24.5, "number-optional-number first baseVal");
|
||||
is(blur.stdDeviationX.animVal, 24.5, "number-optional-number first animVal");
|
||||
is(blur.stdDeviationY.baseVal, 0.5, "number-optional-number second baseVal");
|
||||
is(blur.stdDeviationY.animVal, 0.5, "number-optional-number second animVal");
|
||||
|
||||
blur.setAttribute("stdDeviation", "");
|
||||
ok(blur.getAttribute("stdDeviation") === "",
|
||||
@ -144,6 +144,27 @@ function runTests()
|
||||
is(filter.filterResY.baseVal, 90, "integer-optional-integer second baseVal");
|
||||
is(filter.filterResY.animVal, 90, "integer-optional-integer second animVal");
|
||||
|
||||
// 32 bit integer range
|
||||
filter.setFilterRes(-2147483648, 2147483647);
|
||||
is(filter.filterResX.baseVal, -2147483648, "integer-optional-integer first baseVal");
|
||||
is(filter.filterResX.animVal, -2147483648, "integer-optional-integer first animVal");
|
||||
is(filter.filterResY.baseVal, 2147483647, "integer-optional-integer second baseVal");
|
||||
is(filter.filterResY.animVal, 2147483647, "integer-optional-integer second animVal");
|
||||
|
||||
// too big, clamp
|
||||
filter.setAttribute("filterRes", "-2147483649, 2147483648");
|
||||
is(filter.filterResX.baseVal, -2147483648, "integer-optional-integer first baseVal");
|
||||
is(filter.filterResX.animVal, -2147483648, "integer-optional-integer first animVal");
|
||||
is(filter.filterResY.baseVal, 2147483647, "integer-optional-integer second baseVal");
|
||||
is(filter.filterResY.animVal, 2147483647, "integer-optional-integer second animVal");
|
||||
|
||||
// invalid
|
||||
filter.setAttribute("filterRes", "-00000000000invalid, 214748364720invalid");
|
||||
is(filter.filterResX.baseVal, 0, "integer-optional-integer first baseVal");
|
||||
is(filter.filterResX.animVal, 0, "integer-optional-integer first animVal");
|
||||
is(filter.filterResY.baseVal, 0, "integer-optional-integer second baseVal");
|
||||
is(filter.filterResY.animVal, 0, "integer-optional-integer second animVal");
|
||||
|
||||
filter.setAttribute("filterRes", "");
|
||||
ok(filter.getAttribute("filterRes") === "",
|
||||
"empty integer-optional-integer attribute");
|
||||
|
Loading…
x
Reference in New Issue
Block a user