mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-12 21:05:36 +00:00
Bug 870022 - Part 1 - Split nsAttrValue::StringToInteger out to nsContentUtils, update usage. r=jst
This commit is contained in:
parent
eb0149fd3f
commit
02eb0d8e6f
@ -367,6 +367,19 @@ public:
|
||||
*/
|
||||
static bool IsHTMLVoid(nsIAtom* aLocalName);
|
||||
|
||||
enum ParseHTMLIntegerResultFlags {
|
||||
eParseHTMLInteger_NoFlags = 0,
|
||||
eParseHTMLInteger_IsPercent = 1 << 0,
|
||||
eParseHTMLInteger_NonStandard = 1 << 1,
|
||||
eParseHTMLInteger_DidNotConsumeAllInput = 1 << 2,
|
||||
// Set if one or more error flags were set.
|
||||
eParseHTMLInteger_Error = 1 << 3,
|
||||
eParseHTMLInteger_ErrorNoValue = 1 << 4,
|
||||
eParseHTMLInteger_ErrorOverflow = 1 << 5
|
||||
};
|
||||
static int32_t ParseHTMLInteger(const nsAString& aValue,
|
||||
ParseHTMLIntegerResultFlags *aResult);
|
||||
|
||||
/**
|
||||
* Parse a margin string of format 'top, right, bottom, left' into
|
||||
* an nsIntMargin.
|
||||
|
@ -1443,28 +1443,27 @@ nsAttrValue::ParseSpecialIntValue(const nsAString& aString)
|
||||
{
|
||||
ResetIfSet();
|
||||
|
||||
nsresult ec;
|
||||
bool strict;
|
||||
bool isPercent = false;
|
||||
nsAutoString tmp(aString);
|
||||
int32_t originalVal = StringToInteger(aString, &strict, &ec, true, &isPercent);
|
||||
nsContentUtils::ParseHTMLIntegerResultFlags result;
|
||||
int32_t originalVal = nsContentUtils::ParseHTMLInteger(aString, &result);
|
||||
|
||||
if (NS_FAILED(ec)) {
|
||||
if (result & nsContentUtils::eParseHTMLInteger_Error) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isPercent = result & nsContentUtils::eParseHTMLInteger_IsPercent;
|
||||
int32_t val = std::max(originalVal, 0);
|
||||
bool nonStrict = val != originalVal ||
|
||||
(result & nsContentUtils::eParseHTMLInteger_NonStandard) ||
|
||||
(result & nsContentUtils::eParseHTMLInteger_DidNotConsumeAllInput);
|
||||
|
||||
// % (percent)
|
||||
if (isPercent || tmp.RFindChar('%') >= 0) {
|
||||
isPercent = true;
|
||||
}
|
||||
|
||||
strict = strict && (originalVal == val);
|
||||
|
||||
SetIntValueAndType(val,
|
||||
isPercent ? ePercent : eInteger,
|
||||
strict ? nullptr : &aString);
|
||||
SetIntValueAndType(val, isPercent ? ePercent : eInteger,
|
||||
nonStrict ? &aString : nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1476,17 +1475,20 @@ nsAttrValue::ParseIntWithBounds(const nsAString& aString,
|
||||
|
||||
ResetIfSet();
|
||||
|
||||
nsresult ec;
|
||||
bool strict;
|
||||
int32_t originalVal = StringToInteger(aString, &strict, &ec);
|
||||
if (NS_FAILED(ec)) {
|
||||
nsContentUtils::ParseHTMLIntegerResultFlags result;
|
||||
int32_t originalVal = nsContentUtils::ParseHTMLInteger(aString, &result);
|
||||
if (result & nsContentUtils::eParseHTMLInteger_Error) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t val = std::max(originalVal, aMin);
|
||||
val = std::min(val, aMax);
|
||||
strict = strict && (originalVal == val);
|
||||
SetIntValueAndType(val, eInteger, strict ? nullptr : &aString);
|
||||
bool nonStrict = (val != originalVal) ||
|
||||
(result & nsContentUtils::eParseHTMLInteger_IsPercent) ||
|
||||
(result & nsContentUtils::eParseHTMLInteger_NonStandard) ||
|
||||
(result & nsContentUtils::eParseHTMLInteger_DidNotConsumeAllInput);
|
||||
|
||||
SetIntValueAndType(val, eInteger, nonStrict ? &aString : nullptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1496,14 +1498,17 @@ nsAttrValue::ParseNonNegativeIntValue(const nsAString& aString)
|
||||
{
|
||||
ResetIfSet();
|
||||
|
||||
nsresult ec;
|
||||
bool strict;
|
||||
int32_t originalVal = StringToInteger(aString, &strict, &ec);
|
||||
if (NS_FAILED(ec) || originalVal < 0) {
|
||||
nsContentUtils::ParseHTMLIntegerResultFlags result;
|
||||
int32_t originalVal = nsContentUtils::ParseHTMLInteger(aString, &result);
|
||||
if ((result & nsContentUtils::eParseHTMLInteger_Error) || originalVal < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SetIntValueAndType(originalVal, eInteger, strict ? nullptr : &aString);
|
||||
bool nonStrict = (result & nsContentUtils::eParseHTMLInteger_IsPercent) ||
|
||||
(result & nsContentUtils::eParseHTMLInteger_NonStandard) ||
|
||||
(result & nsContentUtils::eParseHTMLInteger_DidNotConsumeAllInput);
|
||||
|
||||
SetIntValueAndType(originalVal, eInteger, nonStrict ? &aString : nullptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1513,14 +1518,17 @@ nsAttrValue::ParsePositiveIntValue(const nsAString& aString)
|
||||
{
|
||||
ResetIfSet();
|
||||
|
||||
nsresult ec;
|
||||
bool strict;
|
||||
int32_t originalVal = StringToInteger(aString, &strict, &ec);
|
||||
if (NS_FAILED(ec) || originalVal <= 0) {
|
||||
nsContentUtils::ParseHTMLIntegerResultFlags result;
|
||||
int32_t originalVal = nsContentUtils::ParseHTMLInteger(aString, &result);
|
||||
if ((result & nsContentUtils::eParseHTMLInteger_Error) || originalVal <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SetIntValueAndType(originalVal, eInteger, strict ? nullptr : &aString);
|
||||
bool nonStrict = (result & nsContentUtils::eParseHTMLInteger_IsPercent) ||
|
||||
(result & nsContentUtils::eParseHTMLInteger_NonStandard) ||
|
||||
(result & nsContentUtils::eParseHTMLInteger_DidNotConsumeAllInput);
|
||||
|
||||
SetIntValueAndType(originalVal, eInteger, nonStrict ? &aString : nullptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1878,78 +1886,6 @@ nsAttrValue::GetStringBuffer(const nsAString& aValue) const
|
||||
return buf.forget();
|
||||
}
|
||||
|
||||
int32_t
|
||||
nsAttrValue::StringToInteger(const nsAString& aValue, bool* aStrict,
|
||||
nsresult* aErrorCode,
|
||||
bool aCanBePercent,
|
||||
bool* aIsPercent) const
|
||||
{
|
||||
*aStrict = true;
|
||||
*aErrorCode = NS_ERROR_ILLEGAL_VALUE;
|
||||
if (aCanBePercent) {
|
||||
*aIsPercent = false;
|
||||
}
|
||||
|
||||
nsAString::const_iterator iter, end;
|
||||
aValue.BeginReading(iter);
|
||||
aValue.EndReading(end);
|
||||
|
||||
while (iter != end && nsContentUtils::IsHTMLWhitespace(*iter)) {
|
||||
*aStrict = false;
|
||||
++iter;
|
||||
}
|
||||
|
||||
if (iter == end) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool negate = false;
|
||||
if (*iter == char16_t('-')) {
|
||||
negate = true;
|
||||
++iter;
|
||||
} else if (*iter == char16_t('+')) {
|
||||
*aStrict = false;
|
||||
++iter;
|
||||
}
|
||||
|
||||
int32_t value = 0;
|
||||
int32_t pValue = 0; // Previous value, used to check integer overflow
|
||||
while (iter != end) {
|
||||
if (*iter >= char16_t('0') && *iter <= char16_t('9')) {
|
||||
value = (value * 10) + (*iter - char16_t('0'));
|
||||
++iter;
|
||||
// Checking for integer overflow.
|
||||
if (pValue > value) {
|
||||
*aStrict = false;
|
||||
*aErrorCode = NS_ERROR_ILLEGAL_VALUE;
|
||||
break;
|
||||
} else {
|
||||
pValue = value;
|
||||
*aErrorCode = NS_OK;
|
||||
}
|
||||
} else if (aCanBePercent && *iter == char16_t('%')) {
|
||||
++iter;
|
||||
*aIsPercent = true;
|
||||
if (iter != end) {
|
||||
*aStrict = false;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
*aStrict = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (negate) {
|
||||
value = -value;
|
||||
// Checking the special case of -0.
|
||||
if (!value) {
|
||||
*aStrict = false;
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
size_t
|
||||
nsAttrValue::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
|
@ -425,13 +425,6 @@ private:
|
||||
bool EnsureEmptyAtomArray();
|
||||
already_AddRefed<nsStringBuffer>
|
||||
GetStringBuffer(const nsAString& aValue) const;
|
||||
// aStrict is set true if stringifying the return value equals with
|
||||
// aValue.
|
||||
int32_t StringToInteger(const nsAString& aValue,
|
||||
bool* aStrict,
|
||||
nsresult* aErrorCode,
|
||||
bool aCanBePercent = false,
|
||||
bool* aIsPercent = nullptr) const;
|
||||
// Given an enum table and a particular entry in that table, return
|
||||
// the actual integer value we should store.
|
||||
int32_t EnumTableEntryToValue(const EnumTable* aEnumTable,
|
||||
|
@ -878,6 +878,81 @@ nsContentUtils::InternalSerializeAutocompleteAttribute(const nsAttrValue* aAttrV
|
||||
return eAutocompleteAttrState_Invalid;
|
||||
}
|
||||
|
||||
// Parse an integer according to HTML spec
|
||||
int32_t
|
||||
nsContentUtils::ParseHTMLInteger(const nsAString& aValue,
|
||||
ParseHTMLIntegerResultFlags *aResult)
|
||||
{
|
||||
int result = eParseHTMLInteger_NoFlags;
|
||||
|
||||
nsAString::const_iterator iter, end;
|
||||
aValue.BeginReading(iter);
|
||||
aValue.EndReading(end);
|
||||
|
||||
while (iter != end && nsContentUtils::IsHTMLWhitespace(*iter)) {
|
||||
result |= eParseHTMLInteger_NonStandard;
|
||||
++iter;
|
||||
}
|
||||
|
||||
if (iter == end) {
|
||||
result |= eParseHTMLInteger_Error | eParseHTMLInteger_ErrorNoValue;
|
||||
*aResult = (ParseHTMLIntegerResultFlags)result;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool negate = false;
|
||||
if (*iter == char16_t('-')) {
|
||||
negate = true;
|
||||
++iter;
|
||||
} else if (*iter == char16_t('+')) {
|
||||
result |= eParseHTMLInteger_NonStandard;
|
||||
++iter;
|
||||
}
|
||||
|
||||
bool foundValue = false;
|
||||
int32_t value = 0;
|
||||
int32_t pValue = 0; // Previous value, used to check integer overflow
|
||||
while (iter != end) {
|
||||
if (*iter >= char16_t('0') && *iter <= char16_t('9')) {
|
||||
value = (value * 10) + (*iter - char16_t('0'));
|
||||
++iter;
|
||||
// Checking for integer overflow.
|
||||
if (pValue > value) {
|
||||
result |= eParseHTMLInteger_Error | eParseHTMLInteger_ErrorOverflow;
|
||||
break;
|
||||
} else {
|
||||
foundValue = true;
|
||||
pValue = value;
|
||||
}
|
||||
} else if (*iter == char16_t('%')) {
|
||||
++iter;
|
||||
result |= eParseHTMLInteger_IsPercent;
|
||||
break;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundValue) {
|
||||
result |= eParseHTMLInteger_Error | eParseHTMLInteger_ErrorNoValue;
|
||||
}
|
||||
|
||||
if (negate) {
|
||||
value = -value;
|
||||
// Checking the special case of -0.
|
||||
if (!value) {
|
||||
result |= eParseHTMLInteger_NonStandard;
|
||||
}
|
||||
}
|
||||
|
||||
if (iter != end) {
|
||||
result |= eParseHTMLInteger_DidNotConsumeAllInput;
|
||||
}
|
||||
|
||||
*aResult = (ParseHTMLIntegerResultFlags)result;
|
||||
return value;
|
||||
}
|
||||
|
||||
#define SKIP_WHITESPACE(iter, end_iter, end_res) \
|
||||
while ((iter) != (end_iter) && nsCRT::IsAsciiSpace(*(iter))) { \
|
||||
++(iter); \
|
||||
|
Loading…
Reference in New Issue
Block a user