From d2298791af5f9104e5cbd9f58c731f2116195bcd Mon Sep 17 00:00:00 2001 From: Daniel Veillard Date: Fri, 14 Feb 2003 16:54:11 +0000 Subject: [PATCH] more testing on the Relax-NG front, cleaning up the regression tests * check-relaxng-test-suite.py relaxng.c: more testing on the Relax-NG front, cleaning up the regression tests failures current state and I forgot support for "mixed": found 373 test schemas: 280 success 93 failures found 529 test instances: 401 success 68 failures * tree.c include/libxml/tree.h xmlschemastypes.c: finished and moved the Name, NCName and QName validation routine in tree.c * uri.c: fixed handling of URI ending up with #, i.e. having an empty fragment ID. * result/relaxng/*: updated the results Daniel --- ChangeLog | 13 + check-relaxng-test-suite.py | 29 ++- include/libxml/tree.h | 3 + relaxng.c | 441 +++++++++++++++++++++++++++++---- result/relaxng/spec1_err | 2 +- result/relaxng/tutor10_1_4.err | 4 +- result/relaxng/tutor10_1_5.err | 4 +- result/relaxng/tutor10_1_6.err | 4 +- result/relaxng/tutor10_2_3.err | 4 +- result/relaxng/tutor10_2_4.err | 4 +- result/relaxng/tutor10_7_3.err | 2 +- result/relaxng/tutor10_8_3.err | 2 +- result/relaxng/tutor11_2_2.err | 2 +- result/relaxng/tutor11_2_3.err | 2 +- result/relaxng/tutor12_1_err | 2 +- result/relaxng/tutor3_2_1.err | 4 +- result/relaxng/tutor3_5_2.err | 2 +- result/relaxng/tutor3_7_err | 2 +- result/relaxng/tutor5_3_1.err | 2 +- result/relaxng/tutor6_1_3.err | 2 +- result/relaxng/tutor6_2_4.err | 2 +- result/relaxng/tutor6_3_1.err | 2 +- result/relaxng/tutor7_1_2.err | 6 +- result/relaxng/tutor7_1_3.err | 6 +- result/relaxng/tutor7_2_4.err | 4 +- result/relaxng/tutor7_3_4.err | 6 +- result/relaxng/tutor7_3_5.err | 6 +- result/relaxng/tutor8_2_4.err | 6 +- result/relaxng/tutor8_2_5.err | 4 +- result/relaxng/tutor8_2_6.err | 2 +- result/relaxng/tutor9_5_2.err | 2 +- result/relaxng/tutor9_5_3.err | 2 +- result/relaxng/tutor9_6_2.err | 2 +- result/relaxng/tutor9_6_3.err | 2 +- tree.c | 240 ++++++++++++++++++ uri.c | 2 +- xmlschemastypes.c | 136 +--------- 37 files changed, 728 insertions(+), 232 deletions(-) diff --git a/ChangeLog b/ChangeLog index 66067f59..843e8bce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +Fri Feb 14 17:49:26 CET 2003 Daniel Veillard + + * check-relaxng-test-suite.py relaxng.c: more testing on the + Relax-NG front, cleaning up the regression tests failures + current state and I forgot support for "mixed": + found 373 test schemas: 280 success 93 failures + found 529 test instances: 401 success 68 failures + * tree.c include/libxml/tree.h xmlschemastypes.c: finished and + moved the Name, NCName and QName validation routine in tree.c + * uri.c: fixed handling of URI ending up with #, i.e. having + an empty fragment ID. + * result/relaxng/*: updated the results + Thu Feb 13 16:49:24 CET 2003 Daniel Veillard * check-xinclude-test-suite.py: improved the script accordingly diff --git a/check-relaxng-test-suite.py b/check-relaxng-test-suite.py index feb68174..00fe9025 100755 --- a/check-relaxng-test-suite.py +++ b/check-relaxng-test-suite.py @@ -45,7 +45,6 @@ def resolver(URL, ID, ctxt): log.write("resources: %s\n" % (resources)) return None -libxml2.setEntityLoader(resolver) # # handle a valid instance @@ -235,7 +234,6 @@ def handle_dir(node, dir): for r in res: handle_resource(r, name) - # # handle a testCase element # @@ -285,7 +283,17 @@ def handle_testCase(node): # # handle a testSuite element # -def handle_testSuite(node): +def handle_testSuite(node, level = 0): + global nb_schemas_tests, nb_schemas_success, nb_schemas_failed + global nb_instances_tests, nb_instances_success, nb_instances_failed + if level >= 1: + old_schemas_tests = nb_schemas_tests + old_schemas_success = nb_schemas_success + old_schemas_failed = nb_schemas_failed + old_instances_tests = nb_instances_tests + old_instances_success = nb_instances_success + old_instances_failed = nb_instances_failed + docs = node.xpathEval('documentation') authors = node.xpathEval('author') if docs != []: @@ -306,13 +314,26 @@ def handle_testSuite(node): for test in node.xpathEval('testCase'): handle_testCase(test) for test in node.xpathEval('testSuite'): - handle_testSuite(test) + handle_testSuite(test, level + 1) + if level >= 1 and sections != []: + if nb_schemas_tests != old_schemas_tests: + print "found %d test schemas: %d success %d failures" % ( + nb_schemas_tests - old_schemas_tests, + nb_schemas_success - old_schemas_success, + nb_schemas_failed - old_schemas_failed) + if nb_instances_tests != old_instances_tests: + print "found %d test instances: %d success %d failures" % ( + nb_instances_tests - old_instances_tests, + nb_instances_success - old_instances_success, + nb_instances_failed - old_instances_failed) # # Parse the conf file # +libxml2.substituteEntitiesDefault(1); testsuite = libxml2.parseFile(CONF) +libxml2.setEntityLoader(resolver) root = testsuite.getRootElement() if root.name != 'testSuite': print "%s doesn't start with a testSuite element, aborting" % (CONF) diff --git a/include/libxml/tree.h b/include/libxml/tree.h index 13e218b0..d77d704e 100644 --- a/include/libxml/tree.h +++ b/include/libxml/tree.h @@ -538,6 +538,9 @@ LIBXML_DLL_IMPORT extern int xmlSaveNoEmptyTags; /* save empty tags as children; while (tmp != NULL) { tmp2 = tmp->next; if (IS_RELAXNG(tmp, "define")) { name2 = xmlGetProp(tmp, BAD_CAST "name"); + xmlRelaxNGNormExtSpace(name2); if (name2 != NULL) { if (xmlStrEqual(name, name2)) { found = 1; @@ -1193,6 +1196,7 @@ xmlRelaxNGLoadExternalRef(xmlRelaxNGParserCtxtPtr ctxt, const xmlChar *URL, if (((ctxt->flags & 1) == 0) || (ctxt->flags & 2)) \ if (ctxt->error != NULL) ctxt->error(ctxt->userData, a, b, c) +#ifdef DEBUG static const char * xmlRelaxNGDefName(xmlRelaxNGDefinePtr def) { if (def == NULL) @@ -1221,6 +1225,8 @@ xmlRelaxNGDefName(xmlRelaxNGDefinePtr def) { } return("unknown"); } +#endif + #if 0 /** * xmlRelaxNGErrorContext: @@ -1652,6 +1658,10 @@ xmlRelaxNGGetDataTypeLibrary(xmlRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED, if ((IS_RELAXNG(node, "data")) || (IS_RELAXNG(node, "value"))) { ret = xmlGetProp(node, BAD_CAST "datatypeLibrary"); if (ret != NULL) { + if (ret[0] == 0) { + xmlFree(ret); + return(NULL); + } escape = xmlURIEscapeStr(ret, BAD_CAST ":/#?"); if (escape == NULL) { return(ret); @@ -1664,6 +1674,10 @@ xmlRelaxNGGetDataTypeLibrary(xmlRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED, while ((node != NULL) && (node->type == XML_ELEMENT_NODE)) { ret = xmlGetProp(node, BAD_CAST "datatypeLibrary"); if (ret != NULL) { + if (ret[0] == 0) { + xmlFree(ret); + return(NULL); + } escape = xmlURIEscapeStr(ret, BAD_CAST ":/#?"); if (escape == NULL) { return(ret); @@ -1700,6 +1714,14 @@ xmlRelaxNGParseValue(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) { type = xmlGetProp(node, BAD_CAST "type"); if (type != NULL) { + xmlRelaxNGNormExtSpace(type); + if (xmlValidateNCName(type, 0)) { + if (ctxt->error != NULL) + ctxt->error(ctxt->userData, + "value type '%s' is not an NCName\n", + type); + ctxt->nbErrors++; + } library = xmlRelaxNGGetDataTypeLibrary(ctxt, node); if (library == NULL) library = xmlStrdup(BAD_CAST "http://relaxng.org/ns/structure/1.0"); @@ -1786,6 +1808,14 @@ xmlRelaxNGParseData(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) { ctxt->nbErrors++; return(NULL); } + xmlRelaxNGNormExtSpace(type); + if (xmlValidateNCName(type, 0)) { + if (ctxt->error != NULL) + ctxt->error(ctxt->userData, + "data type '%s' is not an NCName\n", + type); + ctxt->nbErrors++; + } library = xmlRelaxNGGetDataTypeLibrary(ctxt, node); if (library == NULL) library = xmlStrdup(BAD_CAST "http://relaxng.org/ns/structure/1.0"); @@ -2119,6 +2149,11 @@ xmlRelaxNGParseInterleave(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) { } } child = node->children; + if (child == NULL) { + if (ctxt->error != NULL) + ctxt->error(ctxt->userData, "Element interleave is empty\n"); + ctxt->nbErrors++; + } while (child != NULL) { if (IS_RELAXNG(child, "element")) { cur = xmlRelaxNGParseElement(ctxt, child); @@ -2218,6 +2253,14 @@ xmlRelaxNGParseDefine(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) { "define has no name\n"); ctxt->nbErrors++; } else { + xmlRelaxNGNormExtSpace(name); + if (xmlValidateNCName(name, 0)) { + if (ctxt->error != NULL) + ctxt->error(ctxt->userData, + "define name '%s' is not an NCName\n", + name); + ctxt->nbErrors++; + } def = xmlRelaxNGNewDefine(ctxt, node); if (def == NULL) { xmlFree(name); @@ -2282,6 +2325,9 @@ static xmlRelaxNGDefinePtr xmlRelaxNGParsePattern(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) { xmlRelaxNGDefinePtr def = NULL; + if (node == NULL) { + return(NULL); + } if (IS_RELAXNG(node, "element")) { def = xmlRelaxNGParseElement(ctxt, node); } else if (IS_RELAXNG(node, "attribute")) { @@ -2291,6 +2337,11 @@ xmlRelaxNGParsePattern(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) { if (def == NULL) return(NULL); def->type = XML_RELAXNG_EMPTY; + if (node->children != NULL) { + if (ctxt->error != NULL) + ctxt->error(ctxt->userData, "empty: had a child node\n"); + ctxt->nbErrors++; + } } else if (IS_RELAXNG(node, "text")) { def = xmlRelaxNGNewDefine(ctxt, node); if (def == NULL) @@ -2306,31 +2357,66 @@ xmlRelaxNGParsePattern(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) { if (def == NULL) return(NULL); def->type = XML_RELAXNG_ZEROORMORE; - def->content = xmlRelaxNGParsePatterns(ctxt, node->children, 1); + if (node->children == NULL) { + if (ctxt->error != NULL) + ctxt->error(ctxt->userData, + "Element %s is empty\n", node->name); + ctxt->nbErrors++; + } else { + def->content = xmlRelaxNGParsePatterns(ctxt, node->children, 1); + } } else if (IS_RELAXNG(node, "oneOrMore")) { def = xmlRelaxNGNewDefine(ctxt, node); if (def == NULL) return(NULL); def->type = XML_RELAXNG_ONEORMORE; - def->content = xmlRelaxNGParsePatterns(ctxt, node->children, 1); + if (node->children == NULL) { + if (ctxt->error != NULL) + ctxt->error(ctxt->userData, + "Element %s is empty\n", node->name); + ctxt->nbErrors++; + } else { + def->content = xmlRelaxNGParsePatterns(ctxt, node->children, 1); + } } else if (IS_RELAXNG(node, "optional")) { def = xmlRelaxNGNewDefine(ctxt, node); if (def == NULL) return(NULL); def->type = XML_RELAXNG_OPTIONAL; - def->content = xmlRelaxNGParsePatterns(ctxt, node->children, 1); + if (node->children == NULL) { + if (ctxt->error != NULL) + ctxt->error(ctxt->userData, + "Element %s is empty\n", node->name); + ctxt->nbErrors++; + } else { + def->content = xmlRelaxNGParsePatterns(ctxt, node->children, 1); + } } else if (IS_RELAXNG(node, "choice")) { def = xmlRelaxNGNewDefine(ctxt, node); if (def == NULL) return(NULL); def->type = XML_RELAXNG_CHOICE; - def->content = xmlRelaxNGParsePatterns(ctxt, node->children, 0); + if (node->children == NULL) { + if (ctxt->error != NULL) + ctxt->error(ctxt->userData, + "Element %s is empty\n", node->name); + ctxt->nbErrors++; + } else { + def->content = xmlRelaxNGParsePatterns(ctxt, node->children, 0); + } } else if (IS_RELAXNG(node, "group")) { def = xmlRelaxNGNewDefine(ctxt, node); if (def == NULL) return(NULL); def->type = XML_RELAXNG_GROUP; - def->content = xmlRelaxNGParsePatterns(ctxt, node->children, 0); + if (node->children == NULL) { + if (ctxt->error != NULL) + ctxt->error(ctxt->userData, + "Element %s is empty\n", node->name); + ctxt->nbErrors++; + } else { + def->content = xmlRelaxNGParsePatterns(ctxt, node->children, 0); + } } else if (IS_RELAXNG(node, "ref")) { def = xmlRelaxNGNewDefine(ctxt, node); if (def == NULL) @@ -2343,6 +2429,14 @@ xmlRelaxNGParsePattern(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) { "ref has no name\n"); ctxt->nbErrors++; } else { + xmlRelaxNGNormExtSpace(def->name); + if (xmlValidateNCName(def->name, 0)) { + if (ctxt->error != NULL) + ctxt->error(ctxt->userData, + "ref name '%s' is not an NCName\n", + def->name); + ctxt->nbErrors++; + } if ((ctxt->define != NULL) && (xmlStrEqual(ctxt->define, def->name))) { if (ctxt->error != NULL) @@ -2390,9 +2484,11 @@ xmlRelaxNGParsePattern(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) { } } else if (IS_RELAXNG(node, "data")) { def = xmlRelaxNGParseData(ctxt, node); +#if 0 } else if (IS_RELAXNG(node, "define")) { xmlRelaxNGParseDefine(ctxt, node); def = NULL; +#endif } else if (IS_RELAXNG(node, "value")) { def = xmlRelaxNGParseValue(ctxt, node); } else if (IS_RELAXNG(node, "list")) { @@ -2400,7 +2496,14 @@ xmlRelaxNGParsePattern(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) { if (def == NULL) return(NULL); def->type = XML_RELAXNG_LIST; - def->content = xmlRelaxNGParsePatterns(ctxt, node->children, 0); + if (node->children == NULL) { + if (ctxt->error != NULL) + ctxt->error(ctxt->userData, + "Element %s is empty\n", node->name); + ctxt->nbErrors++; + } else { + def->content = xmlRelaxNGParsePatterns(ctxt, node->children, 0); + } } else if (IS_RELAXNG(node, "interleave")) { def = xmlRelaxNGParseInterleave(ctxt, node); } else if (IS_RELAXNG(node, "externalRef")) { @@ -2486,6 +2589,15 @@ xmlRelaxNGParsePattern(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) { ctxt->error(ctxt->userData, "parentRef has no name\n"); ctxt->nbErrors++; + } else { + xmlRelaxNGNormExtSpace(def->name); + if (xmlValidateNCName(def->name, 0)) { + if (ctxt->error != NULL) + ctxt->error(ctxt->userData, + "parentRef name '%s' is not an NCName\n", + def->name); + ctxt->nbErrors++; + } } if (node->children != NULL) { if (ctxt->error != NULL) @@ -2501,7 +2613,7 @@ xmlRelaxNGParsePattern(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) { "Could not create references hash\n"); ctxt->nbErrors++; def = NULL; - } else { + } else if (def->name != NULL) { int tmp; tmp = xmlHashAddEntry(ctxt->parentgrammar->refs, def->name, def); @@ -2523,9 +2635,15 @@ xmlRelaxNGParsePattern(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) { } } } - } else { + } else if (IS_RELAXNG(node, "mixed")) { TODO ctxt->nbErrors++; + } else { + if (ctxt->error != NULL) + ctxt->error(ctxt->userData, + "Unexpected node %s is not a pattern\n", + node->name); + ctxt->nbErrors++; def = NULL; } return(def); @@ -2542,7 +2660,7 @@ xmlRelaxNGParsePattern(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) { */ static xmlRelaxNGDefinePtr xmlRelaxNGParseAttribute(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) { - xmlRelaxNGDefinePtr ret, cur, last; + xmlRelaxNGDefinePtr ret, cur; xmlNodePtr child; int old_flags; @@ -2565,11 +2683,9 @@ xmlRelaxNGParseAttribute(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) { if (cur != NULL) child = child->next; - last = NULL; - while (child != NULL) { + if (child != NULL) { cur = xmlRelaxNGParsePattern(ctxt, child); if (cur != NULL) { - cur->parent = ret; switch (cur->type) { case XML_RELAXNG_EMPTY: case XML_RELAXNG_NOT_ALLOWED: @@ -2588,37 +2704,31 @@ xmlRelaxNGParseAttribute(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) { case XML_RELAXNG_CHOICE: case XML_RELAXNG_GROUP: case XML_RELAXNG_INTERLEAVE: - if (last == NULL) { - ret->content = last = cur; - } else { - if ((last->type == XML_RELAXNG_ELEMENT) && - (ret->content == last)) { - ret->content = xmlRelaxNGNewDefine(ctxt, node); - if (ret->content != NULL) { - ret->content->type = XML_RELAXNG_GROUP; - ret->content->content = last; - } else { - ret->content = last; - } - } - last->next = cur; - last = cur; - } + ret->content = cur; cur->parent = ret; break; case XML_RELAXNG_ATTRIBUTE: - cur->next = ret->attrs; - ret->attrs = cur; + if (ctxt->error != NULL) + ctxt->error(ctxt->userData, + "attribute has an attribute child\n"); + ctxt->nbErrors++; break; case XML_RELAXNG_START: case XML_RELAXNG_EXCEPT: - TODO + if (ctxt->error != NULL) + ctxt->error(ctxt->userData, + "attribute has invalid content\n"); ctxt->nbErrors++; break; } } child = child->next; } + if (child != NULL) { + if (ctxt->error != NULL) + ctxt->error(ctxt->userData, "attribute has multiple children\n"); + ctxt->nbErrors++; + } ctxt->flags = old_flags; return(ret); } @@ -2639,8 +2749,19 @@ xmlRelaxNGParseExceptNameClass(xmlRelaxNGParserCtxtPtr ctxt, xmlRelaxNGDefinePtr ret, cur, last = NULL; xmlNodePtr child; - if (!IS_RELAXNG(node, "except")) + if (!IS_RELAXNG(node, "except")) { + if (ctxt->error != NULL) + ctxt->error(ctxt->userData, + "Expecting an except node\n"); + ctxt->nbErrors++; return(NULL); + } + if (node->next != NULL) { + if (ctxt->error != NULL) + ctxt->error(ctxt->userData, + "exceptNameClass allows only a single except node\n"); + ctxt->nbErrors++; + } if (node->children == NULL) { if (ctxt->error != NULL) ctxt->error(ctxt->userData, @@ -2695,6 +2816,20 @@ xmlRelaxNGParseNameClass(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node, if (IS_RELAXNG(node, "name")) { val = xmlNodeGetContent(node); + xmlRelaxNGNormExtSpace(val); + if (xmlValidateNCName(val, 0)) { + if (ctxt->error != NULL) { + if (node->parent != NULL) + ctxt->error(ctxt->userData, + "Element %s name '%s' is not an NCName\n", + node->parent->name, val); + else + ctxt->error(ctxt->userData, + "name '%s' is not an NCName\n", + val); + } + ctxt->nbErrors++; + } ret->name = val; val = xmlGetProp(node, BAD_CAST "ns"); ret->ns = val; @@ -2721,8 +2856,30 @@ xmlRelaxNGParseNameClass(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node, (def->type == XML_RELAXNG_ATTRIBUTE)); } } else if (IS_RELAXNG(node, "choice")) { - TODO - ctxt->nbErrors++; + if (node->children == NULL) { + if (ctxt->error != NULL) + ctxt->error(ctxt->userData, + "Element choice is empty\n"); + ctxt->nbErrors++; + } else { + xmlNodePtr child; + xmlRelaxNGDefinePtr last = NULL, tmp; + + child = node->children; + while (child != NULL) { + tmp = xmlRelaxNGParseExceptNameClass(ctxt, child, + (def->type == XML_RELAXNG_ATTRIBUTE)); + if (tmp != NULL) { + if (last == NULL) { + last = ret->nameClass = tmp; + } else { + last->next = tmp; + last = tmp; + } + } + child = child->next; + } + } } else { if (ctxt->error != NULL) ctxt->error(ctxt->userData, @@ -2894,18 +3051,47 @@ xmlRelaxNGParseStart(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr nodes) { int ret = 0; xmlRelaxNGDefinePtr def = NULL; - while (nodes != NULL) { - if (IS_RELAXNG(nodes, "empty")) { - TODO + if (nodes == NULL) { + if (ctxt->error != NULL) + ctxt->error(ctxt->userData, + "start has no children\n"); + ctxt->nbErrors++; + return(-1); + } + if (IS_RELAXNG(nodes, "empty")) { + def = xmlRelaxNGNewDefine(ctxt, nodes); + if (def == NULL) + return(-1); + def->type = XML_RELAXNG_EMPTY; + if (nodes->children != NULL) { + if (ctxt->error != NULL) + ctxt->error(ctxt->userData, "element empty is not empty\n"); ctxt->nbErrors++; - } else if (IS_RELAXNG(nodes, "notAllowed")) { - TODO - ctxt->nbErrors++; - } else { - def = xmlRelaxNGParsePatterns(ctxt, nodes, 1); - ctxt->grammar->start = def; } - nodes = nodes->next; + ctxt->grammar->start = def; + } else if (IS_RELAXNG(nodes, "notAllowed")) { + def = xmlRelaxNGNewDefine(ctxt, nodes); + if (def == NULL) + return(-1); + def->type = XML_RELAXNG_NOT_ALLOWED; + if (nodes->children != NULL) { + if (ctxt->error != NULL) + ctxt->error(ctxt->userData, + "element notAllowed is not empty\n"); + ctxt->nbErrors++; + } + ctxt->grammar->start = def; + } else { + def = xmlRelaxNGParsePatterns(ctxt, nodes, 1); + ctxt->grammar->start = def; + } + nodes = nodes->next; + if (nodes != NULL) { + if (ctxt->error != NULL) + ctxt->error(ctxt->userData, + "start more than one children\n"); + ctxt->nbErrors++; + return(-1); } return(ret); } @@ -2936,7 +3122,7 @@ xmlRelaxNGParseGrammarContent(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr nodes) if (nodes->children == NULL) { if (ctxt->error != NULL) ctxt->error(ctxt->userData, - "grammar has no children\n"); + "start has no children\n"); ctxt->nbErrors++; } else { tmp = xmlRelaxNGParseStart(ctxt, nodes->children); @@ -3454,6 +3640,153 @@ xmlRelaxNGFreeParserCtxt(xmlRelaxNGParserCtxtPtr ctxt) { xmlFree(ctxt); } +/** + * xmlRelaxNGNormExtSpace: + * @value: a value + * + * Removes the leading and ending spaces of the value + * The string is modified "in situ" + */ +static void +xmlRelaxNGNormExtSpace(xmlChar *value) { + xmlChar *start = value; + xmlChar *cur = value; + if (value == NULL) + return; + + while (IS_BLANK(*cur)) cur++; + if (cur == start) { + do { + while ((*cur != 0) && (!IS_BLANK(*cur))) cur++; + if (*cur == 0) + return; + start = cur; + while (IS_BLANK(*cur)) cur++; + if (*cur == 0) { + *start = 0; + return; + } + } while (1); + } else { + do { + while ((*cur != 0) && (!IS_BLANK(*cur))) + *start++ = *cur++; + if (*cur == 0) { + *start = 0; + return; + } + /* don't try to normalize the inner spaces */ + while (IS_BLANK(*cur)) cur++; + *start++ = *cur++; + if (*cur == 0) { + *start = 0; + return; + } + } while (1); + } +} + +/** + * xmlRelaxNGCheckAttributes: + * @ctxt: a Relax-NG parser context + * @node: a Relax-NG node + * + * Check all the attributes on the given node + */ +static void +xmlRelaxNGCleanupAttributes(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) { + xmlAttrPtr cur, next; + + cur = node->properties; + while (cur != NULL) { + next = cur->next; + if ((cur->ns == NULL) || + (xmlStrEqual(cur->ns->href, xmlRelaxNGNs))) { + if (xmlStrEqual(cur->name, BAD_CAST "name")) { + if ((!xmlStrEqual(node->name, BAD_CAST "element")) && + (!xmlStrEqual(node->name, BAD_CAST "attribute")) && + (!xmlStrEqual(node->name, BAD_CAST "ref")) && + (!xmlStrEqual(node->name, BAD_CAST "parentRef")) && + (!xmlStrEqual(node->name, BAD_CAST "define"))) { + if (ctxt->error != NULL) + ctxt->error(ctxt->userData, + "Attribute %s is not allowed on %s\n", + cur->name, node->name); + ctxt->nbErrors++; + } + } else if (xmlStrEqual(cur->name, BAD_CAST "type")) { + if ((!xmlStrEqual(node->name, BAD_CAST "value")) && + (!xmlStrEqual(node->name, BAD_CAST "data"))) { + if (ctxt->error != NULL) + ctxt->error(ctxt->userData, + "Attribute %s is not allowed on %s\n", + cur->name, node->name); + ctxt->nbErrors++; + } + } else if (xmlStrEqual(cur->name, BAD_CAST "href")) { + if ((!xmlStrEqual(node->name, BAD_CAST "externalRef")) && + (!xmlStrEqual(node->name, BAD_CAST "include"))) { + if (ctxt->error != NULL) + ctxt->error(ctxt->userData, + "Attribute %s is not allowed on %s\n", + cur->name, node->name); + ctxt->nbErrors++; + } + } else if (xmlStrEqual(cur->name, BAD_CAST "combine")) { + if ((!xmlStrEqual(node->name, BAD_CAST "start")) && + (!xmlStrEqual(node->name, BAD_CAST "define"))) { + if (ctxt->error != NULL) + ctxt->error(ctxt->userData, + "Attribute %s is not allowed on %s\n", + cur->name, node->name); + ctxt->nbErrors++; + } + } else if (xmlStrEqual(cur->name, BAD_CAST "datatypeLibrary")) { + xmlChar *val; + xmlURIPtr uri; + + val = xmlNodeListGetString(node->doc, cur->children, 1); + if (val != NULL) { + if (val[0] != 0) { + uri = xmlParseURI((const char *) val); + if (uri == NULL) { + if (ctxt->error != NULL) + ctxt->error(ctxt->userData, + "Attribute %s contains invalid URI %s\n", + cur->name, val); + ctxt->nbErrors++; + } else { + if (uri->scheme == NULL) { + if (ctxt->error != NULL) + ctxt->error(ctxt->userData, + "Attribute %s URI %s is not absolute\n", + cur->name, val); + ctxt->nbErrors++; + } + if (uri->fragment != NULL) { + if (ctxt->error != NULL) + ctxt->error(ctxt->userData, + "Attribute %s URI %s has a fragment ID\n", + cur->name, val); + ctxt->nbErrors++; + } + xmlFreeURI(uri); + } + } + xmlFree(val); + } + } else if (!xmlStrEqual(cur->name, BAD_CAST "ns")) { + if (ctxt->error != NULL) + ctxt->error(ctxt->userData, + "Unknown attribute %s on %s\n", + cur->name, node->name); + ctxt->nbErrors++; + } + } + cur = next; + } +} + /** * xmlRelaxNGCleanupDoc: * @ctxt: a Relax-NG parser context @@ -3497,9 +3830,21 @@ xmlRelaxNGCleanupDoc(xmlRelaxNGParserCtxtPtr ctxt, xmlDocPtr doc) { */ if ((cur->ns == NULL) || (!xmlStrEqual(cur->ns->href, xmlRelaxNGNs))) { + if ((cur->parent != NULL) && + (cur->parent->type == XML_ELEMENT_NODE) && + ((xmlStrEqual(cur->parent->name, BAD_CAST "name")) || + (xmlStrEqual(cur->parent->name, BAD_CAST "value")) || + (xmlStrEqual(cur->parent->name, BAD_CAST "param")))) { + if (ctxt->error != NULL) + ctxt->error(ctxt->userData, + "element %s doesn't allow foreign elements\n", + cur->parent->name); + ctxt->nbErrors++; + } delete = cur; goto skip_children; } else { + xmlRelaxNGCleanupAttributes(ctxt, cur); if (xmlStrEqual(cur->name, BAD_CAST "externalRef")) { xmlChar *href, *ns, *base, *URL; xmlRelaxNGDocumentPtr docu; @@ -5349,7 +5694,11 @@ xmlRelaxNGValidateDefinition(xmlRelaxNGValidCtxtPtr ctxt, ctxt->state->value = oldvalue; if (ret == -1) { VALID_CTXT(); - VALID_ERROR2("internal error validating %s\n", define->name); + if (define->name != NULL) { + VALID_ERROR2("error validating value %s\n", define->name); + } else { + VALID_ERROR("error validating value\n"); + } } else if (ret == 0) { ctxt->state->seq = node->next; } diff --git a/result/relaxng/spec1_err b/result/relaxng/spec1_err index 0fe2d104..9e1a6e08 100644 --- a/result/relaxng/spec1_err +++ b/result/relaxng/spec1_err @@ -1 +1 @@ -Unimplemented block at relaxng.c:4849 +Unimplemented block at relaxng.c:5196 diff --git a/result/relaxng/tutor10_1_4.err b/result/relaxng/tutor10_1_4.err index 3d258549..2086fb08 100644 --- a/result/relaxng/tutor10_1_4.err +++ b/result/relaxng/tutor10_1_4.err @@ -1,4 +1,4 @@ -error detected at relaxng.c:5108 +error detected at relaxng.c:5455 Expecting a namespace for element foo -error detected at relaxng.c:5461 +error detected at relaxng.c:5812 extra data on the document diff --git a/result/relaxng/tutor10_1_5.err b/result/relaxng/tutor10_1_5.err index c4ac9097..9c448e9c 100644 --- a/result/relaxng/tutor10_1_5.err +++ b/result/relaxng/tutor10_1_5.err @@ -1,4 +1,4 @@ -error detected at relaxng.c:5114 -Expecting element foo has wrong namespace: expecting http://www.example.com error detected at relaxng.c:5461 +Expecting element foo has wrong namespace: expecting http://www.example.com +error detected at relaxng.c:5812 extra data on the document diff --git a/result/relaxng/tutor10_1_6.err b/result/relaxng/tutor10_1_6.err index c4ac9097..9c448e9c 100644 --- a/result/relaxng/tutor10_1_6.err +++ b/result/relaxng/tutor10_1_6.err @@ -1,4 +1,4 @@ -error detected at relaxng.c:5114 -Expecting element foo has wrong namespace: expecting http://www.example.com error detected at relaxng.c:5461 +Expecting element foo has wrong namespace: expecting http://www.example.com +error detected at relaxng.c:5812 extra data on the document diff --git a/result/relaxng/tutor10_2_3.err b/result/relaxng/tutor10_2_3.err index fb0f5b8f..2b656ed1 100644 --- a/result/relaxng/tutor10_2_3.err +++ b/result/relaxng/tutor10_2_3.err @@ -1,4 +1,4 @@ -error detected at relaxng.c:5122 +error detected at relaxng.c:5469 Expecting no namespace for element foo -error detected at relaxng.c:5461 +error detected at relaxng.c:5812 extra data on the document diff --git a/result/relaxng/tutor10_2_4.err b/result/relaxng/tutor10_2_4.err index fb0f5b8f..2b656ed1 100644 --- a/result/relaxng/tutor10_2_4.err +++ b/result/relaxng/tutor10_2_4.err @@ -1,4 +1,4 @@ -error detected at relaxng.c:5122 +error detected at relaxng.c:5469 Expecting no namespace for element foo -error detected at relaxng.c:5461 +error detected at relaxng.c:5812 extra data on the document diff --git a/result/relaxng/tutor10_7_3.err b/result/relaxng/tutor10_7_3.err index 984a201e..eca41dd4 100644 --- a/result/relaxng/tutor10_7_3.err +++ b/result/relaxng/tutor10_7_3.err @@ -1,2 +1,2 @@ -error detected at relaxng.c:5164 +error detected at relaxng.c:5511 Extra content for element addressBook: card diff --git a/result/relaxng/tutor10_8_3.err b/result/relaxng/tutor10_8_3.err index 984a201e..eca41dd4 100644 --- a/result/relaxng/tutor10_8_3.err +++ b/result/relaxng/tutor10_8_3.err @@ -1,2 +1,2 @@ -error detected at relaxng.c:5164 +error detected at relaxng.c:5511 Extra content for element addressBook: card diff --git a/result/relaxng/tutor11_2_2.err b/result/relaxng/tutor11_2_2.err index c423d13c..b4fc343c 100644 --- a/result/relaxng/tutor11_2_2.err +++ b/result/relaxng/tutor11_2_2.err @@ -1,2 +1,2 @@ -error detected at relaxng.c:5177 +error detected at relaxng.c:5524 Invalid attribute foo for element card diff --git a/result/relaxng/tutor11_2_3.err b/result/relaxng/tutor11_2_3.err index 2d4fb595..477e5372 100644 --- a/result/relaxng/tutor11_2_3.err +++ b/result/relaxng/tutor11_2_3.err @@ -1,2 +1,2 @@ -error detected at relaxng.c:5177 +error detected at relaxng.c:5524 Invalid attribute b for element card diff --git a/result/relaxng/tutor12_1_err b/result/relaxng/tutor12_1_err index 0fe2d104..9e1a6e08 100644 --- a/result/relaxng/tutor12_1_err +++ b/result/relaxng/tutor12_1_err @@ -1 +1 @@ -Unimplemented block at relaxng.c:4849 +Unimplemented block at relaxng.c:5196 diff --git a/result/relaxng/tutor3_2_1.err b/result/relaxng/tutor3_2_1.err index a005926d..05208e72 100644 --- a/result/relaxng/tutor3_2_1.err +++ b/result/relaxng/tutor3_2_1.err @@ -1,4 +1,4 @@ -error detected at relaxng.c:5099 +error detected at relaxng.c:5446 Expecting element name, got email -error detected at relaxng.c:5164 +error detected at relaxng.c:5511 Extra content for element card: email diff --git a/result/relaxng/tutor3_5_2.err b/result/relaxng/tutor3_5_2.err index 984a201e..eca41dd4 100644 --- a/result/relaxng/tutor3_5_2.err +++ b/result/relaxng/tutor3_5_2.err @@ -1,2 +1,2 @@ -error detected at relaxng.c:5164 +error detected at relaxng.c:5511 Extra content for element addressBook: card diff --git a/result/relaxng/tutor3_7_err b/result/relaxng/tutor3_7_err index c2aa66df..7d90f37e 100644 --- a/result/relaxng/tutor3_7_err +++ b/result/relaxng/tutor3_7_err @@ -1,2 +1,2 @@ -error detected at relaxng.c:5461 +error detected at relaxng.c:5812 extra data on the document diff --git a/result/relaxng/tutor5_3_1.err b/result/relaxng/tutor5_3_1.err index 07da5165..9b6ee153 100644 --- a/result/relaxng/tutor5_3_1.err +++ b/result/relaxng/tutor5_3_1.err @@ -1,2 +1,2 @@ -error detected at relaxng.c:5330 +error detected at relaxng.c:5677 The data does not cover the full element bad diff --git a/result/relaxng/tutor6_1_3.err b/result/relaxng/tutor6_1_3.err index 56a9a142..39e9f460 100644 --- a/result/relaxng/tutor6_1_3.err +++ b/result/relaxng/tutor6_1_3.err @@ -1,2 +1,2 @@ -error detected at relaxng.c:5177 +error detected at relaxng.c:5524 Invalid attribute preferredFormat for element card diff --git a/result/relaxng/tutor6_2_4.err b/result/relaxng/tutor6_2_4.err index b78fdf92..5565186c 100644 --- a/result/relaxng/tutor6_2_4.err +++ b/result/relaxng/tutor6_2_4.err @@ -1,2 +1,2 @@ -error detected at relaxng.c:5164 +error detected at relaxng.c:5511 Extra content for element preferredFormat: text diff --git a/result/relaxng/tutor6_3_1.err b/result/relaxng/tutor6_3_1.err index 56a9a142..39e9f460 100644 --- a/result/relaxng/tutor6_3_1.err +++ b/result/relaxng/tutor6_3_1.err @@ -1,2 +1,2 @@ -error detected at relaxng.c:5177 +error detected at relaxng.c:5524 Invalid attribute preferredFormat for element card diff --git a/result/relaxng/tutor7_1_2.err b/result/relaxng/tutor7_1_2.err index 2dfdcbab..ee868dd1 100644 --- a/result/relaxng/tutor7_1_2.err +++ b/result/relaxng/tutor7_1_2.err @@ -1,6 +1,6 @@ -error detected at relaxng.c:4217 +error detected at relaxng.c:4564 Internal: failed to validate type float -error detected at relaxng.c:5384 +error detected at relaxng.c:5735 internal error validating list -error detected at relaxng.c:5164 +error detected at relaxng.c:5511 Extra content for element vector: text diff --git a/result/relaxng/tutor7_1_3.err b/result/relaxng/tutor7_1_3.err index 727cb375..04e88b89 100644 --- a/result/relaxng/tutor7_1_3.err +++ b/result/relaxng/tutor7_1_3.err @@ -1,6 +1,6 @@ -error detected at relaxng.c:4406 +error detected at relaxng.c:4753 Extra data in list: 5.6 -error detected at relaxng.c:5384 +error detected at relaxng.c:5735 internal error validating list -error detected at relaxng.c:5164 +error detected at relaxng.c:5511 Extra content for element vector: text diff --git a/result/relaxng/tutor7_2_4.err b/result/relaxng/tutor7_2_4.err index 3ee93607..970ed5ec 100644 --- a/result/relaxng/tutor7_2_4.err +++ b/result/relaxng/tutor7_2_4.err @@ -1,4 +1,4 @@ -error detected at relaxng.c:4381 +error detected at relaxng.c:4728 Internal: no state -error detected at relaxng.c:5384 +error detected at relaxng.c:5735 internal error validating list diff --git a/result/relaxng/tutor7_3_4.err b/result/relaxng/tutor7_3_4.err index cb0fdf6a..d13709e3 100644 --- a/result/relaxng/tutor7_3_4.err +++ b/result/relaxng/tutor7_3_4.err @@ -1,6 +1,6 @@ -error detected at relaxng.c:4406 +error detected at relaxng.c:4753 Extra data in list: 5.6 -error detected at relaxng.c:5384 +error detected at relaxng.c:5735 internal error validating list -error detected at relaxng.c:5164 +error detected at relaxng.c:5511 Extra content for element path: text diff --git a/result/relaxng/tutor7_3_5.err b/result/relaxng/tutor7_3_5.err index 66dbf165..bbb092a3 100644 --- a/result/relaxng/tutor7_3_5.err +++ b/result/relaxng/tutor7_3_5.err @@ -1,6 +1,6 @@ -error detected at relaxng.c:4217 +error detected at relaxng.c:4564 Internal: failed to validate type double -error detected at relaxng.c:5384 +error detected at relaxng.c:5735 internal error validating list -error detected at relaxng.c:5164 +error detected at relaxng.c:5511 Extra content for element path: text diff --git a/result/relaxng/tutor8_2_4.err b/result/relaxng/tutor8_2_4.err index da513e4b..c0563aa4 100644 --- a/result/relaxng/tutor8_2_4.err +++ b/result/relaxng/tutor8_2_4.err @@ -1,4 +1,4 @@ -Unimplemented block at relaxng.c:4849 -Unimplemented block at relaxng.c:4849 -error detected at relaxng.c:5164 +Unimplemented block at relaxng.c:5196 +Unimplemented block at relaxng.c:5196 +error detected at relaxng.c:5511 Extra content for element head: meta diff --git a/result/relaxng/tutor8_2_5.err b/result/relaxng/tutor8_2_5.err index 53a5f29a..f25449a2 100644 --- a/result/relaxng/tutor8_2_5.err +++ b/result/relaxng/tutor8_2_5.err @@ -1,4 +1,4 @@ -error detected at relaxng.c:5080 +error detected at relaxng.c:5427 Expecting an element, got empty -error detected at relaxng.c:5164 +error detected at relaxng.c:5511 Extra content for element head: meta diff --git a/result/relaxng/tutor8_2_6.err b/result/relaxng/tutor8_2_6.err index 1f757c6c..ab812550 100644 --- a/result/relaxng/tutor8_2_6.err +++ b/result/relaxng/tutor8_2_6.err @@ -1,2 +1,2 @@ -error detected at relaxng.c:5164 +error detected at relaxng.c:5511 Extra content for element head: base diff --git a/result/relaxng/tutor9_5_2.err b/result/relaxng/tutor9_5_2.err index 984a201e..eca41dd4 100644 --- a/result/relaxng/tutor9_5_2.err +++ b/result/relaxng/tutor9_5_2.err @@ -1,2 +1,2 @@ -error detected at relaxng.c:5164 +error detected at relaxng.c:5511 Extra content for element addressBook: card diff --git a/result/relaxng/tutor9_5_3.err b/result/relaxng/tutor9_5_3.err index 984a201e..eca41dd4 100644 --- a/result/relaxng/tutor9_5_3.err +++ b/result/relaxng/tutor9_5_3.err @@ -1,2 +1,2 @@ -error detected at relaxng.c:5164 +error detected at relaxng.c:5511 Extra content for element addressBook: card diff --git a/result/relaxng/tutor9_6_2.err b/result/relaxng/tutor9_6_2.err index 984a201e..eca41dd4 100644 --- a/result/relaxng/tutor9_6_2.err +++ b/result/relaxng/tutor9_6_2.err @@ -1,2 +1,2 @@ -error detected at relaxng.c:5164 +error detected at relaxng.c:5511 Extra content for element addressBook: card diff --git a/result/relaxng/tutor9_6_3.err b/result/relaxng/tutor9_6_3.err index 984a201e..eca41dd4 100644 --- a/result/relaxng/tutor9_6_3.err +++ b/result/relaxng/tutor9_6_3.err @@ -1,2 +1,2 @@ -error detected at relaxng.c:5164 +error detected at relaxng.c:5511 Extra content for element addressBook: card diff --git a/tree.c b/tree.c index 4937d2ca..8bb06254 100644 --- a/tree.c +++ b/tree.c @@ -123,6 +123,246 @@ xmlGetParameterEntityFromDtd(xmlDtdPtr dtd, const xmlChar *name) { return(NULL); } +/************************************************************************ + * * + * Check Name, NCName and QName strings * + * * + ************************************************************************/ + +#define CUR_SCHAR(s, l) xmlStringCurrentChar(NULL, s, &l) + +/** + * xmlValidateNCName: + * @value: the value to check + * @space: allow spaces in front and end of the string + * + * Check that a value conforms to the lexical space of NCName + * + * Returns 0 if this validates, a positive error code number otherwise + * and -1 in case of internal or API error. + */ +int +xmlValidateNCName(const xmlChar *value, int space) { + const xmlChar *cur = value; + int c,l; + + /* + * First quick algorithm for ASCII range + */ + if (space) + while (IS_BLANK(*cur)) cur++; + if (((*cur >= 'a') && (*cur <= 'z')) || ((*cur >= 'A') && (*cur <= 'Z')) || + (*cur == '_')) + cur++; + else + goto try_complex; + while (((*cur >= 'a') && (*cur <= 'z')) || + ((*cur >= 'A') && (*cur <= 'Z')) || + ((*cur >= '0') && (*cur <= '9')) || + (*cur == '_') || (*cur == '-') || (*cur == '.')) + cur++; + if (space) + while (IS_BLANK(*cur)) cur++; + if (*cur == 0) + return(0); + +try_complex: + /* + * Second check for chars outside the ASCII range + */ + cur = value; + c = CUR_SCHAR(cur, l); + if (space) { + while (IS_BLANK(c)) { + cur += l; + c = CUR_SCHAR(cur, l); + } + } + if ((!xmlIsLetter(c)) && (c != '_')) + return(1); + cur += l; + c = CUR_SCHAR(cur, l); + while (xmlIsLetter(c) || xmlIsDigit(c) || (c == '.') || + (c == '-') || (c == '_') || xmlIsCombining(c) || + xmlIsExtender(c)) { + cur += l; + c = CUR_SCHAR(cur, l); + } + if (space) { + while (IS_BLANK(c)) { + cur += l; + c = CUR_SCHAR(cur, l); + } + } + if (c != 0) + return(1); + + return(0); +} + +/** + * xmlValidateQName: + * @value: the value to check + * @space: allow spaces in front and end of the string + * + * Check that a value conforms to the lexical space of QName + * + * Returns 0 if this validates, a positive error code number otherwise + * and -1 in case of internal or API error. + */ +int +xmlValidateQName(const xmlChar *value, int space) { + const xmlChar *cur = value; + int c,l; + + /* + * First quick algorithm for ASCII range + */ + if (space) + while (IS_BLANK(*cur)) cur++; + if (((*cur >= 'a') && (*cur <= 'z')) || ((*cur >= 'A') && (*cur <= 'Z')) || + (*cur == '_')) + cur++; + else + goto try_complex; + while (((*cur >= 'a') && (*cur <= 'z')) || + ((*cur >= 'A') && (*cur <= 'Z')) || + ((*cur >= '0') && (*cur <= '9')) || + (*cur == '_') || (*cur == '-') || (*cur == '.')) + cur++; + if (*cur == ':') { + cur++; + if (((*cur >= 'a') && (*cur <= 'z')) || + ((*cur >= 'A') && (*cur <= 'Z')) || + (*cur == '_')) + cur++; + else + goto try_complex; + while (((*cur >= 'a') && (*cur <= 'z')) || + ((*cur >= 'A') && (*cur <= 'Z')) || + ((*cur >= '0') && (*cur <= '9')) || + (*cur == '_') || (*cur == '-') || (*cur == '.')) + cur++; + } + if (space) + while (IS_BLANK(*cur)) cur++; + if (*cur == 0) + return(0); + +try_complex: + /* + * Second check for chars outside the ASCII range + */ + cur = value; + c = CUR_SCHAR(cur, l); + if (space) { + while (IS_BLANK(c)) { + cur += l; + c = CUR_SCHAR(cur, l); + } + } + if ((!xmlIsLetter(c)) && (c != '_')) + return(1); + cur += l; + c = CUR_SCHAR(cur, l); + while (xmlIsLetter(c) || xmlIsDigit(c) || (c == '.') || + (c == '-') || (c == '_') || xmlIsCombining(c) || + xmlIsExtender(c)) { + cur += l; + c = CUR_SCHAR(cur, l); + } + if (c == ':') { + cur += l; + c = CUR_SCHAR(cur, l); + if ((!xmlIsLetter(c)) && (c != '_')) + return(1); + cur += l; + c = CUR_SCHAR(cur, l); + while (xmlIsLetter(c) || xmlIsDigit(c) || (c == '.') || + (c == '-') || (c == '_') || xmlIsCombining(c) || + xmlIsExtender(c)) { + cur += l; + c = CUR_SCHAR(cur, l); + } + } + if (space) { + while (IS_BLANK(c)) { + cur += l; + c = CUR_SCHAR(cur, l); + } + } + if (c != 0) + return(1); + return(0); +} + +/** + * xmlValidateName: + * @value: the value to check + * @space: allow spaces in front and end of the string + * + * Check that a value conforms to the lexical space of Name + * + * Returns 0 if this validates, a positive error code number otherwise + * and -1 in case of internal or API error. + */ +int +xmlValidateName(const xmlChar *value, int space) { + const xmlChar *cur = value; + int c,l; + + /* + * First quick algorithm for ASCII range + */ + if (space) + while (IS_BLANK(*cur)) cur++; + if (((*cur >= 'a') && (*cur <= 'z')) || ((*cur >= 'A') && (*cur <= 'Z')) || + (*cur == '_') || (*cur == ':')) + cur++; + else + goto try_complex; + while (((*cur >= 'a') && (*cur <= 'z')) || + ((*cur >= 'A') && (*cur <= 'Z')) || + ((*cur >= '0') && (*cur <= '9')) || + (*cur == '_') || (*cur == '-') || (*cur == '.') || (*cur == ':')) + cur++; + if (space) + while (IS_BLANK(*cur)) cur++; + if (*cur == 0) + return(0); + +try_complex: + /* + * Second check for chars outside the ASCII range + */ + cur = value; + c = CUR_SCHAR(cur, l); + if (space) { + while (IS_BLANK(c)) { + cur += l; + c = CUR_SCHAR(cur, l); + } + } + if ((!xmlIsLetter(c)) && (c != '_') && (c != ':')) + return(1); + cur += l; + c = CUR_SCHAR(cur, l); + while (xmlIsLetter(c) || xmlIsDigit(c) || (c == '.') || (c == ':') || + (c == '-') || (c == '_') || xmlIsCombining(c) || xmlIsExtender(c)) { + cur += l; + c = CUR_SCHAR(cur, l); + } + if (space) { + while (IS_BLANK(c)) { + cur += l; + c = CUR_SCHAR(cur, l); + } + } + if (c != 0) + return(1); + return(0); +} + /************************************************************************ * * * Allocation and deallocation of basic structures * diff --git a/uri.c b/uri.c index 3ad9f57a..c3fa5e74 100644 --- a/uri.c +++ b/uri.c @@ -803,7 +803,7 @@ xmlURIUnescapeString(const char *str, int len, char *target) { if (str == NULL) return(NULL); if (len <= 0) len = strlen(str); - if (len <= 0) return(NULL); + if (len < 0) return(NULL); if (target == NULL) { ret = (char *) xmlMalloc(len + 1); diff --git a/xmlschemastypes.c b/xmlschemastypes.c index 89d30dbf..374eddbb 100644 --- a/xmlschemastypes.c +++ b/xmlschemastypes.c @@ -975,136 +975,6 @@ error: } -/** - * xmlSchemaValidateNCName: - * @value: the value to check - * - * Check that a value conforms to the lexical space of NCName - * - * Returns 0 if this validates, a positive error code number otherwise - * and -1 in case of internal or API error. - */ -static int -xmlSchemaValidateNCName(const xmlChar *value) { - const xmlChar *cur = value; - - /* - * First quick algorithm for ASCII range - */ - while (IS_BLANK(*cur)) cur++; - if (((*cur >= 'a') && (*cur <= 'z')) || ((*cur >= 'A') && (*cur <= 'Z')) || - (*cur == '_')) - cur++; - else - goto try_complex; - while (((*cur >= 'a') && (*cur <= 'z')) || - ((*cur >= 'A') && (*cur <= 'Z')) || - ((*cur >= '0') && (*cur <= '9')) || - (*cur == '_') || (*cur == '-') || (*cur == '.')) - cur++; - while (IS_BLANK(*cur)) cur++; - if (*cur == 0) - return(0); - -try_complex: - /* - * Second check for chars outside the ASCII range - */ - TODO - return(0); -} - -/** - * xmlSchemaValidateQName: - * @value: the value to check - * - * Check that a value conforms to the lexical space of QName - * - * Returns 0 if this validates, a positive error code number otherwise - * and -1 in case of internal or API error. - */ -static int -xmlSchemaValidateQName(const xmlChar *value) { - const xmlChar *cur = value; - - /* - * First quick algorithm for ASCII range - */ - while (IS_BLANK(*cur)) cur++; - if (((*cur >= 'a') && (*cur <= 'z')) || ((*cur >= 'A') && (*cur <= 'Z')) || - (*cur == '_')) - cur++; - else - goto try_complex; - while (((*cur >= 'a') && (*cur <= 'z')) || - ((*cur >= 'A') && (*cur <= 'Z')) || - ((*cur >= '0') && (*cur <= '9')) || - (*cur == '_') || (*cur == '-') || (*cur == '.')) - cur++; - if (*cur == ':') { - cur++; - if (((*cur >= 'a') && (*cur <= 'z')) || - ((*cur >= 'A') && (*cur <= 'Z')) || - (*cur == '_')) - cur++; - else - goto try_complex; - while (((*cur >= 'a') && (*cur <= 'z')) || - ((*cur >= 'A') && (*cur <= 'Z')) || - ((*cur >= '0') && (*cur <= '9')) || - (*cur == '_') || (*cur == '-') || (*cur == '.')) - cur++; - } - while (IS_BLANK(*cur)) cur++; - if (*cur == 0) - return(0); - -try_complex: - /* - * Second check for chars outside the ASCII range - */ - TODO - return(0); -} - -/** - * xmlSchemaValidateName: - * @value: the value to check - * - * Check that a value conforms to the lexical space of Name - * - * Returns 0 if this validates, a positive error code number otherwise - * and -1 in case of internal or API error. - */ -static int -xmlSchemaValidateName(const xmlChar *value) { - const xmlChar *cur = value; - - /* - * First quick algorithm for ASCII range - */ - while (IS_BLANK(*cur)) cur++; - if (((*cur >= 'a') && (*cur <= 'z')) || ((*cur >= 'A') && (*cur <= 'Z')) || - (*cur == '_') || (*cur == ':')) - cur++; - else - goto try_complex; - while (((*cur >= 'a') && (*cur <= 'z')) || - ((*cur >= 'A') && (*cur <= 'Z')) || - ((*cur >= '0') && (*cur <= '9')) || - (*cur == '_') || (*cur == '-') || (*cur == '.') || (*cur == ':')) - cur++; - while (IS_BLANK(*cur)) cur++; - if (*cur == 0) - return(0); - -try_complex: - /* - * Second check for chars outside the ASCII range - */ - TODO - return(0); -} /** * xmlSchemaValidatePredefinedType: * @type: the predefined type @@ -1405,19 +1275,19 @@ xmlSchemaValidatePredefinedType(xmlSchemaTypePtr type, const xmlChar *value, } return(0); } else if (type == xmlSchemaTypeNameDef) { - ret = xmlSchemaValidateName(value); + ret = xmlValidateName(value, 1); if ((ret == 0) && (val != NULL)) { TODO; } return(ret); } else if (type == xmlSchemaTypeQNameDef) { - ret = xmlSchemaValidateQName(value); + ret = xmlValidateQName(value, 1); if ((ret == 0) && (val != NULL)) { TODO; } return(ret); } else if (type == xmlSchemaTypeNCNameDef) { - ret = xmlSchemaValidateNCName(value); + ret = xmlValidateNCName(value, 1); if ((ret == 0) && (val != NULL)) { TODO; }