| OLD | NEW |
| 1 /* | 1 /* |
| 2 * valid.c : part of the code use to do the DTD handling and the validity | 2 * valid.c : part of the code use to do the DTD handling and the validity |
| 3 * checking | 3 * checking |
| 4 * | 4 * |
| 5 * See Copyright for the status of this software. | 5 * See Copyright for the status of this software. |
| 6 * | 6 * |
| 7 * daniel@veillard.com | 7 * daniel@veillard.com |
| 8 */ | 8 */ |
| 9 | 9 |
| 10 #define IN_LIBXML | 10 #define IN_LIBXML |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 static xmlElementPtr xmlGetDtdElementDesc2(xmlDtdPtr dtd, const xmlChar *name, | 29 static xmlElementPtr xmlGetDtdElementDesc2(xmlDtdPtr dtd, const xmlChar *name, |
| 30 int create); | 30 int create); |
| 31 /* #define DEBUG_VALID_ALGO */ | 31 /* #define DEBUG_VALID_ALGO */ |
| 32 /* #define DEBUG_REGEXP_ALGO */ | 32 /* #define DEBUG_REGEXP_ALGO */ |
| 33 | 33 |
| 34 #define TODO \ | 34 #define TODO \ |
| 35 xmlGenericError(xmlGenericErrorContext, \ | 35 xmlGenericError(xmlGenericErrorContext, \ |
| 36 "Unimplemented block at %s:%d\n", \ | 36 "Unimplemented block at %s:%d\n", \ |
| 37 __FILE__, __LINE__); | 37 __FILE__, __LINE__); |
| 38 | 38 |
| 39 #ifdef LIBXML_VALID_ENABLED |
| 40 static int |
| 41 xmlValidateAttributeValueInternal(xmlDocPtr doc, xmlAttributeType type, |
| 42 const xmlChar *value); |
| 43 #endif |
| 39 /************************************************************************ | 44 /************************************************************************ |
| 40 * * | 45 * * |
| 41 * Error handling routines * | 46 * Error handling routines * |
| 42 * * | 47 * * |
| 43 ************************************************************************/ | 48 ************************************************************************/ |
| 44 | 49 |
| 45 /** | 50 /** |
| 46 * xmlVErrMemory: | 51 * xmlVErrMemory: |
| 47 * @ctxt: an XML validation parser context | 52 * @ctxt: an XML validation parser context |
| 48 * @extra: extra informations | 53 * @extra: extra informations |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 110 } | 115 } |
| 111 if (extra) | 116 if (extra) |
| 112 __xmlRaiseError(NULL, channel, data, | 117 __xmlRaiseError(NULL, channel, data, |
| 113 pctxt, NULL, XML_FROM_VALID, error, | 118 pctxt, NULL, XML_FROM_VALID, error, |
| 114 XML_ERR_ERROR, NULL, 0, extra, NULL, NULL, 0, 0, | 119 XML_ERR_ERROR, NULL, 0, extra, NULL, NULL, 0, 0, |
| 115 msg, extra); | 120 msg, extra); |
| 116 else | 121 else |
| 117 __xmlRaiseError(NULL, channel, data, | 122 __xmlRaiseError(NULL, channel, data, |
| 118 pctxt, NULL, XML_FROM_VALID, error, | 123 pctxt, NULL, XML_FROM_VALID, error, |
| 119 XML_ERR_ERROR, NULL, 0, NULL, NULL, NULL, 0, 0, | 124 XML_ERR_ERROR, NULL, 0, NULL, NULL, NULL, 0, 0, |
| 120 msg); | 125 "%s", msg); |
| 121 } | 126 } |
| 122 | 127 |
| 123 #if defined(LIBXML_VALID_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) | 128 #if defined(LIBXML_VALID_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) |
| 124 /** | 129 /** |
| 125 * xmlErrValidNode: | 130 * xmlErrValidNode: |
| 126 * @ctxt: an XML validation parser context | 131 * @ctxt: an XML validation parser context |
| 127 * @node: the node raising the error | 132 * @node: the node raising the error |
| 128 * @error: the error number | 133 * @error: the error number |
| 129 * @str1: extra informations | 134 * @str1: extra informations |
| 130 * @str2: extra informations | 135 * @str2: extra informations |
| (...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 625 #endif | 630 #endif |
| 626 | 631 |
| 627 /* TODO: use hash table for accesses to elem and attribute definitions */ | 632 /* TODO: use hash table for accesses to elem and attribute definitions */ |
| 628 | 633 |
| 629 | 634 |
| 630 #define CHECK_DTD \ | 635 #define CHECK_DTD \ |
| 631 if (doc == NULL) return(0); \ | 636 if (doc == NULL) return(0); \ |
| 632 else if ((doc->intSubset == NULL) && \ | 637 else if ((doc->intSubset == NULL) && \ |
| 633 (doc->extSubset == NULL)) return(0) | 638 (doc->extSubset == NULL)) return(0) |
| 634 | 639 |
| 635 xmlAttributePtr xmlScanAttributeDecl(xmlDtdPtr dtd, const xmlChar *elem); | |
| 636 | |
| 637 #ifdef LIBXML_REGEXP_ENABLED | 640 #ifdef LIBXML_REGEXP_ENABLED |
| 638 | 641 |
| 639 /************************************************************************ | 642 /************************************************************************ |
| 640 * * | 643 * * |
| 641 * Content model validation based on the regexps * | 644 * Content model validation based on the regexps * |
| 642 * * | 645 * * |
| 643 ************************************************************************/ | 646 ************************************************************************/ |
| 644 | 647 |
| 645 /** | 648 /** |
| 646 * xmlValidBuildAContentModel: | 649 * xmlValidBuildAContentModel: |
| (...skipping 1174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1821 xmlBufferWriteChar(buf, ")"); | 1824 xmlBufferWriteChar(buf, ")"); |
| 1822 else { | 1825 else { |
| 1823 xmlBufferWriteChar(buf, " | "); | 1826 xmlBufferWriteChar(buf, " | "); |
| 1824 xmlDumpEnumeration(buf, cur->next); | 1827 xmlDumpEnumeration(buf, cur->next); |
| 1825 } | 1828 } |
| 1826 } | 1829 } |
| 1827 #endif /* LIBXML_OUTPUT_ENABLED */ | 1830 #endif /* LIBXML_OUTPUT_ENABLED */ |
| 1828 | 1831 |
| 1829 #ifdef LIBXML_VALID_ENABLED | 1832 #ifdef LIBXML_VALID_ENABLED |
| 1830 /** | 1833 /** |
| 1831 * xmlScanAttributeDeclCallback: | |
| 1832 * @attr: the attribute decl | |
| 1833 * @list: the list to update | |
| 1834 * | |
| 1835 * Callback called by xmlScanAttributeDecl when a new attribute | |
| 1836 * has to be entered in the list. | |
| 1837 */ | |
| 1838 static void | |
| 1839 xmlScanAttributeDeclCallback(xmlAttributePtr attr, xmlAttributePtr *list, | |
| 1840 const xmlChar* name ATTRIBUTE_UNUSED) { | |
| 1841 attr->nexth = *list; | |
| 1842 *list = attr; | |
| 1843 } | |
| 1844 | |
| 1845 /** | |
| 1846 * xmlScanAttributeDecl: | |
| 1847 * @dtd: pointer to the DTD | |
| 1848 * @elem: the element name | |
| 1849 * | |
| 1850 * When inserting a new element scan the DtD for existing attributes | |
| 1851 * for that element and initialize the Attribute chain | |
| 1852 * | |
| 1853 * Returns the pointer to the first attribute decl in the chain, | |
| 1854 * possibly NULL. | |
| 1855 */ | |
| 1856 xmlAttributePtr | |
| 1857 xmlScanAttributeDecl(xmlDtdPtr dtd, const xmlChar *elem) { | |
| 1858 xmlAttributePtr ret = NULL; | |
| 1859 xmlAttributeTablePtr table; | |
| 1860 | |
| 1861 if (dtd == NULL) { | |
| 1862 return(NULL); | |
| 1863 } | |
| 1864 if (elem == NULL) { | |
| 1865 return(NULL); | |
| 1866 } | |
| 1867 table = (xmlAttributeTablePtr) dtd->attributes; | |
| 1868 if (table == NULL) | |
| 1869 return(NULL); | |
| 1870 | |
| 1871 /* WRONG !!! */ | |
| 1872 xmlHashScan3(table, NULL, NULL, elem, | |
| 1873 (xmlHashScanner) xmlScanAttributeDeclCallback, &ret); | |
| 1874 return(ret); | |
| 1875 } | |
| 1876 | |
| 1877 /** | |
| 1878 * xmlScanIDAttributeDecl: | 1834 * xmlScanIDAttributeDecl: |
| 1879 * @ctxt: the validation context | 1835 * @ctxt: the validation context |
| 1880 * @elem: the element name | 1836 * @elem: the element name |
| 1881 * @err: whether to raise errors here | 1837 * @err: whether to raise errors here |
| 1882 * | 1838 * |
| 1883 * Verify that the element don't have too many ID attributes | 1839 * Verify that the element don't have too many ID attributes |
| 1884 * declared. | 1840 * declared. |
| 1885 * | 1841 * |
| 1886 * Returns the number of ID attributes found. | 1842 * Returns the number of ID attributes found. |
| 1887 */ | 1843 */ |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2017 case XML_ATTRIBUTE_NOTATION: | 1973 case XML_ATTRIBUTE_NOTATION: |
| 2018 break; | 1974 break; |
| 2019 default: | 1975 default: |
| 2020 xmlErrValid(ctxt, XML_ERR_INTERNAL_ERROR, | 1976 xmlErrValid(ctxt, XML_ERR_INTERNAL_ERROR, |
| 2021 "Internal: ATTRIBUTE struct corrupted invalid type\n", | 1977 "Internal: ATTRIBUTE struct corrupted invalid type\n", |
| 2022 NULL); | 1978 NULL); |
| 2023 xmlFreeEnumeration(tree); | 1979 xmlFreeEnumeration(tree); |
| 2024 return(NULL); | 1980 return(NULL); |
| 2025 } | 1981 } |
| 2026 if ((defaultValue != NULL) && | 1982 if ((defaultValue != NULL) && |
| 2027 (!xmlValidateAttributeValue(type, defaultValue))) { | 1983 (!xmlValidateAttributeValueInternal(dtd->doc, type, defaultValue))) { |
| 2028 xmlErrValidNode(ctxt, (xmlNodePtr) dtd, XML_DTD_ATTRIBUTE_DEFAULT, | 1984 xmlErrValidNode(ctxt, (xmlNodePtr) dtd, XML_DTD_ATTRIBUTE_DEFAULT, |
| 2029 "Attribute %s of %s: invalid default value\n", | 1985 "Attribute %s of %s: invalid default value\n", |
| 2030 elem, name, defaultValue); | 1986 elem, name, defaultValue); |
| 2031 defaultValue = NULL; | 1987 defaultValue = NULL; |
| 2032 if (ctxt != NULL) | 1988 if (ctxt != NULL) |
| 2033 ctxt->valid = 0; | 1989 ctxt->valid = 0; |
| 2034 } | 1990 } |
| 2035 #endif /* LIBXML_VALID_ENABLED */ | 1991 #endif /* LIBXML_VALID_ENABLED */ |
| 2036 | 1992 |
| 2037 /* | 1993 /* |
| 2038 * Check first that an attribute defined in the external subset wasn't | 1994 * Check first that an attribute defined in the external subset wasn't |
| 2039 * already defined in the internal subset | 1995 * already defined in the internal subset |
| 2040 */ | 1996 */ |
| 2041 if ((dtd->doc != NULL) && (dtd->doc->extSubset == dtd) && | 1997 if ((dtd->doc != NULL) && (dtd->doc->extSubset == dtd) && |
| 2042 (dtd->doc->intSubset != NULL) && | 1998 (dtd->doc->intSubset != NULL) && |
| 2043 (dtd->doc->intSubset->attributes != NULL)) { | 1999 (dtd->doc->intSubset->attributes != NULL)) { |
| 2044 ret = xmlHashLookup3(dtd->doc->intSubset->attributes, name, ns, elem); | 2000 ret = xmlHashLookup3(dtd->doc->intSubset->attributes, name, ns, elem); |
| 2045 » if (ret != NULL) | 2001 » if (ret != NULL) { |
| 2002 » xmlFreeEnumeration(tree); |
| 2046 return(NULL); | 2003 return(NULL); |
| 2004 } |
| 2047 } | 2005 } |
| 2048 | 2006 |
| 2049 /* | 2007 /* |
| 2050 * Create the Attribute table if needed. | 2008 * Create the Attribute table if needed. |
| 2051 */ | 2009 */ |
| 2052 table = (xmlAttributeTablePtr) dtd->attributes; | 2010 table = (xmlAttributeTablePtr) dtd->attributes; |
| 2053 if (table == NULL) { | 2011 if (table == NULL) { |
| 2054 table = xmlHashCreateDict(0, dict); | 2012 table = xmlHashCreateDict(0, dict); |
| 2055 dtd->attributes = (void *) table; | 2013 dtd->attributes = (void *) table; |
| 2056 } | 2014 } |
| 2057 if (table == NULL) { | 2015 if (table == NULL) { |
| 2058 xmlVErrMemory(ctxt, | 2016 xmlVErrMemory(ctxt, |
| 2059 "xmlAddAttributeDecl: Table creation failed!\n"); | 2017 "xmlAddAttributeDecl: Table creation failed!\n"); |
| 2018 xmlFreeEnumeration(tree); |
| 2060 return(NULL); | 2019 return(NULL); |
| 2061 } | 2020 } |
| 2062 | 2021 |
| 2063 | 2022 |
| 2064 ret = (xmlAttributePtr) xmlMalloc(sizeof(xmlAttribute)); | 2023 ret = (xmlAttributePtr) xmlMalloc(sizeof(xmlAttribute)); |
| 2065 if (ret == NULL) { | 2024 if (ret == NULL) { |
| 2066 xmlVErrMemory(ctxt, "malloc failed"); | 2025 xmlVErrMemory(ctxt, "malloc failed"); |
| 2026 xmlFreeEnumeration(tree); |
| 2067 return(NULL); | 2027 return(NULL); |
| 2068 } | 2028 } |
| 2069 memset(ret, 0, sizeof(xmlAttribute)); | 2029 memset(ret, 0, sizeof(xmlAttribute)); |
| 2070 ret->type = XML_ATTRIBUTE_DECL; | 2030 ret->type = XML_ATTRIBUTE_DECL; |
| 2071 | 2031 |
| 2072 /* | 2032 /* |
| 2073 * fill the structure. | 2033 * fill the structure. |
| 2074 */ | 2034 */ |
| 2075 ret->atype = type; | 2035 ret->atype = type; |
| 2076 /* | 2036 /* |
| (...skipping 635 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2712 * Returns 0 or 1 depending on the lookup result | 2672 * Returns 0 or 1 depending on the lookup result |
| 2713 */ | 2673 */ |
| 2714 int | 2674 int |
| 2715 xmlIsID(xmlDocPtr doc, xmlNodePtr elem, xmlAttrPtr attr) { | 2675 xmlIsID(xmlDocPtr doc, xmlNodePtr elem, xmlAttrPtr attr) { |
| 2716 if ((attr == NULL) || (attr->name == NULL)) return(0); | 2676 if ((attr == NULL) || (attr->name == NULL)) return(0); |
| 2717 if ((attr->ns != NULL) && (attr->ns->prefix != NULL) && | 2677 if ((attr->ns != NULL) && (attr->ns->prefix != NULL) && |
| 2718 (!strcmp((char *) attr->name, "id")) && | 2678 (!strcmp((char *) attr->name, "id")) && |
| 2719 (!strcmp((char *) attr->ns->prefix, "xml"))) | 2679 (!strcmp((char *) attr->ns->prefix, "xml"))) |
| 2720 return(1); | 2680 return(1); |
| 2721 if (doc == NULL) return(0); | 2681 if (doc == NULL) return(0); |
| 2722 if ((doc->intSubset == NULL) && (doc->extSubset == NULL)) { | 2682 if ((doc->intSubset == NULL) && (doc->extSubset == NULL) && |
| 2683 (doc->type != XML_HTML_DOCUMENT_NODE)) { |
| 2723 return(0); | 2684 return(0); |
| 2724 } else if (doc->type == XML_HTML_DOCUMENT_NODE) { | 2685 } else if (doc->type == XML_HTML_DOCUMENT_NODE) { |
| 2725 if ((xmlStrEqual(BAD_CAST "id", attr->name)) || | 2686 if ((xmlStrEqual(BAD_CAST "id", attr->name)) || |
| 2726 ((xmlStrEqual(BAD_CAST "name", attr->name)) && | 2687 ((xmlStrEqual(BAD_CAST "name", attr->name)) && |
| 2727 ((elem == NULL) || (xmlStrEqual(elem->name, BAD_CAST "a"))))) | 2688 ((elem == NULL) || (xmlStrEqual(elem->name, BAD_CAST "a"))))) |
| 2728 return(1); | 2689 return(1); |
| 2729 return(0); | 2690 return(0); |
| 2730 } else if (elem == NULL) { | 2691 } else if (elem == NULL) { |
| 2731 return(0); | 2692 return(0); |
| 2732 } else { | 2693 } else { |
| (...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3383 * Validate that the given name match a notation declaration. | 3344 * Validate that the given name match a notation declaration. |
| 3384 * - [ VC: Notation Declared ] | 3345 * - [ VC: Notation Declared ] |
| 3385 * | 3346 * |
| 3386 * returns 1 if valid or 0 otherwise | 3347 * returns 1 if valid or 0 otherwise |
| 3387 */ | 3348 */ |
| 3388 | 3349 |
| 3389 int | 3350 int |
| 3390 xmlValidateNotationUse(xmlValidCtxtPtr ctxt, xmlDocPtr doc, | 3351 xmlValidateNotationUse(xmlValidCtxtPtr ctxt, xmlDocPtr doc, |
| 3391 const xmlChar *notationName) { | 3352 const xmlChar *notationName) { |
| 3392 xmlNotationPtr notaDecl; | 3353 xmlNotationPtr notaDecl; |
| 3393 if ((doc == NULL) || (doc->intSubset == NULL)) return(-1); | 3354 if ((doc == NULL) || (doc->intSubset == NULL) || |
| 3355 (notationName == NULL)) return(-1); |
| 3394 | 3356 |
| 3395 notaDecl = xmlGetDtdNotationDesc(doc->intSubset, notationName); | 3357 notaDecl = xmlGetDtdNotationDesc(doc->intSubset, notationName); |
| 3396 if ((notaDecl == NULL) && (doc->extSubset != NULL)) | 3358 if ((notaDecl == NULL) && (doc->extSubset != NULL)) |
| 3397 notaDecl = xmlGetDtdNotationDesc(doc->extSubset, notationName); | 3359 notaDecl = xmlGetDtdNotationDesc(doc->extSubset, notationName); |
| 3398 | 3360 |
| 3399 if ((notaDecl == NULL) && (ctxt != NULL)) { | 3361 if ((notaDecl == NULL) && (ctxt != NULL)) { |
| 3400 xmlErrValidNode(ctxt, (xmlNodePtr) doc, XML_DTD_UNKNOWN_NOTATION, | 3362 xmlErrValidNode(ctxt, (xmlNodePtr) doc, XML_DTD_UNKNOWN_NOTATION, |
| 3401 "NOTATION %s is not declared\n", | 3363 "NOTATION %s is not declared\n", |
| 3402 notationName, NULL, NULL); | 3364 notationName, NULL, NULL); |
| 3403 return(0); | 3365 return(0); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3438 * on <empty> </empty> for example | 3400 * on <empty> </empty> for example |
| 3439 */ | 3401 */ |
| 3440 case XML_ELEMENT_TYPE_ANY: | 3402 case XML_ELEMENT_TYPE_ANY: |
| 3441 case XML_ELEMENT_TYPE_MIXED: | 3403 case XML_ELEMENT_TYPE_MIXED: |
| 3442 return(1); | 3404 return(1); |
| 3443 } | 3405 } |
| 3444 return(1); | 3406 return(1); |
| 3445 } | 3407 } |
| 3446 | 3408 |
| 3447 #ifdef LIBXML_VALID_ENABLED | 3409 #ifdef LIBXML_VALID_ENABLED |
| 3410 |
| 3411 static int |
| 3412 xmlIsDocNameStartChar(xmlDocPtr doc, int c) { |
| 3413 if ((doc == NULL) || (doc->properties & XML_DOC_OLD10) == 0) { |
| 3414 /* |
| 3415 * Use the new checks of production [4] [4a] amd [5] of the |
| 3416 * Update 5 of XML-1.0 |
| 3417 */ |
| 3418 if (((c >= 'a') && (c <= 'z')) || |
| 3419 ((c >= 'A') && (c <= 'Z')) || |
| 3420 (c == '_') || (c == ':') || |
| 3421 ((c >= 0xC0) && (c <= 0xD6)) || |
| 3422 ((c >= 0xD8) && (c <= 0xF6)) || |
| 3423 ((c >= 0xF8) && (c <= 0x2FF)) || |
| 3424 ((c >= 0x370) && (c <= 0x37D)) || |
| 3425 ((c >= 0x37F) && (c <= 0x1FFF)) || |
| 3426 ((c >= 0x200C) && (c <= 0x200D)) || |
| 3427 ((c >= 0x2070) && (c <= 0x218F)) || |
| 3428 ((c >= 0x2C00) && (c <= 0x2FEF)) || |
| 3429 ((c >= 0x3001) && (c <= 0xD7FF)) || |
| 3430 ((c >= 0xF900) && (c <= 0xFDCF)) || |
| 3431 ((c >= 0xFDF0) && (c <= 0xFFFD)) || |
| 3432 ((c >= 0x10000) && (c <= 0xEFFFF))) |
| 3433 return(1); |
| 3434 } else { |
| 3435 if (IS_LETTER(c) || (c == '_') || (c == ':')) |
| 3436 return(1); |
| 3437 } |
| 3438 return(0); |
| 3439 } |
| 3440 |
| 3441 static int |
| 3442 xmlIsDocNameChar(xmlDocPtr doc, int c) { |
| 3443 if ((doc == NULL) || (doc->properties & XML_DOC_OLD10) == 0) { |
| 3444 /* |
| 3445 * Use the new checks of production [4] [4a] amd [5] of the |
| 3446 * Update 5 of XML-1.0 |
| 3447 */ |
| 3448 if (((c >= 'a') && (c <= 'z')) || |
| 3449 ((c >= 'A') && (c <= 'Z')) || |
| 3450 ((c >= '0') && (c <= '9')) || /* !start */ |
| 3451 (c == '_') || (c == ':') || |
| 3452 (c == '-') || (c == '.') || (c == 0xB7) || /* !start */ |
| 3453 ((c >= 0xC0) && (c <= 0xD6)) || |
| 3454 ((c >= 0xD8) && (c <= 0xF6)) || |
| 3455 ((c >= 0xF8) && (c <= 0x2FF)) || |
| 3456 ((c >= 0x300) && (c <= 0x36F)) || /* !start */ |
| 3457 ((c >= 0x370) && (c <= 0x37D)) || |
| 3458 ((c >= 0x37F) && (c <= 0x1FFF)) || |
| 3459 ((c >= 0x200C) && (c <= 0x200D)) || |
| 3460 ((c >= 0x203F) && (c <= 0x2040)) || /* !start */ |
| 3461 ((c >= 0x2070) && (c <= 0x218F)) || |
| 3462 ((c >= 0x2C00) && (c <= 0x2FEF)) || |
| 3463 ((c >= 0x3001) && (c <= 0xD7FF)) || |
| 3464 ((c >= 0xF900) && (c <= 0xFDCF)) || |
| 3465 ((c >= 0xFDF0) && (c <= 0xFFFD)) || |
| 3466 ((c >= 0x10000) && (c <= 0xEFFFF))) |
| 3467 return(1); |
| 3468 } else { |
| 3469 if ((IS_LETTER(c)) || (IS_DIGIT(c)) || |
| 3470 (c == '.') || (c == '-') || |
| 3471 (c == '_') || (c == ':') || |
| 3472 (IS_COMBINING(c)) || |
| 3473 (IS_EXTENDER(c))) |
| 3474 return(1); |
| 3475 } |
| 3476 return(0); |
| 3477 } |
| 3478 |
| 3448 /** | 3479 /** |
| 3449 * xmlValidateNameValue: | 3480 * xmlValidateNameValue: |
| 3481 * @doc: pointer to the document or NULL |
| 3450 * @value: an Name value | 3482 * @value: an Name value |
| 3451 * | 3483 * |
| 3452 * Validate that the given value match Name production | 3484 * Validate that the given value match Name production |
| 3453 * | 3485 * |
| 3454 * returns 1 if valid or 0 otherwise | 3486 * returns 1 if valid or 0 otherwise |
| 3455 */ | 3487 */ |
| 3456 | 3488 |
| 3457 int | 3489 static int |
| 3458 xmlValidateNameValue(const xmlChar *value) { | 3490 xmlValidateNameValueInternal(xmlDocPtr doc, const xmlChar *value) { |
| 3459 const xmlChar *cur; | 3491 const xmlChar *cur; |
| 3460 int val, len; | 3492 int val, len; |
| 3461 | 3493 |
| 3462 if (value == NULL) return(0); | 3494 if (value == NULL) return(0); |
| 3463 cur = value; | 3495 cur = value; |
| 3464 val = xmlStringCurrentChar(NULL, cur, &len); | 3496 val = xmlStringCurrentChar(NULL, cur, &len); |
| 3465 cur += len; | 3497 cur += len; |
| 3466 if (!IS_LETTER(val) && (val != '_') && | 3498 if (!xmlIsDocNameStartChar(doc, val)) |
| 3467 (val != ':')) { | |
| 3468 return(0); | 3499 return(0); |
| 3469 } | |
| 3470 | 3500 |
| 3471 val = xmlStringCurrentChar(NULL, cur, &len); | 3501 val = xmlStringCurrentChar(NULL, cur, &len); |
| 3472 cur += len; | 3502 cur += len; |
| 3473 while ((IS_LETTER(val)) || (IS_DIGIT(val)) || | 3503 while (xmlIsDocNameChar(doc, val)) { |
| 3474 (val == '.') || (val == '-') || | |
| 3475 » (val == '_') || (val == ':') || | |
| 3476 » (IS_COMBINING(val)) || | |
| 3477 » (IS_EXTENDER(val))) { | |
| 3478 val = xmlStringCurrentChar(NULL, cur, &len); | 3504 val = xmlStringCurrentChar(NULL, cur, &len); |
| 3479 cur += len; | 3505 cur += len; |
| 3480 } | 3506 } |
| 3481 | 3507 |
| 3482 if (val != 0) return(0); | 3508 if (val != 0) return(0); |
| 3483 | 3509 |
| 3484 return(1); | 3510 return(1); |
| 3485 } | 3511 } |
| 3486 | 3512 |
| 3487 /** | 3513 /** |
| 3488 * xmlValidateNamesValue: | 3514 * xmlValidateNameValue: |
| 3515 * @value: an Name value |
| 3516 * |
| 3517 * Validate that the given value match Name production |
| 3518 * |
| 3519 * returns 1 if valid or 0 otherwise |
| 3520 */ |
| 3521 |
| 3522 int |
| 3523 xmlValidateNameValue(const xmlChar *value) { |
| 3524 return(xmlValidateNameValueInternal(NULL, value)); |
| 3525 } |
| 3526 |
| 3527 /** |
| 3528 * xmlValidateNamesValueInternal: |
| 3529 * @doc: pointer to the document or NULL |
| 3489 * @value: an Names value | 3530 * @value: an Names value |
| 3490 * | 3531 * |
| 3491 * Validate that the given value match Names production | 3532 * Validate that the given value match Names production |
| 3492 * | 3533 * |
| 3493 * returns 1 if valid or 0 otherwise | 3534 * returns 1 if valid or 0 otherwise |
| 3494 */ | 3535 */ |
| 3495 | 3536 |
| 3496 int | 3537 static int |
| 3497 xmlValidateNamesValue(const xmlChar *value) { | 3538 xmlValidateNamesValueInternal(xmlDocPtr doc, const xmlChar *value) { |
| 3498 const xmlChar *cur; | 3539 const xmlChar *cur; |
| 3499 int val, len; | 3540 int val, len; |
| 3500 | 3541 |
| 3501 if (value == NULL) return(0); | 3542 if (value == NULL) return(0); |
| 3502 cur = value; | 3543 cur = value; |
| 3503 val = xmlStringCurrentChar(NULL, cur, &len); | 3544 val = xmlStringCurrentChar(NULL, cur, &len); |
| 3504 cur += len; | 3545 cur += len; |
| 3505 | 3546 |
| 3506 if (!IS_LETTER(val) && (val != '_') && | 3547 if (!xmlIsDocNameStartChar(doc, val)) |
| 3507 (val != ':')) { | |
| 3508 return(0); | 3548 return(0); |
| 3509 } | |
| 3510 | 3549 |
| 3511 val = xmlStringCurrentChar(NULL, cur, &len); | 3550 val = xmlStringCurrentChar(NULL, cur, &len); |
| 3512 cur += len; | 3551 cur += len; |
| 3513 while ((IS_LETTER(val)) || (IS_DIGIT(val)) || | 3552 while (xmlIsDocNameChar(doc, val)) { |
| 3514 (val == '.') || (val == '-') || | |
| 3515 » (val == '_') || (val == ':') || | |
| 3516 » (IS_COMBINING(val)) || | |
| 3517 » (IS_EXTENDER(val))) { | |
| 3518 val = xmlStringCurrentChar(NULL, cur, &len); | 3553 val = xmlStringCurrentChar(NULL, cur, &len); |
| 3519 cur += len; | 3554 cur += len; |
| 3520 } | 3555 } |
| 3521 | 3556 |
| 3522 /* Should not test IS_BLANK(val) here -- see erratum E20*/ | 3557 /* Should not test IS_BLANK(val) here -- see erratum E20*/ |
| 3523 while (val == 0x20) { | 3558 while (val == 0x20) { |
| 3524 while (val == 0x20) { | 3559 while (val == 0x20) { |
| 3525 val = xmlStringCurrentChar(NULL, cur, &len); | 3560 val = xmlStringCurrentChar(NULL, cur, &len); |
| 3526 cur += len; | 3561 cur += len; |
| 3527 } | 3562 } |
| 3528 | 3563 |
| 3529 » if (!IS_LETTER(val) && (val != '_') && | 3564 » if (!xmlIsDocNameStartChar(doc, val)) |
| 3530 » (val != ':')) { | |
| 3531 return(0); | 3565 return(0); |
| 3532 » } | 3566 |
| 3533 val = xmlStringCurrentChar(NULL, cur, &len); | 3567 val = xmlStringCurrentChar(NULL, cur, &len); |
| 3534 cur += len; | 3568 cur += len; |
| 3535 | 3569 |
| 3536 » while ((IS_LETTER(val)) || (IS_DIGIT(val)) || | 3570 » while (xmlIsDocNameChar(doc, val)) { |
| 3537 » (val == '.') || (val == '-') || | |
| 3538 » (val == '_') || (val == ':') || | |
| 3539 » (IS_COMBINING(val)) || | |
| 3540 » (IS_EXTENDER(val))) { | |
| 3541 val = xmlStringCurrentChar(NULL, cur, &len); | 3571 val = xmlStringCurrentChar(NULL, cur, &len); |
| 3542 cur += len; | 3572 cur += len; |
| 3543 } | 3573 } |
| 3544 } | 3574 } |
| 3545 | 3575 |
| 3546 if (val != 0) return(0); | 3576 if (val != 0) return(0); |
| 3547 | 3577 |
| 3548 return(1); | 3578 return(1); |
| 3549 } | 3579 } |
| 3550 | 3580 |
| 3551 /** | 3581 /** |
| 3552 * xmlValidateNmtokenValue: | 3582 * xmlValidateNamesValue: |
| 3583 * @value: an Names value |
| 3584 * |
| 3585 * Validate that the given value match Names production |
| 3586 * |
| 3587 * returns 1 if valid or 0 otherwise |
| 3588 */ |
| 3589 |
| 3590 int |
| 3591 xmlValidateNamesValue(const xmlChar *value) { |
| 3592 return(xmlValidateNamesValueInternal(NULL, value)); |
| 3593 } |
| 3594 |
| 3595 /** |
| 3596 * xmlValidateNmtokenValueInternal: |
| 3597 * @doc: pointer to the document or NULL |
| 3553 * @value: an Nmtoken value | 3598 * @value: an Nmtoken value |
| 3554 * | 3599 * |
| 3555 * Validate that the given value match Nmtoken production | 3600 * Validate that the given value match Nmtoken production |
| 3556 * | 3601 * |
| 3557 * [ VC: Name Token ] | 3602 * [ VC: Name Token ] |
| 3558 * | 3603 * |
| 3559 * returns 1 if valid or 0 otherwise | 3604 * returns 1 if valid or 0 otherwise |
| 3560 */ | 3605 */ |
| 3561 | 3606 |
| 3562 int | 3607 static int |
| 3563 xmlValidateNmtokenValue(const xmlChar *value) { | 3608 xmlValidateNmtokenValueInternal(xmlDocPtr doc, const xmlChar *value) { |
| 3564 const xmlChar *cur; | 3609 const xmlChar *cur; |
| 3565 int val, len; | 3610 int val, len; |
| 3566 | 3611 |
| 3567 if (value == NULL) return(0); | 3612 if (value == NULL) return(0); |
| 3568 cur = value; | 3613 cur = value; |
| 3569 val = xmlStringCurrentChar(NULL, cur, &len); | 3614 val = xmlStringCurrentChar(NULL, cur, &len); |
| 3570 cur += len; | 3615 cur += len; |
| 3571 | 3616 |
| 3572 if (!IS_LETTER(val) && !IS_DIGIT(val) && | 3617 if (!xmlIsDocNameChar(doc, val)) |
| 3573 (val != '.') && (val != '-') && | |
| 3574 (val != '_') && (val != ':') && | |
| 3575 (!IS_COMBINING(val)) && | |
| 3576 (!IS_EXTENDER(val))) | |
| 3577 return(0); | 3618 return(0); |
| 3578 | 3619 |
| 3579 while ((IS_LETTER(val)) || (IS_DIGIT(val)) || | 3620 val = xmlStringCurrentChar(NULL, cur, &len); |
| 3580 (val == '.') || (val == '-') || | 3621 cur += len; |
| 3581 » (val == '_') || (val == ':') || | 3622 while (xmlIsDocNameChar(doc, val)) { |
| 3582 » (IS_COMBINING(val)) || | |
| 3583 » (IS_EXTENDER(val))) { | |
| 3584 val = xmlStringCurrentChar(NULL, cur, &len); | 3623 val = xmlStringCurrentChar(NULL, cur, &len); |
| 3585 cur += len; | 3624 cur += len; |
| 3586 } | 3625 } |
| 3587 | 3626 |
| 3588 if (val != 0) return(0); | 3627 if (val != 0) return(0); |
| 3589 | 3628 |
| 3590 return(1); | 3629 return(1); |
| 3591 } | 3630 } |
| 3592 | 3631 |
| 3593 /** | 3632 /** |
| 3594 * xmlValidateNmtokensValue: | 3633 * xmlValidateNmtokenValue: |
| 3634 * @value: an Nmtoken value |
| 3635 * |
| 3636 * Validate that the given value match Nmtoken production |
| 3637 * |
| 3638 * [ VC: Name Token ] |
| 3639 * |
| 3640 * returns 1 if valid or 0 otherwise |
| 3641 */ |
| 3642 |
| 3643 int |
| 3644 xmlValidateNmtokenValue(const xmlChar *value) { |
| 3645 return(xmlValidateNmtokenValueInternal(NULL, value)); |
| 3646 } |
| 3647 |
| 3648 /** |
| 3649 * xmlValidateNmtokensValueInternal: |
| 3650 * @doc: pointer to the document or NULL |
| 3595 * @value: an Nmtokens value | 3651 * @value: an Nmtokens value |
| 3596 * | 3652 * |
| 3597 * Validate that the given value match Nmtokens production | 3653 * Validate that the given value match Nmtokens production |
| 3598 * | 3654 * |
| 3599 * [ VC: Name Token ] | 3655 * [ VC: Name Token ] |
| 3600 * | 3656 * |
| 3601 * returns 1 if valid or 0 otherwise | 3657 * returns 1 if valid or 0 otherwise |
| 3602 */ | 3658 */ |
| 3603 | 3659 |
| 3604 int | 3660 static int |
| 3605 xmlValidateNmtokensValue(const xmlChar *value) { | 3661 xmlValidateNmtokensValueInternal(xmlDocPtr doc, const xmlChar *value) { |
| 3606 const xmlChar *cur; | 3662 const xmlChar *cur; |
| 3607 int val, len; | 3663 int val, len; |
| 3608 | 3664 |
| 3609 if (value == NULL) return(0); | 3665 if (value == NULL) return(0); |
| 3610 cur = value; | 3666 cur = value; |
| 3611 val = xmlStringCurrentChar(NULL, cur, &len); | 3667 val = xmlStringCurrentChar(NULL, cur, &len); |
| 3612 cur += len; | 3668 cur += len; |
| 3613 | 3669 |
| 3614 while (IS_BLANK(val)) { | 3670 while (IS_BLANK(val)) { |
| 3615 val = xmlStringCurrentChar(NULL, cur, &len); | 3671 val = xmlStringCurrentChar(NULL, cur, &len); |
| 3616 cur += len; | 3672 cur += len; |
| 3617 } | 3673 } |
| 3618 | 3674 |
| 3619 if (!IS_LETTER(val) && !IS_DIGIT(val) && | 3675 if (!xmlIsDocNameChar(doc, val)) |
| 3620 (val != '.') && (val != '-') && | |
| 3621 (val != '_') && (val != ':') && | |
| 3622 (!IS_COMBINING(val)) && | |
| 3623 (!IS_EXTENDER(val))) | |
| 3624 return(0); | 3676 return(0); |
| 3625 | 3677 |
| 3626 while ((IS_LETTER(val)) || (IS_DIGIT(val)) || | 3678 while (xmlIsDocNameChar(doc, val)) { |
| 3627 (val == '.') || (val == '-') || | |
| 3628 » (val == '_') || (val == ':') || | |
| 3629 » (IS_COMBINING(val)) || | |
| 3630 » (IS_EXTENDER(val))) { | |
| 3631 val = xmlStringCurrentChar(NULL, cur, &len); | 3679 val = xmlStringCurrentChar(NULL, cur, &len); |
| 3632 cur += len; | 3680 cur += len; |
| 3633 } | 3681 } |
| 3634 | 3682 |
| 3635 /* Should not test IS_BLANK(val) here -- see erratum E20*/ | 3683 /* Should not test IS_BLANK(val) here -- see erratum E20*/ |
| 3636 while (val == 0x20) { | 3684 while (val == 0x20) { |
| 3637 while (val == 0x20) { | 3685 while (val == 0x20) { |
| 3638 val = xmlStringCurrentChar(NULL, cur, &len); | 3686 val = xmlStringCurrentChar(NULL, cur, &len); |
| 3639 cur += len; | 3687 cur += len; |
| 3640 } | 3688 } |
| 3641 if (val == 0) return(1); | 3689 if (val == 0) return(1); |
| 3642 | 3690 |
| 3643 » if (!IS_LETTER(val) && !IS_DIGIT(val) && | 3691 » if (!xmlIsDocNameChar(doc, val)) |
| 3644 » (val != '.') && (val != '-') && | |
| 3645 » (val != '_') && (val != ':') && | |
| 3646 » (!IS_COMBINING(val)) && | |
| 3647 » (!IS_EXTENDER(val))) | |
| 3648 return(0); | 3692 return(0); |
| 3649 | 3693 |
| 3650 » while ((IS_LETTER(val)) || (IS_DIGIT(val)) || | 3694 » val = xmlStringCurrentChar(NULL, cur, &len); |
| 3651 » (val == '.') || (val == '-') || | 3695 » cur += len; |
| 3652 » (val == '_') || (val == ':') || | 3696 |
| 3653 » (IS_COMBINING(val)) || | 3697 » while (xmlIsDocNameChar(doc, val)) { |
| 3654 » (IS_EXTENDER(val))) { | |
| 3655 val = xmlStringCurrentChar(NULL, cur, &len); | 3698 val = xmlStringCurrentChar(NULL, cur, &len); |
| 3656 cur += len; | 3699 cur += len; |
| 3657 } | 3700 } |
| 3658 } | 3701 } |
| 3659 | 3702 |
| 3660 if (val != 0) return(0); | 3703 if (val != 0) return(0); |
| 3661 | 3704 |
| 3662 return(1); | 3705 return(1); |
| 3663 } | 3706 } |
| 3664 | 3707 |
| 3665 /** | 3708 /** |
| 3709 * xmlValidateNmtokensValue: |
| 3710 * @value: an Nmtokens value |
| 3711 * |
| 3712 * Validate that the given value match Nmtokens production |
| 3713 * |
| 3714 * [ VC: Name Token ] |
| 3715 * |
| 3716 * returns 1 if valid or 0 otherwise |
| 3717 */ |
| 3718 |
| 3719 int |
| 3720 xmlValidateNmtokensValue(const xmlChar *value) { |
| 3721 return(xmlValidateNmtokensValueInternal(NULL, value)); |
| 3722 } |
| 3723 |
| 3724 /** |
| 3666 * xmlValidateNotationDecl: | 3725 * xmlValidateNotationDecl: |
| 3667 * @ctxt: the validation context | 3726 * @ctxt: the validation context |
| 3668 * @doc: a document instance | 3727 * @doc: a document instance |
| 3669 * @nota: a notation definition | 3728 * @nota: a notation definition |
| 3670 * | 3729 * |
| 3671 * Try to validate a single notation definition | 3730 * Try to validate a single notation definition |
| 3672 * basically it does the following checks as described by the | 3731 * basically it does the following checks as described by the |
| 3673 * XML-1.0 recommendation: | 3732 * XML-1.0 recommendation: |
| 3674 * - it seems that no validity constraint exists on notation declarations | 3733 * - it seems that no validity constraint exists on notation declarations |
| 3675 * But this function get called anyway ... | 3734 * But this function get called anyway ... |
| 3676 * | 3735 * |
| 3677 * returns 1 if valid or 0 otherwise | 3736 * returns 1 if valid or 0 otherwise |
| 3678 */ | 3737 */ |
| 3679 | 3738 |
| 3680 int | 3739 int |
| 3681 xmlValidateNotationDecl(xmlValidCtxtPtr ctxt ATTRIBUTE_UNUSED, xmlDocPtr doc ATT
RIBUTE_UNUSED, | 3740 xmlValidateNotationDecl(xmlValidCtxtPtr ctxt ATTRIBUTE_UNUSED, xmlDocPtr doc ATT
RIBUTE_UNUSED, |
| 3682 xmlNotationPtr nota ATTRIBUTE_UNUSED) { | 3741 xmlNotationPtr nota ATTRIBUTE_UNUSED) { |
| 3683 int ret = 1; | 3742 int ret = 1; |
| 3684 | 3743 |
| 3685 return(ret); | 3744 return(ret); |
| 3686 } | 3745 } |
| 3687 | 3746 |
| 3688 /** | 3747 /** |
| 3748 * xmlValidateAttributeValueInternal: |
| 3749 * @doc: the document |
| 3750 * @type: an attribute type |
| 3751 * @value: an attribute value |
| 3752 * |
| 3753 * Validate that the given attribute value match the proper production |
| 3754 * |
| 3755 * returns 1 if valid or 0 otherwise |
| 3756 */ |
| 3757 |
| 3758 static int |
| 3759 xmlValidateAttributeValueInternal(xmlDocPtr doc, xmlAttributeType type, |
| 3760 const xmlChar *value) { |
| 3761 switch (type) { |
| 3762 case XML_ATTRIBUTE_ENTITIES: |
| 3763 case XML_ATTRIBUTE_IDREFS: |
| 3764 return(xmlValidateNamesValueInternal(doc, value)); |
| 3765 case XML_ATTRIBUTE_ENTITY: |
| 3766 case XML_ATTRIBUTE_IDREF: |
| 3767 case XML_ATTRIBUTE_ID: |
| 3768 case XML_ATTRIBUTE_NOTATION: |
| 3769 return(xmlValidateNameValueInternal(doc, value)); |
| 3770 case XML_ATTRIBUTE_NMTOKENS: |
| 3771 case XML_ATTRIBUTE_ENUMERATION: |
| 3772 return(xmlValidateNmtokensValueInternal(doc, value)); |
| 3773 case XML_ATTRIBUTE_NMTOKEN: |
| 3774 return(xmlValidateNmtokenValueInternal(doc, value)); |
| 3775 case XML_ATTRIBUTE_CDATA: |
| 3776 break; |
| 3777 } |
| 3778 return(1); |
| 3779 } |
| 3780 |
| 3781 /** |
| 3689 * xmlValidateAttributeValue: | 3782 * xmlValidateAttributeValue: |
| 3690 * @type: an attribute type | 3783 * @type: an attribute type |
| 3691 * @value: an attribute value | 3784 * @value: an attribute value |
| 3692 * | 3785 * |
| 3693 * Validate that the given attribute value match the proper production | 3786 * Validate that the given attribute value match the proper production |
| 3694 * | 3787 * |
| 3695 * [ VC: ID ] | 3788 * [ VC: ID ] |
| 3696 * Values of type ID must match the Name production.... | 3789 * Values of type ID must match the Name production.... |
| 3697 * | 3790 * |
| 3698 * [ VC: IDREF ] | 3791 * [ VC: IDREF ] |
| 3699 * Values of type IDREF must match the Name production, and values | 3792 * Values of type IDREF must match the Name production, and values |
| 3700 * of type IDREFS must match Names ... | 3793 * of type IDREFS must match Names ... |
| 3701 * | 3794 * |
| 3702 * [ VC: Entity Name ] | 3795 * [ VC: Entity Name ] |
| 3703 * Values of type ENTITY must match the Name production, values | 3796 * Values of type ENTITY must match the Name production, values |
| 3704 * of type ENTITIES must match Names ... | 3797 * of type ENTITIES must match Names ... |
| 3705 * | 3798 * |
| 3706 * [ VC: Name Token ] | 3799 * [ VC: Name Token ] |
| 3707 * Values of type NMTOKEN must match the Nmtoken production; values | 3800 * Values of type NMTOKEN must match the Nmtoken production; values |
| 3708 * of type NMTOKENS must match Nmtokens. | 3801 * of type NMTOKENS must match Nmtokens. |
| 3709 * | 3802 * |
| 3710 * returns 1 if valid or 0 otherwise | 3803 * returns 1 if valid or 0 otherwise |
| 3711 */ | 3804 */ |
| 3712 | |
| 3713 int | 3805 int |
| 3714 xmlValidateAttributeValue(xmlAttributeType type, const xmlChar *value) { | 3806 xmlValidateAttributeValue(xmlAttributeType type, const xmlChar *value) { |
| 3715 switch (type) { | 3807 return(xmlValidateAttributeValueInternal(NULL, type, value)); |
| 3716 » case XML_ATTRIBUTE_ENTITIES: | |
| 3717 » case XML_ATTRIBUTE_IDREFS: | |
| 3718 » return(xmlValidateNamesValue(value)); | |
| 3719 » case XML_ATTRIBUTE_ENTITY: | |
| 3720 » case XML_ATTRIBUTE_IDREF: | |
| 3721 » case XML_ATTRIBUTE_ID: | |
| 3722 » case XML_ATTRIBUTE_NOTATION: | |
| 3723 » return(xmlValidateNameValue(value)); | |
| 3724 » case XML_ATTRIBUTE_NMTOKENS: | |
| 3725 » case XML_ATTRIBUTE_ENUMERATION: | |
| 3726 » return(xmlValidateNmtokensValue(value)); | |
| 3727 » case XML_ATTRIBUTE_NMTOKEN: | |
| 3728 » return(xmlValidateNmtokenValue(value)); | |
| 3729 case XML_ATTRIBUTE_CDATA: | |
| 3730 » break; | |
| 3731 } | |
| 3732 return(1); | |
| 3733 } | 3808 } |
| 3734 | 3809 |
| 3735 /** | 3810 /** |
| 3736 * xmlValidateAttributeValue2: | 3811 * xmlValidateAttributeValue2: |
| 3737 * @ctxt: the validation context | 3812 * @ctxt: the validation context |
| 3738 * @doc: the document | 3813 * @doc: the document |
| 3739 * @name: the attribute name (used for error reporting only) | 3814 * @name: the attribute name (used for error reporting only) |
| 3740 * @type: the attribute type | 3815 * @type: the attribute type |
| 3741 * @value: the attribute value | 3816 * @value: the attribute value |
| 3742 * | 3817 * |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3971 xmlAttributePtr attrDecl = NULL; | 4046 xmlAttributePtr attrDecl = NULL; |
| 3972 | 4047 |
| 3973 if (doc == NULL) return(NULL); | 4048 if (doc == NULL) return(NULL); |
| 3974 if (elem == NULL) return(NULL); | 4049 if (elem == NULL) return(NULL); |
| 3975 if (name == NULL) return(NULL); | 4050 if (name == NULL) return(NULL); |
| 3976 if (value == NULL) return(NULL); | 4051 if (value == NULL) return(NULL); |
| 3977 | 4052 |
| 3978 if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) { | 4053 if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) { |
| 3979 xmlChar fn[50]; | 4054 xmlChar fn[50]; |
| 3980 xmlChar *fullname; | 4055 xmlChar *fullname; |
| 3981 » | 4056 |
| 3982 fullname = xmlBuildQName(elem->name, elem->ns->prefix, fn, 50); | 4057 fullname = xmlBuildQName(elem->name, elem->ns->prefix, fn, 50); |
| 3983 if (fullname == NULL) | 4058 if (fullname == NULL) |
| 3984 return(NULL); | 4059 return(NULL); |
| 3985 attrDecl = xmlGetDtdAttrDesc(doc->intSubset, fullname, name); | |
| 3986 if ((attrDecl == NULL) && (doc->extSubset != NULL)) | |
| 3987 attrDecl = xmlGetDtdAttrDesc(doc->extSubset, fullname, name); | |
| 3988 if ((fullname != fn) && (fullname != elem->name)) | 4060 if ((fullname != fn) && (fullname != elem->name)) |
| 3989 xmlFree(fullname); | 4061 xmlFree(fullname); |
| 3990 } | 4062 } |
| 3991 attrDecl = xmlGetDtdAttrDesc(doc->intSubset, elem->name, name); | 4063 attrDecl = xmlGetDtdAttrDesc(doc->intSubset, elem->name, name); |
| 3992 if ((attrDecl == NULL) && (doc->extSubset != NULL)) | 4064 if ((attrDecl == NULL) && (doc->extSubset != NULL)) |
| 3993 attrDecl = xmlGetDtdAttrDesc(doc->extSubset, elem->name, name); | 4065 attrDecl = xmlGetDtdAttrDesc(doc->extSubset, elem->name, name); |
| 3994 | 4066 |
| 3995 if (attrDecl == NULL) | 4067 if (attrDecl == NULL) |
| 3996 return(NULL); | 4068 return(NULL); |
| 3997 if (attrDecl->atype == XML_ATTRIBUTE_CDATA) | 4069 if (attrDecl->atype == XML_ATTRIBUTE_CDATA) |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4040 * returns 1 if valid or 0 otherwise | 4112 * returns 1 if valid or 0 otherwise |
| 4041 */ | 4113 */ |
| 4042 | 4114 |
| 4043 int | 4115 int |
| 4044 xmlValidateAttributeDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc, | 4116 xmlValidateAttributeDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc, |
| 4045 xmlAttributePtr attr) { | 4117 xmlAttributePtr attr) { |
| 4046 int ret = 1; | 4118 int ret = 1; |
| 4047 int val; | 4119 int val; |
| 4048 CHECK_DTD; | 4120 CHECK_DTD; |
| 4049 if(attr == NULL) return(1); | 4121 if(attr == NULL) return(1); |
| 4050 | 4122 |
| 4051 /* Attribute Default Legal */ | 4123 /* Attribute Default Legal */ |
| 4052 /* Enumeration */ | 4124 /* Enumeration */ |
| 4053 if (attr->defaultValue != NULL) { | 4125 if (attr->defaultValue != NULL) { |
| 4054 » val = xmlValidateAttributeValue(attr->atype, attr->defaultValue); | 4126 » val = xmlValidateAttributeValueInternal(doc, attr->atype, |
| 4127 » attr->defaultValue); |
| 4055 if (val == 0) { | 4128 if (val == 0) { |
| 4056 xmlErrValidNode(ctxt, (xmlNodePtr) attr, XML_DTD_ATTRIBUTE_DEFAULT, | 4129 xmlErrValidNode(ctxt, (xmlNodePtr) attr, XML_DTD_ATTRIBUTE_DEFAULT, |
| 4057 "Syntax of default value for attribute %s of %s is not valid\n", | 4130 "Syntax of default value for attribute %s of %s is not valid\n", |
| 4058 attr->name, attr->elem, NULL); | 4131 attr->name, attr->elem, NULL); |
| 4059 } | 4132 } |
| 4060 ret &= val; | 4133 ret &= val; |
| 4061 } | 4134 } |
| 4062 | 4135 |
| 4063 /* ID Attribute Default */ | 4136 /* ID Attribute Default */ |
| 4064 if ((attr->atype == XML_ATTRIBUTE_ID)&& | 4137 if ((attr->atype == XML_ATTRIBUTE_ID)&& |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4175 cur = elem->content; | 4248 cur = elem->content; |
| 4176 while (cur != NULL) { | 4249 while (cur != NULL) { |
| 4177 if (cur->type != XML_ELEMENT_CONTENT_OR) break; | 4250 if (cur->type != XML_ELEMENT_CONTENT_OR) break; |
| 4178 if (cur->c1 == NULL) break; | 4251 if (cur->c1 == NULL) break; |
| 4179 if (cur->c1->type == XML_ELEMENT_CONTENT_ELEMENT) { | 4252 if (cur->c1->type == XML_ELEMENT_CONTENT_ELEMENT) { |
| 4180 name = cur->c1->name; | 4253 name = cur->c1->name; |
| 4181 next = cur->c2; | 4254 next = cur->c2; |
| 4182 while (next != NULL) { | 4255 while (next != NULL) { |
| 4183 if (next->type == XML_ELEMENT_CONTENT_ELEMENT) { | 4256 if (next->type == XML_ELEMENT_CONTENT_ELEMENT) { |
| 4184 if ((xmlStrEqual(next->name, name)) && | 4257 if ((xmlStrEqual(next->name, name)) && |
| 4185 » » » (xmlStrEqual(next->prefix, cur->prefix))) { | 4258 » » » (xmlStrEqual(next->prefix, cur->c1->prefix))) { |
| 4186 » » » if (cur->prefix == NULL) { | 4259 » » » if (cur->c1->prefix == NULL) { |
| 4187 xmlErrValidNode(ctxt, (xmlNodePtr) elem, XML_DTD
_CONTENT_ERROR, | 4260 xmlErrValidNode(ctxt, (xmlNodePtr) elem, XML_DTD
_CONTENT_ERROR, |
| 4188 "Definition of %s has duplicate references of %s\n", | 4261 "Definition of %s has duplicate references of %s\n", |
| 4189 elem->name, name, NULL); | 4262 elem->name, name, NULL); |
| 4190 } else { | 4263 } else { |
| 4191 xmlErrValidNode(ctxt, (xmlNodePtr) elem, XML_DTD
_CONTENT_ERROR, | 4264 xmlErrValidNode(ctxt, (xmlNodePtr) elem, XML_DTD
_CONTENT_ERROR, |
| 4192 "Definition of %s has duplicate references of %s:%s\n", | 4265 "Definition of %s has duplicate references of %s:%s\n", |
| 4193 » » » » elem->name, cur->prefix, name); | 4266 » » » » elem->name, cur->c1->prefix, name); |
| 4194 } | 4267 } |
| 4195 ret = 0; | 4268 ret = 0; |
| 4196 } | 4269 } |
| 4197 break; | 4270 break; |
| 4198 } | 4271 } |
| 4199 if (next->c1 == NULL) break; | 4272 if (next->c1 == NULL) break; |
| 4200 if (next->c1->type != XML_ELEMENT_CONTENT_ELEMENT) break; | 4273 if (next->c1->type != XML_ELEMENT_CONTENT_ELEMENT) break; |
| 4201 if ((xmlStrEqual(next->c1->name, name)) && | 4274 if ((xmlStrEqual(next->c1->name, name)) && |
| 4202 » » (xmlStrEqual(next->c1->prefix, cur->prefix))) { | 4275 » » (xmlStrEqual(next->c1->prefix, cur->c1->prefix))) { |
| 4203 » » » if (cur->prefix == NULL) { | 4276 » » » if (cur->c1->prefix == NULL) { |
| 4204 xmlErrValidNode(ctxt, (xmlNodePtr) elem, XML_DTD_CON
TENT_ERROR, | 4277 xmlErrValidNode(ctxt, (xmlNodePtr) elem, XML_DTD_CON
TENT_ERROR, |
| 4205 "Definition of %s has duplicate references to %s\n", | 4278 "Definition of %s has duplicate references to %s\n", |
| 4206 elem->name, name, NULL); | 4279 elem->name, name, NULL); |
| 4207 } else { | 4280 } else { |
| 4208 xmlErrValidNode(ctxt, (xmlNodePtr) elem, XML_DTD_CON
TENT_ERROR, | 4281 xmlErrValidNode(ctxt, (xmlNodePtr) elem, XML_DTD_CON
TENT_ERROR, |
| 4209 "Definition of %s has duplicate references to %s:%s\n", | 4282 "Definition of %s has duplicate references to %s:%s\n", |
| 4210 » » » » elem->name, cur->prefix, name); | 4283 » » » » elem->name, cur->c1->prefix, name); |
| 4211 } | 4284 } |
| 4212 ret = 0; | 4285 ret = 0; |
| 4213 } | 4286 } |
| 4214 next = next->c2; | 4287 next = next->c2; |
| 4215 } | 4288 } |
| 4216 } | 4289 } |
| 4217 cur = cur->c2; | 4290 cur = cur->c2; |
| 4218 } | 4291 } |
| 4219 } | 4292 } |
| 4220 | 4293 |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4325 | 4398 |
| 4326 /* Validity Constraint: Attribute Value Type */ | 4399 /* Validity Constraint: Attribute Value Type */ |
| 4327 if (attrDecl == NULL) { | 4400 if (attrDecl == NULL) { |
| 4328 xmlErrValidNode(ctxt, elem, XML_DTD_UNKNOWN_ATTRIBUTE, | 4401 xmlErrValidNode(ctxt, elem, XML_DTD_UNKNOWN_ATTRIBUTE, |
| 4329 "No declaration for attribute %s of element %s\n", | 4402 "No declaration for attribute %s of element %s\n", |
| 4330 attr->name, elem->name, NULL); | 4403 attr->name, elem->name, NULL); |
| 4331 return(0); | 4404 return(0); |
| 4332 } | 4405 } |
| 4333 attr->atype = attrDecl->atype; | 4406 attr->atype = attrDecl->atype; |
| 4334 | 4407 |
| 4335 val = xmlValidateAttributeValue(attrDecl->atype, value); | 4408 val = xmlValidateAttributeValueInternal(doc, attrDecl->atype, value); |
| 4336 if (val == 0) { | 4409 if (val == 0) { |
| 4337 xmlErrValidNode(ctxt, elem, XML_DTD_ATTRIBUTE_VALUE, | 4410 xmlErrValidNode(ctxt, elem, XML_DTD_ATTRIBUTE_VALUE, |
| 4338 "Syntax of value for attribute %s of %s is not valid\n", | 4411 "Syntax of value for attribute %s of %s is not valid\n", |
| 4339 attr->name, elem->name, NULL); | 4412 attr->name, elem->name, NULL); |
| 4340 ret = 0; | 4413 ret = 0; |
| 4341 } | 4414 } |
| 4342 | 4415 |
| 4343 /* Validity constraint: Fixed Attribute Default */ | 4416 /* Validity constraint: Fixed Attribute Default */ |
| 4344 if (attrDecl->def == XML_ATTRIBUTE_FIXED) { | 4417 if (attrDecl->def == XML_ATTRIBUTE_FIXED) { |
| 4345 if (!xmlStrEqual(value, attrDecl->defaultValue)) { | 4418 if (!xmlStrEqual(value, attrDecl->defaultValue)) { |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4510 "No declaration for attribute xmlns:%s of element %s\n", | 4583 "No declaration for attribute xmlns:%s of element %s\n", |
| 4511 ns->prefix, elem->name, NULL); | 4584 ns->prefix, elem->name, NULL); |
| 4512 } else { | 4585 } else { |
| 4513 xmlErrValidNode(ctxt, elem, XML_DTD_UNKNOWN_ATTRIBUTE, | 4586 xmlErrValidNode(ctxt, elem, XML_DTD_UNKNOWN_ATTRIBUTE, |
| 4514 "No declaration for attribute xmlns of element %s\n", | 4587 "No declaration for attribute xmlns of element %s\n", |
| 4515 elem->name, NULL, NULL); | 4588 elem->name, NULL, NULL); |
| 4516 } | 4589 } |
| 4517 return(0); | 4590 return(0); |
| 4518 } | 4591 } |
| 4519 | 4592 |
| 4520 val = xmlValidateAttributeValue(attrDecl->atype, value); | 4593 val = xmlValidateAttributeValueInternal(doc, attrDecl->atype, value); |
| 4521 if (val == 0) { | 4594 if (val == 0) { |
| 4522 if (ns->prefix != NULL) { | 4595 if (ns->prefix != NULL) { |
| 4523 xmlErrValidNode(ctxt, elem, XML_DTD_INVALID_DEFAULT, | 4596 xmlErrValidNode(ctxt, elem, XML_DTD_INVALID_DEFAULT, |
| 4524 "Syntax of value for attribute xmlns:%s of %s is not valid\n", | 4597 "Syntax of value for attribute xmlns:%s of %s is not valid\n", |
| 4525 ns->prefix, elem->name, NULL); | 4598 ns->prefix, elem->name, NULL); |
| 4526 } else { | 4599 } else { |
| 4527 xmlErrValidNode(ctxt, elem, XML_DTD_INVALID_DEFAULT, | 4600 xmlErrValidNode(ctxt, elem, XML_DTD_INVALID_DEFAULT, |
| 4528 "Syntax of value for attribute xmlns of %s is not valid\n", | 4601 "Syntax of value for attribute xmlns of %s is not valid\n", |
| 4529 elem->name, NULL, NULL); | 4602 elem->name, NULL, NULL); |
| 4530 } | 4603 } |
| (...skipping 2135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6666 * | 6739 * |
| 6667 * returns 1 if valid or 0 if invalid and -1 if not well-formed | 6740 * returns 1 if valid or 0 if invalid and -1 if not well-formed |
| 6668 */ | 6741 */ |
| 6669 | 6742 |
| 6670 int | 6743 int |
| 6671 xmlValidateDtdFinal(xmlValidCtxtPtr ctxt, xmlDocPtr doc) { | 6744 xmlValidateDtdFinal(xmlValidCtxtPtr ctxt, xmlDocPtr doc) { |
| 6672 xmlDtdPtr dtd; | 6745 xmlDtdPtr dtd; |
| 6673 xmlAttributeTablePtr table; | 6746 xmlAttributeTablePtr table; |
| 6674 xmlEntitiesTablePtr entities; | 6747 xmlEntitiesTablePtr entities; |
| 6675 | 6748 |
| 6676 if (doc == NULL) return(0); | 6749 if ((doc == NULL) || (ctxt == NULL)) return(0); |
| 6677 if ((doc->intSubset == NULL) && (doc->extSubset == NULL)) | 6750 if ((doc->intSubset == NULL) && (doc->extSubset == NULL)) |
| 6678 return(0); | 6751 return(0); |
| 6679 ctxt->doc = doc; | 6752 ctxt->doc = doc; |
| 6680 ctxt->valid = 1; | 6753 ctxt->valid = 1; |
| 6681 dtd = doc->intSubset; | 6754 dtd = doc->intSubset; |
| 6682 if ((dtd != NULL) && (dtd->attributes != NULL)) { | 6755 if ((dtd != NULL) && (dtd->attributes != NULL)) { |
| 6683 table = (xmlAttributeTablePtr) dtd->attributes; | 6756 table = (xmlAttributeTablePtr) dtd->attributes; |
| 6684 xmlHashScan(table, (xmlHashScanner) xmlValidateAttributeCallback, ctxt); | 6757 xmlHashScan(table, (xmlHashScanner) xmlValidateAttributeCallback, ctxt); |
| 6685 } | 6758 } |
| 6686 if ((dtd != NULL) && (dtd->entities != NULL)) { | 6759 if ((dtd != NULL) && (dtd->entities != NULL)) { |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6959 */ | 7032 */ |
| 6960 test_node->name = name; | 7033 test_node->name = name; |
| 6961 xmlFreeNode(test_node); | 7034 xmlFreeNode(test_node); |
| 6962 | 7035 |
| 6963 return(nb_valid_elements); | 7036 return(nb_valid_elements); |
| 6964 } | 7037 } |
| 6965 #endif /* LIBXML_VALID_ENABLED */ | 7038 #endif /* LIBXML_VALID_ENABLED */ |
| 6966 | 7039 |
| 6967 #define bottom_valid | 7040 #define bottom_valid |
| 6968 #include "elfgcchack.h" | 7041 #include "elfgcchack.h" |
| OLD | NEW |