From c6ef33a1985bfe9b3a568736040a0a35a6062b9c Mon Sep 17 00:00:00 2001 From: "aaronr%us.ibm.com" Date: Mon, 15 May 2006 21:34:39 +0000 Subject: [PATCH] NPOTDB support validating xsd:double. Bug 331897, patch by sspeiche, r=doronr+allan --- .../src/nsSchemaValidator.cpp | 93 +++++++++++++++++++ .../schema-validation/src/nsSchemaValidator.h | 10 ++ .../src/nsSchemaValidatorUtils.cpp | 16 +++- .../schema-validation/tests/schema.html | 28 ++++++ extensions/schema-validation/tests/schema.xsd | 33 +++++++ 5 files changed, 179 insertions(+), 1 deletion(-) diff --git a/extensions/schema-validation/src/nsSchemaValidator.cpp b/extensions/schema-validation/src/nsSchemaValidator.cpp index 9c76230ba10..5401a374e1f 100644 --- a/extensions/schema-validation/src/nsSchemaValidator.cpp +++ b/extensions/schema-validation/src/nsSchemaValidator.cpp @@ -924,6 +924,18 @@ nsSchemaValidator::ValidateDerivedBuiltinType(const nsAString & aNodeValue, break; } + case nsISchemaBuiltinType::BUILTIN_TYPE_DOUBLE: { + rv = ValidateBuiltinTypeDouble(aNodeValue, + aDerived->totalDigits.value, + aDerived->maxExclusive.value, + aDerived->minExclusive.value, + aDerived->maxInclusive.value, + aDerived->minInclusive.value, + &aDerived->enumerationList, + &isValid); + break; + } + case nsISchemaBuiltinType::BUILTIN_TYPE_DECIMAL: { rv = ValidateBuiltinTypeDecimal(aNodeValue, aDerived->totalDigits.value, @@ -1243,6 +1255,11 @@ nsSchemaValidator::ValidateBuiltinType(const nsAString & aNodeValue, break; } + case nsISchemaBuiltinType::BUILTIN_TYPE_DOUBLE: { + isValid = IsValidSchemaDouble(aNodeValue, nsnull); + break; + } + case nsISchemaBuiltinType::BUILTIN_TYPE_DECIMAL: { nsAutoString wholePart, fractionPart; isValid = IsValidSchemaDecimal(aNodeValue, wholePart, fractionPart); @@ -2873,6 +2890,82 @@ nsSchemaValidator::IsValidSchemaFloat(const nsAString & aNodeValue, return isValid; } +/* http://www.w3.org/TR/xmlschema-2/#double */ +nsresult +nsSchemaValidator::ValidateBuiltinTypeDouble(const nsAString & aNodeValue, + PRUint32 aTotalDigits, + const nsAString & aMaxExclusive, + const nsAString & aMinExclusive, + const nsAString & aMaxInclusive, + const nsAString & aMinInclusive, + nsStringArray *aEnumerationList, + PRBool *aResult) +{ + PRBool isValid = PR_FALSE; + + double doubleValue; + isValid = IsValidSchemaDouble(aNodeValue, &doubleValue); + + if (isValid && !aMaxExclusive.IsEmpty()) { + double maxExclusive; + + if (IsValidSchemaDouble(aMaxExclusive, &maxExclusive) && + (doubleValue >= maxExclusive)) { + isValid = PR_FALSE; + LOG((" Not valid: Value (%f) is too big", doubleValue)); + } + } + + if (isValid && !aMinExclusive.IsEmpty()) { + double minExclusive; + + if (IsValidSchemaDouble(aMinExclusive, &minExclusive) && + (doubleValue <= minExclusive)) { + isValid = PR_FALSE; + LOG((" Not valid: Value (%f) is too small", doubleValue)); + } + } + + if (isValid && !aMaxInclusive.IsEmpty()) { + double maxInclusive; + + if (IsValidSchemaDouble(aMaxInclusive, &maxInclusive) && + (doubleValue > maxInclusive)) { + isValid = PR_FALSE; + LOG((" Not valid: Value (%f) is too big", doubleValue)); + } + } + + if (isValid && !aMinInclusive.IsEmpty()) { + double minInclusive; + + if (IsValidSchemaDouble(aMinInclusive, &minInclusive) && + (doubleValue < minInclusive)) { + isValid = PR_FALSE; + LOG((" Not valid: Value (%f) is too small", doubleValue)); + } + } + + if (isValid && aEnumerationList && (aEnumerationList->Count() > 0)) { + isValid = nsSchemaValidatorUtils::HandleEnumeration(aNodeValue, + *aEnumerationList); + } + +#ifdef PR_LOGGING + LOG((isValid ? (" Value is valid!") : (" Value is not valid!"))); +#endif + + *aResult = isValid; + return NS_OK; +} + +PRBool +nsSchemaValidator::IsValidSchemaDouble(const nsAString & aNodeValue, + double *aResult) +{ + return nsSchemaValidatorUtils::IsValidSchemaDouble(aNodeValue, aResult); +} + /* http://www.w3.org/TR/xmlschema-2/#decimal */ nsresult nsSchemaValidator::ValidateBuiltinTypeDecimal(const nsAString & aNodeValue, diff --git a/extensions/schema-validation/src/nsSchemaValidator.h b/extensions/schema-validation/src/nsSchemaValidator.h index 3e1be40af01..2a344bf5d65 100644 --- a/extensions/schema-validation/src/nsSchemaValidator.h +++ b/extensions/schema-validation/src/nsSchemaValidator.h @@ -213,6 +213,16 @@ private: PRBool *aResult); PRBool IsValidSchemaFloat(const nsAString & aNodeValue, float *aResult); + nsresult ValidateBuiltinTypeDouble(const nsAString & aNodeValue, + PRUint32 aTotalDigits, + const nsAString & aMaxExclusive, + const nsAString & aMinExclusive, + const nsAString & aMaxInclusive, + const nsAString & aMinInclusive, + nsStringArray *aEnumerationList, + PRBool *aResult); + PRBool IsValidSchemaDouble(const nsAString & aNodeValue, double *aResult); + nsresult ValidateBuiltinTypeByte(const nsAString & aNodeValue, PRUint32 aTotalDigits, const nsAString & aMaxExclusive, diff --git a/extensions/schema-validation/src/nsSchemaValidatorUtils.cpp b/extensions/schema-validation/src/nsSchemaValidatorUtils.cpp index 0e00231b715..ded1d75a980 100644 --- a/extensions/schema-validation/src/nsSchemaValidatorUtils.cpp +++ b/extensions/schema-validation/src/nsSchemaValidatorUtils.cpp @@ -114,6 +114,8 @@ PRBool nsSchemaValidatorUtils::IsValidSchemaDouble(const char* aString, double *aResult) { + PRBool isValid = PR_TRUE; + if (*aString == 0) return PR_FALSE; @@ -123,7 +125,19 @@ nsSchemaValidatorUtils::IsValidSchemaDouble(const char* aString, if (aResult) *aResult = value; - return (pEnd != aString); + // If end pointer hasn't moved, then the string wasn't a + // true double (could be INF, -INF or NaN though) + if (pEnd == aString) { + NS_NAMED_LITERAL_CSTRING(temp, aString); + + // doubles may be INF, -INF or NaN + if (!temp.Equals(NS_LITERAL_CSTRING("INF")) && + !temp.Equals(NS_LITERAL_CSTRING("-INF")) && + !temp.Equals(NS_LITERAL_CSTRING("NaN"))) { + isValid = PR_FALSE; + } + } + return isValid; } PRBool diff --git a/extensions/schema-validation/tests/schema.html b/extensions/schema-validation/tests/schema.html index 4ad54042645..af322231949 100644 --- a/extensions/schema-validation/tests/schema.html +++ b/extensions/schema-validation/tests/schema.html @@ -209,6 +209,7 @@ validate("0.1", "float-test-1", false); validate("0.98", "float-test-1", false); validate("1.02", "float-test-1", true); + validate("2011.0E-3", "float-test-1", true); validate("8.342", "float-test-2", false); validate("-3.46", "float-test-2", false); @@ -218,6 +219,33 @@ validate("-1.99", "float-test-2", false); validate("-5.32", "float-test-2", false); +/* XXX Skip boundary tests for now + validate("-INF", "float-test-3", true); + validate("INF", "float-test-3", false); + validate("NaN", "float-test-3", false); + validate("4.21e4", "float-test-3", true); */ + + validate("-1", "double-test-1", false); + validate("1.230", "double-test-1", true); + validate("3.34", "double-test-1", false); + validate("0.98", "double-test-1", false); + validate("2011.0E-3", "double-test-1", true); + + validate("1.98e-14", "double-test-2", false); + validate("0", "double-test-2", false); + validate("1.230", "double-test-2", true); + validate("1.230E42", "double-test-2", true); + +/* XXX Skip boundary tests for now + validate("-INF", "double-test-3", true); + validate("NaN", "double-test-3", true); + + validate("-INF", "double-test-4", true); + validate("INF", "double-test-4", false); + validate("NaN", "double-test-4", false); + validate("1.0E12", "double-test-4", true); + validate("-0", "double-test-4", true); */ + validate("220.343434", "decimal-test-1", true); validate("220.3434a34", "decimal-test-1", false); validate("220.343.34", "decimal-test-1", false); diff --git a/extensions/schema-validation/tests/schema.xsd b/extensions/schema-validation/tests/schema.xsd index 59dfa06dadd..2cae6c962cf 100644 --- a/extensions/schema-validation/tests/schema.xsd +++ b/extensions/schema-validation/tests/schema.xsd @@ -108,6 +108,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +