Rebase for libxml2 2.9.4
[platform/upstream/libxml2.git] / xmlschemastypes.c
index a9edc03..5f38599 100644 (file)
@@ -62,7 +62,7 @@ struct _xmlSchemaValDate {
     long               year;
     unsigned int       mon     :4;     /* 1 <=  mon    <= 12   */
     unsigned int       day     :5;     /* 1 <=  day    <= 31   */
-    unsigned int       hour    :5;     /* 0 <=  hour   <= 23   */
+    unsigned int       hour    :5;     /* 0 <=  hour   <= 24   */
     unsigned int       min     :6;     /* 0 <=  min    <= 59   */
     double             sec;
     unsigned int       tz_flag :1;     /* is tzo explicitely set? */
@@ -242,6 +242,10 @@ xmlSchemaNewMinLengthFacet(int value)
     }
     ret->type = XML_SCHEMA_FACET_MINLENGTH;
     ret->val = xmlSchemaNewValue(XML_SCHEMAS_NNINTEGER);
+    if (ret->val == NULL) {
+        xmlFree(ret);
+       return(NULL);
+    }
     ret->val->value.decimal.lo = value;
     return (ret);
 }
@@ -1135,9 +1139,13 @@ static const unsigned int daysInMonthLeap[12] =
 #define VALID_DATE(dt)                                         \
        (VALID_YEAR(dt->year) && VALID_MONTH(dt->mon) && VALID_MDAY(dt))
 
+#define VALID_END_OF_DAY(dt)                                   \
+       ((dt)->hour == 24 && (dt)->min == 0 && (dt)->sec == 0)
+
 #define VALID_TIME(dt)                                         \
-       (VALID_HOUR(dt->hour) && VALID_MIN(dt->min) &&          \
-        VALID_SEC(dt->sec) && VALID_TZO(dt->tzo))
+       (((VALID_HOUR(dt->hour) && VALID_MIN(dt->min) &&        \
+         VALID_SEC(dt->sec)) || VALID_END_OF_DAY(dt)) &&       \
+        VALID_TZO(dt->tzo))
 
 #define VALID_DATETIME(dt)                                     \
        (VALID_DATE(dt) && VALID_TIME(dt))
@@ -1351,7 +1359,7 @@ _xmlSchemaParseTime (xmlSchemaValDatePtr dt, const xmlChar **str) {
        return ret;
     if (*cur != ':')
        return 1;
-    if (!VALID_HOUR(value))
+    if (!VALID_HOUR(value) && value != 24 /* Allow end-of-day hour */)
        return 2;
     cur++;
 
@@ -1373,7 +1381,7 @@ _xmlSchemaParseTime (xmlSchemaValDatePtr dt, const xmlChar **str) {
     if (ret != 0)
        return ret;
 
-    if ((!VALID_SEC(dt->sec)) || (!VALID_TZO(dt->tzo)))
+    if (!VALID_TIME(dt))
        return 2;
 
     *str = cur;
@@ -3844,13 +3852,14 @@ _xmlSchemaDateAdd (xmlSchemaValPtr dt, xmlSchemaValPtr dur)
             * Coverity detected an overrun in daysInMonth
             * of size 12 at position 12 with index variable "((r)->mon - 1)"
             */
-           if (tmon < 0)
-               tmon = 0;
+           if (tmon < 1)
+               tmon = 1;
            if (tmon > 12)
                tmon = 12;
             tempdays += MAX_DAYINMONTH(tyr, tmon);
             carry = -1;
-        } else if (tempdays > (long) MAX_DAYINMONTH(r->year, r->mon)) {
+        } else if (VALID_YEAR(r->year) && VALID_MONTH(r->mon) &&
+                   tempdays > (long) MAX_DAYINMONTH(r->year, r->mon)) {
             tempdays = tempdays - MAX_DAYINMONTH(r->year, r->mon);
             carry = 1;
         } else
@@ -4929,7 +4938,7 @@ xmlSchemaCompareValues(xmlSchemaValPtr x, xmlSchemaValPtr y) {
 
     if (y->type == XML_SCHEMAS_STRING)
        yws = XML_SCHEMA_WHITESPACE_PRESERVE;
-    else if (x->type == XML_SCHEMAS_NORMSTRING)
+    else if (y->type == XML_SCHEMAS_NORMSTRING)
         yws = XML_SCHEMA_WHITESPACE_REPLACE;
     else
         yws = XML_SCHEMA_WHITESPACE_COLLAPSE;
@@ -5298,6 +5307,7 @@ xmlSchemaValidateFacetInternal(xmlSchemaFacetPtr facet,
                               xmlSchemaWhitespaceValueType ws)
 {
     int ret;
+    int stringType;
 
     if (facet == NULL)
        return(-1);
@@ -5310,7 +5320,15 @@ xmlSchemaValidateFacetInternal(xmlSchemaFacetPtr facet,
            */
            if (value == NULL)
                return(-1);
-           ret = xmlRegexpExec(facet->regexp, value);
+           /*
+           * If string-derived type, regexp must be tested on the value space of
+           * the datatype.
+           * See https://www.w3.org/TR/xmlschema-2/#rf-pattern
+           */
+           stringType = val && ((val->type >= XML_SCHEMAS_STRING && val->type <= XML_SCHEMAS_NORMSTRING)
+                             || (val->type >= XML_SCHEMAS_TOKEN && val->type <= XML_SCHEMAS_NCNAME));
+           ret = xmlRegexpExec(facet->regexp,
+                               (stringType && val->value.str) ? val->value.str : value);
            if (ret == 1)
                return(0);
            if (ret == 0)
@@ -5644,7 +5662,7 @@ xmlSchemaFormatFloat(double number, char buffer[], int buffersize)
  * @val: the precomputed value
  * @retValue: the returned value
  *
- * Get a the cononical lexical representation of the value.
+ * Get the canonical lexical representation of the value.
  * The caller has to FREE the returned retValue.
  *
  * WARNING: Some value types are not supported yet, resulting
@@ -6066,7 +6084,7 @@ xmlSchemaGetCanonValue(xmlSchemaValPtr val, const xmlChar **retValue)
  * @retValue: the returned value
  * @ws: the whitespace type of the value
  *
- * Get a the cononical representation of the value.
+ * Get the canonical representation of the value.
  * The caller has to free the returned @retValue.
  *
  * Returns 0 if the value could be built, 1 if the value type is