summaryrefslogtreecommitdiff
path: root/xmlschemastypes.c
diff options
context:
space:
mode:
Diffstat (limited to 'xmlschemastypes.c')
-rw-r--r--xmlschemastypes.c166
1 files changed, 108 insertions, 58 deletions
diff --git a/xmlschemastypes.c b/xmlschemastypes.c
index 9d99bbb..ffb2505 100644
--- a/xmlschemastypes.c
+++ b/xmlschemastypes.c
@@ -434,9 +434,7 @@ xmlSchemaInitTypes(void)
}
memset(wild, 0, sizeof(xmlSchemaWildcard));
wild->type = XML_SCHEMA_TYPE_ANY;
- wild->any = 1;
- wild->minOccurs = 1;
- wild->maxOccurs = 1;
+ wild->any = 1;
wild->processContents = XML_SCHEMAS_ANY_LAX;
particle->children = (xmlSchemaTreeItemPtr) wild;
/*
@@ -450,9 +448,7 @@ xmlSchemaInitTypes(void)
}
memset(wild, 0, sizeof(xmlSchemaWildcard));
wild->any = 1;
- wild->processContents = XML_SCHEMAS_ANY_LAX;
- wild->minOccurs = 1;
- wild->maxOccurs = 1;
+ wild->processContents = XML_SCHEMAS_ANY_LAX;
xmlSchemaTypeAnyTypeDef->attributeWildcard = wild;
}
xmlSchemaTypeAnySimpleTypeDef = xmlSchemaInitBasicType("anySimpleType",
@@ -1700,7 +1696,7 @@ xmlSchemaValidateDates (xmlSchemaValType type,
ret = _xmlSchemaParseTimeZone(&(dt->value.date), &cur);
if (collapse)
while IS_WSP_BLANK_CH(*cur) cur++;
- if ((ret != 0) || (*cur != 0) || !VALID_DATETIME((&(dt->value.date))))
+ if ((ret != 0) || (*cur != 0) || (!(VALID_DATETIME((&(dt->value.date))))))
goto error;
@@ -2248,100 +2244,122 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar * value,
}
case XML_SCHEMAS_DECIMAL:{
const xmlChar *cur = value;
- unsigned int len, neg = 0;
+ unsigned int len, neg, integ, hasLeadingZeroes;
xmlChar cval[25];
- xmlChar *cptr = cval;
- unsigned int dec = ~0u;
+ xmlChar *cptr = cval;
- if (cur == NULL)
+ if ((cur == NULL) || (*cur == 0))
goto return1;
+ /*
+ * xs:decimal has a whitespace-facet value of 'collapse'.
+ */
if (normOnTheFly)
while IS_WSP_BLANK_CH(*cur) cur++;
- /* First we handle an optional sign */
- if (*cur == '+')
+ /*
+ * First we handle an optional sign.
+ */
+ neg = 0;
+ if (*cur == '-') {
+ neg = 1;
cur++;
- else if (*cur == '-') {
- neg = 1;
+ } else if (*cur == '+')
cur++;
- }
+ /*
+ * Disallow: "", "-", "- "
+ */
+ if (*cur == 0)
+ goto return1;
/*
* Next we "pre-parse" the number, in preparation for calling
* the common routine xmlSchemaParseUInt. We get rid of any
* leading zeroes (because we have reserved only 25 chars),
- * and note the position of any decimal point.
+ * and note the position of a decimal point.
*/
len = 0;
+ integ = ~0u;
+ hasLeadingZeroes = 0;
/*
* Skip leading zeroes.
*/
- while (*cur == '0')
+ while (*cur == '0') {
cur++;
+ hasLeadingZeroes = 1;
+ }
if (*cur != 0) {
- while (len < 24) {
+ do {
if ((*cur >= '0') && (*cur <= '9')) {
*cptr++ = *cur++;
len++;
} else if (*cur == '.') {
- if (len == 0)
- len++;
- if (dec != ~0u)
- goto return1; /* multiple decimal points */
cur++;
- if ((*cur == 0) && (cur -1 == value))
+ integ = len;
+ do {
+ if ((*cur >= '0') && (*cur <= '9')) {
+ *cptr++ = *cur++;
+ len++;
+ } else
+ break;
+ } while (len < 24);
+ /*
+ * Disallow "." but allow "00."
+ */
+ if ((len == 0) && (!hasLeadingZeroes))
goto return1;
-
- dec = len;
- while ((len < 24) && (*cur >= '0') &&
- (*cur <= '9')) {
- *cptr++ = *cur++;
- len++;
- }
break;
} else
break;
- }
+ } while (len < 24);
}
if (normOnTheFly)
while IS_WSP_BLANK_CH(*cur) cur++;
if (*cur != 0)
- goto return1; /* error if any extraneous chars */
+ goto return1; /* error if any extraneous chars */
if (val != NULL) {
v = xmlSchemaNewValue(XML_SCHEMAS_DECIMAL);
if (v != NULL) {
/*
- * If a mixed decimal, get rid of trailing zeroes
+ * Now evaluate the significant digits of the number
*/
- if (dec != ~0u) {
- while ((len > dec) && (cptr > cval) &&
- (*(cptr-1) == '0')) {
- cptr--;
- len--;
+ if (len != 0) {
+
+ if (integ != ~0u) {
+ /*
+ * Get rid of trailing zeroes in the
+ * fractional part.
+ */
+ while ((len != integ) && (*(cptr-1) == '0')) {
+ cptr--;
+ len--;
+ }
+ }
+ /*
+ * Terminate the (preparsed) string.
+ */
+ if (len != 0) {
+ *cptr = 0;
+ cptr = cval;
+
+ xmlSchemaParseUInt((const xmlChar **)&cptr,
+ &v->value.decimal.lo,
+ &v->value.decimal.mi,
+ &v->value.decimal.hi);
}
}
- *cptr = 0; /* Terminate our (preparsed) string */
- cptr = cval;
- /*
- * Now evaluate the significant digits of the number
- */
- if (*cptr != 0)
- xmlSchemaParseUInt((const xmlChar **)&cptr,
- &v->value.decimal.lo,
- &v->value.decimal.mi,
- &v->value.decimal.hi);
/*
* Set the total digits to 1 if a zero value.
*/
- if (len == 0)
- len++;
v->value.decimal.sign = neg;
- if (dec == ~0u) {
- v->value.decimal.frac = 0;
- v->value.decimal.total = len;
+ if (len == 0) {
+ /* Speedup for zero values. */
+ v->value.decimal.total = 1;
} else {
- v->value.decimal.frac = len - dec;
v->value.decimal.total = len;
+ if (integ == ~0u)
+ v->value.decimal.frac = 0;
+ else
+ v->value.decimal.frac = len - integ;
}
*val = v;
}
@@ -3406,10 +3424,42 @@ xmlSchemaCompareDecimals(xmlSchemaValPtr x, xmlSchemaValPtr y)
*/
integx = x->value.decimal.total - x->value.decimal.frac;
integy = y->value.decimal.total - y->value.decimal.frac;
+ /*
+ * NOTE: We changed the "total" for values like "0.1"
+ * (or "-0.1" or ".1") to be 1, which was 2 previously.
+ * Therefore the special case, when such values are
+ * compared with 0, needs to be handled separately;
+ * otherwise a zero would be recognized incorrectly as
+ * greater than those values. This has the nice side effect
+ * that we gain an overall optimized comparison with zeroes.
+ * Note that a "0" has a "total" of 1 already.
+ */
+ if (integx == 1) {
+ if (x->value.decimal.lo == 0) {
+ if (integy != 1)
+ return -order;
+ else if (y->value.decimal.lo != 0)
+ return -order;
+ else
+ return(0);
+ }
+ }
+ if (integy == 1) {
+ if (y->value.decimal.lo == 0) {
+ if (integx != 1)
+ return order;
+ else if (x->value.decimal.lo != 0)
+ return order;
+ else
+ return(0);
+ }
+ }
+
if (integx > integy)
return order;
else if (integy > integx)
return -order;
+
/*
* If the number of integral digits is the same for both numbers,
* then things get a little more complicated. We need to "normalize"
@@ -3763,8 +3813,8 @@ _xmlSchemaDateAdd (xmlSchemaValPtr dt, xmlSchemaValPtr dur)
while (1) {
if (tempdays < 1) {
- long tmon = (long) MODULO_RANGE(r->mon-1, 1, 13);
- long tyr = r->year + (long)FQUOTIENT_RANGE(r->mon-1, 1, 13);
+ long tmon = (long) MODULO_RANGE((int)r->mon-1, 1, 13);
+ long tyr = r->year + (long)FQUOTIENT_RANGE((int)r->mon-1, 1, 13);
if (tyr == 0)
tyr--;
tempdays += MAX_DAYINMONTH(tyr, tmon);
@@ -5377,7 +5427,7 @@ xmlSchemaValidateFacetInternal(xmlSchemaFacetPtr facet,
case XML_SCHEMA_FACET_FRACTIONDIGITS:
if ((facet->val == NULL) ||
- ((facet->val->type != XML_SCHEMAS_DECIMAL) &&
+ ((facet->val->type != XML_SCHEMAS_PINTEGER) &&
(facet->val->type != XML_SCHEMAS_NNINTEGER)) ||
(facet->val->value.decimal.frac != 0)) {
return(-1);