1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-07-30 22:43:14 +03:00

fixed an error reporting bug in Relax-NG when we end up with multiple

* relaxng.c: fixed an error reporting bug in Relax-NG when we end
  up with multiple states, select the "best" one. Fix #120682
* result/relaxng/tutor11_2_3.err: small change resulting

* xmlschemastypes.c: applied base64 support patch from Anthony Carrico
This commit is contained in:
Daniel Veillard
2003-08-27 14:15:15 +00:00
parent aa3cfbd080
commit 1ac24d36b1
4 changed files with 1093 additions and 777 deletions

View File

@ -1,3 +1,13 @@
Wed Aug 27 16:12:41 CEST 2003 Daniel Veillard <daniel@veillard.com>
* relaxng.c: fixed an error reporting bug in Relax-NG when we end
up with multiple states, select the "best" one. Fix #120682
* result/relaxng/tutor11_2_3.err: small change resulting
Wed Aug 27 11:25:25 CEST 2003 Daniel Veillard <daniel@veillard.com>
* xmlschemastypes.c: applied base64 support patch from Anthony Carrico
Wed Aug 27 10:58:51 CEST 2003 Igor Zlatkovic <igor@zlatkovic.com>
* include/libxml/[threads-xpointer].h: realigned parameters

142
relaxng.c
View File

@ -7786,7 +7786,8 @@ xmlRelaxNGValidateCompiledContent(xmlRelaxNGValidCtxtPtr ctxt,
************************************************************************/
static int xmlRelaxNGValidateAttributeList(xmlRelaxNGValidCtxtPtr ctxt,
xmlRelaxNGDefinePtr defines);
static int xmlRelaxNGValidateElementEnd(xmlRelaxNGValidCtxtPtr ctxt);
static int xmlRelaxNGValidateElementEnd(xmlRelaxNGValidCtxtPtr ctxt, int log);
static void xmlRelaxNGLogBestError(xmlRelaxNGValidCtxtPtr ctxt);
/**
* xmlRelaxNGElemPush:
@ -7944,7 +7945,7 @@ xmlRelaxNGValidateProgressiveCallback(xmlRegExecCtxtPtr exec ATTRIBUTE_UNUSED,
}
if (ctxt->state != NULL) {
ctxt->state->seq = NULL;
ret = xmlRelaxNGValidateElementEnd(ctxt);
ret = xmlRelaxNGValidateElementEnd(ctxt, 1);
if (ret != 0) {
ctxt->pstate = -1;
}
@ -7953,16 +7954,27 @@ xmlRelaxNGValidateProgressiveCallback(xmlRegExecCtxtPtr exec ATTRIBUTE_UNUSED,
int tmp = -1, i;
oldflags = ctxt->flags;
ctxt->flags |= FLAGS_IGNORABLE;
for (i = 0; i < ctxt->states->nbState; i++) {
state = ctxt->states->tabState[i];
ctxt->state = state;
ctxt->state->seq = NULL;
if (xmlRelaxNGValidateElementEnd(ctxt) == 0)
if (xmlRelaxNGValidateElementEnd(ctxt, 0) == 0) {
tmp = 0;
xmlRelaxNGFreeValidState(ctxt, state);
break;
}
}
if (tmp != 0) {
/*
* validation error, log the message for the "best" one
*/
ctxt->flags |= FLAGS_IGNORABLE;
xmlRelaxNGLogBestError(ctxt);
}
for (i = 0; i < ctxt->states->nbState; i++) {
xmlRelaxNGFreeValidState(ctxt,
ctxt->states->tabState[i]);
}
xmlRelaxNGFreeStates(ctxt, ctxt->states);
ctxt->states = NULL;
@ -9301,9 +9313,75 @@ xmlRelaxNGElementMatch(xmlRelaxNGValidCtxtPtr ctxt,
return(ret);
}
/**
* xmlRelaxNGBestState:
* @ctxt: a Relax-NG validation context
*
* Find the "best" state in the ctxt->states list of states to report
* errors about. I.e. a state with no element left in the child list
* or the one with the less attributes left.
* This is called only if a falidation error was detected
*
* Returns the index of the "best" state or -1 in case of error
*/
static int
xmlRelaxNGBestState(xmlRelaxNGValidCtxtPtr ctxt) {
xmlRelaxNGValidStatePtr state;
int i, tmp;
int best = -1;
int value = 1000000;
if ((ctxt == NULL) || (ctxt->states == NULL) ||
(ctxt->states->nbState <= 0))
return(-1);
for (i = 0;i < ctxt->states->nbState;i++) {
state = ctxt->states->tabState[i];
if (state == NULL)
continue;
if (state->seq != NULL) {
if ((best == -1) || (value > 100000)) {
value = 100000;
best = i;
}
} else {
tmp = state->nbAttrLeft;
if ((best == -1) || (value > tmp)) {
value = tmp;
best = i;
}
}
}
return(best);
}
/**
* xmlRelaxNGLogBestError:
* @ctxt: a Relax-NG validation context
*
* Find the "best" state in the ctxt->states list of states to report
* errors about and log it.
*/
static void
xmlRelaxNGLogBestError(xmlRelaxNGValidCtxtPtr ctxt) {
int best;
if ((ctxt == NULL) || (ctxt->states == NULL) ||
(ctxt->states->nbState <= 0))
return;
best = xmlRelaxNGBestState(ctxt);
if ((best >= 0) && (best < ctxt->states->nbState)) {
ctxt->state = ctxt->states->tabState[best];
xmlRelaxNGValidateElementEnd(ctxt, 1);
}
}
/**
* xmlRelaxNGValidateElementEnd:
* @ctxt: a Relax-NG validation context
* @log: indicate that error logging should be done
*
* Validate the end of the element, implements check that
* there is nothing left not consumed in the element content
@ -9312,27 +9390,31 @@ xmlRelaxNGElementMatch(xmlRelaxNGValidCtxtPtr ctxt,
* Returns 0 if the validation succeeded or an error code.
*/
static int
xmlRelaxNGValidateElementEnd(xmlRelaxNGValidCtxtPtr ctxt) {
int ret = 0, i;
xmlRelaxNGValidateElementEnd(xmlRelaxNGValidCtxtPtr ctxt, int log) {
int i;
xmlRelaxNGValidStatePtr state;
state = ctxt->state;
if (state->seq != NULL) {
state->seq = xmlRelaxNGSkipIgnored(ctxt, state->seq);
if (state->seq != NULL) {
if (log) {
VALID_ERR3(XML_RELAXNG_ERR_EXTRACONTENT,
state->node->name, state->seq->name);
ret = -1;
}
return(-1);
}
}
for (i = 0;i < state->nbAttrs;i++) {
if (state->attrs[i] != NULL) {
if (log) {
VALID_ERR3(XML_RELAXNG_ERR_INVALIDATTR,
state->attrs[i]->name, state->node->name);
ret = -1;
}
return(-1 -i);
}
}
return(ret);
return(0);
}
/**
@ -9503,16 +9585,26 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
if (ctxt->states != NULL) {
tmp = -1;
ctxt->flags |= FLAGS_IGNORABLE;
for (i = 0; i < ctxt->states->nbState; i++) {
state = ctxt->states->tabState[i];
ctxt->state = state;
ctxt->state->seq = nseq;
if (xmlRelaxNGValidateElementEnd(ctxt) == 0)
if (xmlRelaxNGValidateElementEnd(ctxt, 0) == 0) {
tmp = 0;
xmlRelaxNGFreeValidState(ctxt, state);
break;
}
}
if (tmp != 0) {
/*
* validation error, log the message for the "best" one
*/
ctxt->flags |= FLAGS_IGNORABLE;
xmlRelaxNGLogBestError(ctxt);
}
for (i = 0; i < ctxt->states->nbState; i++) {
xmlRelaxNGFreeValidState(ctxt,
ctxt->states->tabState[i]);
}
xmlRelaxNGFreeStates(ctxt, ctxt->states);
ctxt->flags = oldflags;
@ -9523,7 +9615,7 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
state = ctxt->state;
ctxt->state->seq = nseq;
if (ret == 0)
ret = xmlRelaxNGValidateElementEnd(ctxt);
ret = xmlRelaxNGValidateElementEnd(ctxt, 1);
xmlRelaxNGFreeValidState(ctxt, state);
}
} else {
@ -9547,15 +9639,25 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
if (ctxt->states != NULL) {
tmp = -1;
ctxt->flags |= FLAGS_IGNORABLE;
for (i = 0; i < ctxt->states->nbState; i++) {
state = ctxt->states->tabState[i];
ctxt->state = state;
if (xmlRelaxNGValidateElementEnd(ctxt) == 0)
if (xmlRelaxNGValidateElementEnd(ctxt, 0) == 0) {
tmp = 0;
xmlRelaxNGFreeValidState(ctxt, state);
break;
}
}
if (tmp != 0) {
/*
* validation error, log the message for the "best" one
*/
ctxt->flags |= FLAGS_IGNORABLE;
xmlRelaxNGLogBestError(ctxt);
}
for (i = 0; i < ctxt->states->nbState; i++) {
xmlRelaxNGFreeValidState(ctxt,
ctxt->states->tabState[i]);
}
xmlRelaxNGFreeStates(ctxt, ctxt->states);
ctxt->flags = oldflags;
@ -9565,7 +9667,7 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
} else {
state = ctxt->state;
if (ret == 0)
ret = xmlRelaxNGValidateElementEnd(ctxt);
ret = xmlRelaxNGValidateElementEnd(ctxt, 1);
xmlRelaxNGFreeValidState(ctxt, state);
}
}

View File

@ -1,2 +1,2 @@
RNG validity error: file ./test/relaxng/tutor11_2_3.xml line 3 element card
Invalid attribute foo for element card
Invalid attribute b for element card

View File

@ -83,7 +83,8 @@ typedef enum {
XML_SCHEMAS_USHORT,
XML_SCHEMAS_BYTE,
XML_SCHEMAS_UBYTE,
XML_SCHEMAS_HEXBINARY
XML_SCHEMAS_HEXBINARY,
XML_SCHEMAS_BASE64BINARY
} xmlSchemaValType;
static unsigned long powten[10] = {
@ -141,6 +142,13 @@ struct _xmlSchemaValHex {
unsigned int total;
};
typedef struct _xmlSchemaValBase64 xmlSchemaValBase64;
typedef xmlSchemaValBase64 *xmlSchemaValBase64Ptr;
struct _xmlSchemaValBase64 {
xmlChar *str;
unsigned int total;
};
struct _xmlSchemaVal {
xmlSchemaValType type;
union {
@ -149,6 +157,7 @@ struct _xmlSchemaVal {
xmlSchemaValDuration dur;
xmlSchemaValQName qname;
xmlSchemaValHex hex;
xmlSchemaValBase64 base64;
float f;
double d;
int b;
@ -179,6 +188,7 @@ static xmlSchemaTypePtr xmlSchemaTypeFloatDef = NULL;
static xmlSchemaTypePtr xmlSchemaTypeBooleanDef = NULL;
static xmlSchemaTypePtr xmlSchemaTypeDoubleDef = NULL;
static xmlSchemaTypePtr xmlSchemaTypeHexBinaryDef = NULL;
static xmlSchemaTypePtr xmlSchemaTypeBase64BinaryDef = NULL;
static xmlSchemaTypePtr xmlSchemaTypeAnyURIDef = NULL;
/*
@ -290,6 +300,8 @@ xmlSchemaInitTypes(void)
XML_SCHEMAS_ANYURI);
xmlSchemaTypeHexBinaryDef = xmlSchemaInitBasicType("hexBinary",
XML_SCHEMAS_HEXBINARY);
xmlSchemaTypeBase64BinaryDef
= xmlSchemaInitBasicType("base64Binary", XML_SCHEMAS_BASE64BINARY);
/*
* derived datatypes
@ -425,6 +437,10 @@ xmlSchemaFreeValue(xmlSchemaValPtr value) {
if (value->value.hex.str != NULL)
xmlFree(value->value.hex.str);
break;
case XML_SCHEMAS_BASE64BINARY:
if (value->value.base64.str != NULL)
xmlFree(value->value.base64.str);
break;
default:
break;
}
@ -795,6 +811,25 @@ _xmlSchemaParseTimeZone (xmlSchemaValDatePtr dt, const xmlChar **str) {
return 0;
}
/**
* _xmlSchemaBase64Decode:
* @ch: a character
*
* Converts a base64 encoded character to its base 64 value.
*
* Returns 0-63 (value), 64 (pad), or -1 (not recognized)
*/
static int
_xmlSchemaBase64Decode (const xmlChar ch) {
if (('A' <= ch) && (ch <= 'Z')) return ch - 'A';
if (('a' <= ch) && (ch <= 'z')) return ch - 'a' + 26;
if (('0' <= ch) && (ch <= '9')) return ch - '0' + 52;
if ('+' == ch) return 62;
if ('/' == ch) return 63;
if ('=' == ch) return 64;
return -1;
}
/****************************************************************
* *
* XML Schema Dates/Times Datatypes Handling *
@ -1392,7 +1427,8 @@ xmlSchemaParseUInt(const xmlChar **str, unsigned long *llo,
*/
static int
xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar * value,
xmlSchemaValPtr *val, xmlNodePtr node, int flags) {
xmlSchemaValPtr * val, xmlNodePtr node, int flags)
{
xmlSchemaValPtr v;
xmlChar *norm = NULL;
int ret = 0;
@ -1421,12 +1457,12 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar *value,
case XML_SCHEMAS_STRING:
goto return0;
case XML_SCHEMAS_NORMSTRING:
TODO
goto return0;
TODO goto return0;
case XML_SCHEMAS_DECIMAL:{
const xmlChar *cur = value, *tmp;
unsigned int frac = 0, len, neg = 0;
unsigned long base = 0;
if (cur == NULL)
goto return1;
if (*cur == '+')
@ -1481,6 +1517,7 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar *value,
case XML_SCHEMAS_DOUBLE:{
const xmlChar *cur = value;
int neg = 0;
if (cur == NULL)
goto return1;
if ((cur[0] == 'N') && (cur[1] == 'a') && (cur[2] == 'N')) {
@ -1570,11 +1607,14 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar *value,
if (type == xmlSchemaTypeFloatDef) {
v = xmlSchemaNewValue(XML_SCHEMAS_FLOAT);
if (v != NULL) {
if (sscanf((const char *)value, "%f", &(v->value.f))==1) {
if (sscanf
((const char *) value, "%f",
&(v->value.f)) == 1) {
*val = v;
} else {
xmlGenericError(xmlGenericErrorContext,
"failed to scanf float %s\n", value);
"failed to scanf float %s\n",
value);
xmlSchemaFreeValue(v);
goto return1;
}
@ -1584,11 +1624,14 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar *value,
} else {
v = xmlSchemaNewValue(XML_SCHEMAS_DOUBLE);
if (v != NULL) {
if (sscanf((const char *)value, "%lf", &(v->value.d))==1) {
if (sscanf
((const char *) value, "%lf",
&(v->value.d)) == 1) {
*val = v;
} else {
xmlGenericError(xmlGenericErrorContext,
"failed to scanf double %s\n", value);
"failed to scanf double %s\n",
value);
xmlSchemaFreeValue(v);
goto return1;
}
@ -1606,11 +1649,13 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar *value,
ret = 0;
else if ((cur[0] == '1') && (cur[1] == 0))
ret = 1;
else if ((cur[0] == 't') && (cur[1] == 'r') && (cur[2] == 'u') &&
(cur[3] == 'e') && (cur[4] == 0))
else if ((cur[0] == 't') && (cur[1] == 'r')
&& (cur[2] == 'u') && (cur[3] == 'e')
&& (cur[4] == 0))
ret = 1;
else if ((cur[0] == 'f') && (cur[1] == 'a') && (cur[2] == 'l') &&
(cur[3] == 's') && (cur[4] == 'e') && (cur[5] == 0))
else if ((cur[0] == 'f') && (cur[1] == 'a')
&& (cur[2] == 'l') && (cur[3] == 's')
&& (cur[4] == 'e') && (cur[5] == 0))
ret = 0;
else
goto return1;
@ -1704,6 +1749,7 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar *value,
ret = xmlValidateQName(value, 1);
if ((ret == 0) && (node != NULL)) {
xmlChar *prefix;
local = xmlSplitQName2(value, &prefix);
if (prefix != NULL) {
xmlNsPtr ns;
@ -1766,6 +1812,7 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar *value,
if ((ret == 0) && (node != NULL) &&
(node->type == XML_ATTRIBUTE_NODE)) {
xmlAttrPtr attr = (xmlAttrPtr) node;
/*
* NOTE: the IDness might have already be declared in the DTD
*/
@ -1822,6 +1869,7 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar *value,
goto done;
case XML_SCHEMAS_ENTITY:{
xmlChar *strip;
ret = xmlValidateNCName(value, 1);
if ((node == NULL) || (node->doc == NULL))
ret = 3;
@ -1836,7 +1884,8 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar *value,
ent = xmlGetDocEntity(node->doc, value);
}
if ((ent == NULL) ||
(ent->etype != XML_EXTERNAL_GENERAL_UNPARSED_ENTITY))
(ent->etype !=
XML_EXTERNAL_GENERAL_UNPARSED_ENTITY))
ret = 4;
}
if ((ret == 0) && (val != NULL)) {
@ -1873,6 +1922,7 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar *value,
ret = xmlValidateQName(value, 1);
if ((ret == 0) && (node != NULL)) {
xmlChar *prefix;
local = xmlSplitQName2(value, &prefix);
if (prefix != NULL) {
xmlNsPtr ns;
@ -1941,7 +1991,8 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar *value,
while (((*cur >= '0') && (*cur <= '9')) ||
((*cur >= 'A') && (*cur <= 'F')) ||
((*cur >= 'a') && (*cur <= 'f'))) {
i++;cur++;
i++;
cur++;
}
if (*cur != 0)
@ -1976,6 +2027,133 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar *value,
}
goto return0;
}
case XML_SCHEMAS_BASE64BINARY:{
/* ISSUE:
*
* Ignore all stray characters? (yes, currently)
* Worry about long lines? (no, currently)
*
* rfc2045.txt:
*
* "The encoded output stream must be represented in lines of
* no more than 76 characters each. All line breaks or other
* characters not found in Table 1 must be ignored by decoding
* software. In base64 data, characters other than those in
* Table 1, line breaks, and other white space probably
* indicate a transmission error, about which a warning
* message or even a message rejection might be appropriate
* under some circumstances." */
const xmlChar *cur = value;
xmlChar *base;
int total, i = 0, pad = 0;
if (cur == NULL)
goto return1;
for (; *cur; ++cur) {
int decc;
decc = _xmlSchemaBase64Decode(*cur);
if (decc < 0) ;
else if (decc < 64)
i++;
else
break;
}
for (; *cur; ++cur) {
int decc;
decc = _xmlSchemaBase64Decode(*cur);
if (decc < 0) ;
else if (decc < 64)
goto return1;
if (decc == 64)
pad++;
}
/* rfc2045.txt: "Special processing is performed if fewer than
* 24 bits are available at the end of the data being encoded.
* A full encoding quantum is always completed at the end of a
* body. When fewer than 24 input bits are available in an
* input group, zero bits are added (on the right) to form an
* integral number of 6-bit groups. Padding at the end of the
* data is performed using the "=" character. Since all
* base64 input is an integral number of octets, only the
* following cases can arise: (1) the final quantum of
* encoding input is an integral multiple of 24 bits; here,
* the final unit of encoded output will be an integral
* multiple ofindent: Standard input:701: Warning:old style
* assignment ambiguity in "=*". Assuming "= *" 4 characters
* with no "=" padding, (2) the final
* quantum of encoding input is exactly 8 bits; here, the
* final unit of encoded output will be two characters
* followed by two "=" padding characters, or (3) the final
* quantum of encoding input is exactly 16 bits; here, the
* final unit of encoded output will be three characters
* followed by one "=" padding character." */
total = 3 * (i / 4);
if (pad == 0) {
if (i % 4 != 0)
goto return1;
} else if (pad == 1) {
int decc;
if (i % 4 != 3)
goto return1;
for (decc = _xmlSchemaBase64Decode(*cur);
(decc < 0) || (decc > 63);
decc = _xmlSchemaBase64Decode(*cur))
--cur;
/* 16bits in 24bits means 2 pad bits: nnnnnn nnmmmm mmmm00*/
/* 00111100 -> 0x3c */
if (decc & ~0x3c)
goto return1;
total += 2;
} else if (pad == 2) {
int decc;
if (i % 4 != 2)
goto return1;
for (decc = _xmlSchemaBase64Decode(*cur);
(decc < 0) || (decc > 63);
decc = _xmlSchemaBase64Decode(*cur))
--cur;
/* 8bits in 12bits means 4 pad bits: nnnnnn nn0000 */
/* 00110000 -> 0x30 */
if (decc & ~0x30)
goto return1;
total += 1;
} else
goto return1;
if (val != NULL) {
v = xmlSchemaNewValue(XML_SCHEMAS_BASE64BINARY);
if (v == NULL)
goto error;
base =
(xmlChar *) xmlMallocAtomic((i + pad + 1) *
sizeof(xmlChar));
if (base == NULL) {
xmlGenericError(xmlGenericErrorContext,
"malloc of %ld byte failed\n",
(i + pad +
1) * (long) sizeof(xmlChar));
xmlFree(v);
goto return1;
}
v->value.base64.str = base;
for (cur = value; *cur; ++cur)
if (_xmlSchemaBase64Decode(*cur) >= 0) {
*base = *cur;
++base;
}
*base = 0;
v->value.base64.total = total;
*val = v;
}
goto return0;
}
case XML_SCHEMAS_INTEGER:
case XML_SCHEMAS_PINTEGER:
case XML_SCHEMAS_NPINTEGER:
@ -1984,6 +2162,7 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar *value,
const xmlChar *cur = value;
unsigned long lo, mi, hi;
int sign = 0;
if (cur == NULL)
goto return1;
if (*cur == '-') {
@ -2040,6 +2219,7 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar *value,
unsigned long lo, mi, hi;
int total = 0;
int sign = 0;
if (cur == NULL)
goto return1;
if (*cur == '-') {
@ -2112,6 +2292,7 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar *value,
const xmlChar *cur = value;
unsigned long lo, mi, hi;
int total = 0;
if (cur == NULL)
goto return1;
ret = xmlSchemaParseUInt(&cur, &lo, &mi, &hi);
@ -2167,19 +2348,24 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar *value,
}
done:
if (norm != NULL) xmlFree(norm);
if (norm != NULL)
xmlFree(norm);
return (ret);
return3:
if (norm != NULL) xmlFree(norm);
if (norm != NULL)
xmlFree(norm);
return (3);
return1:
if (norm != NULL) xmlFree(norm);
if (norm != NULL)
xmlFree(norm);
return (1);
return0:
if (norm != NULL) xmlFree(norm);
if (norm != NULL)
xmlFree(norm);
return (0);
error:
if (norm != NULL) xmlFree(norm);
if (norm != NULL)
xmlFree(norm);
return (-1);
}
@ -3138,6 +3324,22 @@ xmlSchemaCompareValues(xmlSchemaValPtr x, xmlSchemaValPtr y) {
return(-1);
}
return (-2);
case XML_SCHEMAS_BASE64BINARY:
if (y->type == XML_SCHEMAS_BASE64BINARY) {
if (x->value.base64.total == y->value.base64.total) {
int ret = xmlStrcmp(x->value.base64.str,
y->value.base64.str);
if (ret > 0)
return(1);
else if (ret == 0)
return(0);
}
else if (x->value.base64.total > y->value.base64.total)
return(1);
else
return(-1);
}
return (-2);
case XML_SCHEMAS_STRING:
case XML_SCHEMAS_IDREFS:
case XML_SCHEMAS_ENTITIES:
@ -3284,6 +3486,8 @@ xmlSchemaValidateFacet(xmlSchemaTypePtr base ATTRIBUTE_UNUSED,
}
if ((val != NULL) && (val->type == XML_SCHEMAS_HEXBINARY))
len = val->value.hex.total;
else if ((val != NULL) && (val->type == XML_SCHEMAS_BASE64BINARY))
len = val->value.base64.total;
else {
switch (base->flags) {
case XML_SCHEMAS_IDREF: