XML C parser available under the MIT license. http://xmlsoft.org/

Dependents:   libiio

Committer:
pcercuei
Date:
Thu Aug 25 10:07:34 2016 +0000
Revision:
1:26f20484cbdc
Parent:
0:03b5121a232e
Add config.h and dummy.c containing empty functions

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pcercuei 0:03b5121a232e 1 /*
pcercuei 0:03b5121a232e 2 * parser.c : an XML 1.0 parser, namespaces and validity support are mostly
pcercuei 0:03b5121a232e 3 * implemented on top of the SAX interfaces
pcercuei 0:03b5121a232e 4 *
pcercuei 0:03b5121a232e 5 * References:
pcercuei 0:03b5121a232e 6 * The XML specification:
pcercuei 0:03b5121a232e 7 * http://www.w3.org/TR/REC-xml
pcercuei 0:03b5121a232e 8 * Original 1.0 version:
pcercuei 0:03b5121a232e 9 * http://www.w3.org/TR/1998/REC-xml-19980210
pcercuei 0:03b5121a232e 10 * XML second edition working draft
pcercuei 0:03b5121a232e 11 * http://www.w3.org/TR/2000/WD-xml-2e-20000814
pcercuei 0:03b5121a232e 12 *
pcercuei 0:03b5121a232e 13 * Okay this is a big file, the parser core is around 7000 lines, then it
pcercuei 0:03b5121a232e 14 * is followed by the progressive parser top routines, then the various
pcercuei 0:03b5121a232e 15 * high level APIs to call the parser and a few miscellaneous functions.
pcercuei 0:03b5121a232e 16 * A number of helper functions and deprecated ones have been moved to
pcercuei 0:03b5121a232e 17 * parserInternals.c to reduce this file size.
pcercuei 0:03b5121a232e 18 * As much as possible the functions are associated with their relative
pcercuei 0:03b5121a232e 19 * production in the XML specification. A few productions defining the
pcercuei 0:03b5121a232e 20 * different ranges of character are actually implanted either in
pcercuei 0:03b5121a232e 21 * parserInternals.h or parserInternals.c
pcercuei 0:03b5121a232e 22 * The DOM tree build is realized from the default SAX callbacks in
pcercuei 0:03b5121a232e 23 * the module SAX.c.
pcercuei 0:03b5121a232e 24 * The routines doing the validation checks are in valid.c and called either
pcercuei 0:03b5121a232e 25 * from the SAX callbacks or as standalone functions using a preparsed
pcercuei 0:03b5121a232e 26 * document.
pcercuei 0:03b5121a232e 27 *
pcercuei 0:03b5121a232e 28 * See Copyright for the status of this software.
pcercuei 0:03b5121a232e 29 *
pcercuei 0:03b5121a232e 30 * daniel@veillard.com
pcercuei 0:03b5121a232e 31 */
pcercuei 0:03b5121a232e 32
pcercuei 0:03b5121a232e 33 #define IN_LIBXML
pcercuei 0:03b5121a232e 34 #include "libxml.h"
pcercuei 0:03b5121a232e 35
pcercuei 0:03b5121a232e 36 #if defined(WIN32) && !defined (__CYGWIN__)
pcercuei 0:03b5121a232e 37 #define XML_DIR_SEP '\\'
pcercuei 0:03b5121a232e 38 #else
pcercuei 0:03b5121a232e 39 #define XML_DIR_SEP '/'
pcercuei 0:03b5121a232e 40 #endif
pcercuei 0:03b5121a232e 41
pcercuei 0:03b5121a232e 42 #include <stdlib.h>
pcercuei 0:03b5121a232e 43 #include <limits.h>
pcercuei 0:03b5121a232e 44 #include <string.h>
pcercuei 0:03b5121a232e 45 #include <stdarg.h>
pcercuei 0:03b5121a232e 46 #include <libxml/xmlmemory.h>
pcercuei 0:03b5121a232e 47 #include <libxml/threads.h>
pcercuei 0:03b5121a232e 48 #include <libxml/globals.h>
pcercuei 0:03b5121a232e 49 #include <libxml/tree.h>
pcercuei 0:03b5121a232e 50 #include <libxml/parser.h>
pcercuei 0:03b5121a232e 51 #include <libxml/parserInternals.h>
pcercuei 0:03b5121a232e 52 #include <libxml/valid.h>
pcercuei 0:03b5121a232e 53 #include <libxml/entities.h>
pcercuei 0:03b5121a232e 54 #include <libxml/xmlerror.h>
pcercuei 0:03b5121a232e 55 #include <libxml/encoding.h>
pcercuei 0:03b5121a232e 56 #include <libxml/xmlIO.h>
pcercuei 0:03b5121a232e 57 #include <libxml/uri.h>
pcercuei 0:03b5121a232e 58 #ifdef LIBXML_CATALOG_ENABLED
pcercuei 0:03b5121a232e 59 #include <libxml/catalog.h>
pcercuei 0:03b5121a232e 60 #endif
pcercuei 0:03b5121a232e 61 #ifdef LIBXML_SCHEMAS_ENABLED
pcercuei 0:03b5121a232e 62 #include <libxml/xmlschemastypes.h>
pcercuei 0:03b5121a232e 63 #include <libxml/relaxng.h>
pcercuei 0:03b5121a232e 64 #endif
pcercuei 0:03b5121a232e 65 #ifdef HAVE_CTYPE_H
pcercuei 0:03b5121a232e 66 #include <ctype.h>
pcercuei 0:03b5121a232e 67 #endif
pcercuei 0:03b5121a232e 68 #ifdef HAVE_STDLIB_H
pcercuei 0:03b5121a232e 69 #include <stdlib.h>
pcercuei 0:03b5121a232e 70 #endif
pcercuei 0:03b5121a232e 71 #ifdef HAVE_SYS_STAT_H
pcercuei 0:03b5121a232e 72 #include <sys/stat.h>
pcercuei 0:03b5121a232e 73 #endif
pcercuei 0:03b5121a232e 74 #ifdef HAVE_FCNTL_H
pcercuei 0:03b5121a232e 75 #include <fcntl.h>
pcercuei 0:03b5121a232e 76 #endif
pcercuei 0:03b5121a232e 77 #ifdef HAVE_UNISTD_H
pcercuei 0:03b5121a232e 78 #include <unistd.h>
pcercuei 0:03b5121a232e 79 #endif
pcercuei 0:03b5121a232e 80 #ifdef HAVE_ZLIB_H
pcercuei 0:03b5121a232e 81 #include <zlib.h>
pcercuei 0:03b5121a232e 82 #endif
pcercuei 0:03b5121a232e 83 #ifdef HAVE_LZMA_H
pcercuei 0:03b5121a232e 84 #include <lzma.h>
pcercuei 0:03b5121a232e 85 #endif
pcercuei 0:03b5121a232e 86
pcercuei 0:03b5121a232e 87 #include "buf.h"
pcercuei 0:03b5121a232e 88 #include "enc.h"
pcercuei 0:03b5121a232e 89
pcercuei 0:03b5121a232e 90 static void
pcercuei 0:03b5121a232e 91 xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info);
pcercuei 0:03b5121a232e 92
pcercuei 0:03b5121a232e 93 static xmlParserCtxtPtr
pcercuei 0:03b5121a232e 94 xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
pcercuei 0:03b5121a232e 95 const xmlChar *base, xmlParserCtxtPtr pctx);
pcercuei 0:03b5121a232e 96
pcercuei 0:03b5121a232e 97 static void xmlHaltParser(xmlParserCtxtPtr ctxt);
pcercuei 0:03b5121a232e 98
pcercuei 0:03b5121a232e 99 /************************************************************************
pcercuei 0:03b5121a232e 100 * *
pcercuei 0:03b5121a232e 101 * Arbitrary limits set in the parser. See XML_PARSE_HUGE *
pcercuei 0:03b5121a232e 102 * *
pcercuei 0:03b5121a232e 103 ************************************************************************/
pcercuei 0:03b5121a232e 104
pcercuei 0:03b5121a232e 105 #define XML_PARSER_BIG_ENTITY 1000
pcercuei 0:03b5121a232e 106 #define XML_PARSER_LOT_ENTITY 5000
pcercuei 0:03b5121a232e 107
pcercuei 0:03b5121a232e 108 /*
pcercuei 0:03b5121a232e 109 * XML_PARSER_NON_LINEAR is the threshold where the ratio of parsed entity
pcercuei 0:03b5121a232e 110 * replacement over the size in byte of the input indicates that you have
pcercuei 0:03b5121a232e 111 * and eponential behaviour. A value of 10 correspond to at least 3 entity
pcercuei 0:03b5121a232e 112 * replacement per byte of input.
pcercuei 0:03b5121a232e 113 */
pcercuei 0:03b5121a232e 114 #define XML_PARSER_NON_LINEAR 10
pcercuei 0:03b5121a232e 115
pcercuei 0:03b5121a232e 116 /*
pcercuei 0:03b5121a232e 117 * xmlParserEntityCheck
pcercuei 0:03b5121a232e 118 *
pcercuei 0:03b5121a232e 119 * Function to check non-linear entity expansion behaviour
pcercuei 0:03b5121a232e 120 * This is here to detect and stop exponential linear entity expansion
pcercuei 0:03b5121a232e 121 * This is not a limitation of the parser but a safety
pcercuei 0:03b5121a232e 122 * boundary feature. It can be disabled with the XML_PARSE_HUGE
pcercuei 0:03b5121a232e 123 * parser option.
pcercuei 0:03b5121a232e 124 */
pcercuei 0:03b5121a232e 125 static int
pcercuei 0:03b5121a232e 126 xmlParserEntityCheck(xmlParserCtxtPtr ctxt, size_t size,
pcercuei 0:03b5121a232e 127 xmlEntityPtr ent, size_t replacement)
pcercuei 0:03b5121a232e 128 {
pcercuei 0:03b5121a232e 129 size_t consumed = 0;
pcercuei 0:03b5121a232e 130
pcercuei 0:03b5121a232e 131 if ((ctxt == NULL) || (ctxt->options & XML_PARSE_HUGE))
pcercuei 0:03b5121a232e 132 return (0);
pcercuei 0:03b5121a232e 133 if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
pcercuei 0:03b5121a232e 134 return (1);
pcercuei 0:03b5121a232e 135
pcercuei 0:03b5121a232e 136 /*
pcercuei 0:03b5121a232e 137 * This may look absurd but is needed to detect
pcercuei 0:03b5121a232e 138 * entities problems
pcercuei 0:03b5121a232e 139 */
pcercuei 0:03b5121a232e 140 if ((ent != NULL) && (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
pcercuei 0:03b5121a232e 141 (ent->content != NULL) && (ent->checked == 0)) {
pcercuei 0:03b5121a232e 142 unsigned long oldnbent = ctxt->nbentities;
pcercuei 0:03b5121a232e 143 xmlChar *rep;
pcercuei 0:03b5121a232e 144
pcercuei 0:03b5121a232e 145 ent->checked = 1;
pcercuei 0:03b5121a232e 146
pcercuei 0:03b5121a232e 147 rep = xmlStringDecodeEntities(ctxt, ent->content,
pcercuei 0:03b5121a232e 148 XML_SUBSTITUTE_REF, 0, 0, 0);
pcercuei 0:03b5121a232e 149
pcercuei 0:03b5121a232e 150 ent->checked = (ctxt->nbentities - oldnbent + 1) * 2;
pcercuei 0:03b5121a232e 151 if (rep != NULL) {
pcercuei 0:03b5121a232e 152 if (xmlStrchr(rep, '<'))
pcercuei 0:03b5121a232e 153 ent->checked |= 1;
pcercuei 0:03b5121a232e 154 xmlFree(rep);
pcercuei 0:03b5121a232e 155 rep = NULL;
pcercuei 0:03b5121a232e 156 }
pcercuei 0:03b5121a232e 157 }
pcercuei 0:03b5121a232e 158 if (replacement != 0) {
pcercuei 0:03b5121a232e 159 if (replacement < XML_MAX_TEXT_LENGTH)
pcercuei 0:03b5121a232e 160 return(0);
pcercuei 0:03b5121a232e 161
pcercuei 0:03b5121a232e 162 /*
pcercuei 0:03b5121a232e 163 * If the volume of entity copy reaches 10 times the
pcercuei 0:03b5121a232e 164 * amount of parsed data and over the large text threshold
pcercuei 0:03b5121a232e 165 * then that's very likely to be an abuse.
pcercuei 0:03b5121a232e 166 */
pcercuei 0:03b5121a232e 167 if (ctxt->input != NULL) {
pcercuei 0:03b5121a232e 168 consumed = ctxt->input->consumed +
pcercuei 0:03b5121a232e 169 (ctxt->input->cur - ctxt->input->base);
pcercuei 0:03b5121a232e 170 }
pcercuei 0:03b5121a232e 171 consumed += ctxt->sizeentities;
pcercuei 0:03b5121a232e 172
pcercuei 0:03b5121a232e 173 if (replacement < XML_PARSER_NON_LINEAR * consumed)
pcercuei 0:03b5121a232e 174 return(0);
pcercuei 0:03b5121a232e 175 } else if (size != 0) {
pcercuei 0:03b5121a232e 176 /*
pcercuei 0:03b5121a232e 177 * Do the check based on the replacement size of the entity
pcercuei 0:03b5121a232e 178 */
pcercuei 0:03b5121a232e 179 if (size < XML_PARSER_BIG_ENTITY)
pcercuei 0:03b5121a232e 180 return(0);
pcercuei 0:03b5121a232e 181
pcercuei 0:03b5121a232e 182 /*
pcercuei 0:03b5121a232e 183 * A limit on the amount of text data reasonably used
pcercuei 0:03b5121a232e 184 */
pcercuei 0:03b5121a232e 185 if (ctxt->input != NULL) {
pcercuei 0:03b5121a232e 186 consumed = ctxt->input->consumed +
pcercuei 0:03b5121a232e 187 (ctxt->input->cur - ctxt->input->base);
pcercuei 0:03b5121a232e 188 }
pcercuei 0:03b5121a232e 189 consumed += ctxt->sizeentities;
pcercuei 0:03b5121a232e 190
pcercuei 0:03b5121a232e 191 if ((size < XML_PARSER_NON_LINEAR * consumed) &&
pcercuei 0:03b5121a232e 192 (ctxt->nbentities * 3 < XML_PARSER_NON_LINEAR * consumed))
pcercuei 0:03b5121a232e 193 return (0);
pcercuei 0:03b5121a232e 194 } else if (ent != NULL) {
pcercuei 0:03b5121a232e 195 /*
pcercuei 0:03b5121a232e 196 * use the number of parsed entities in the replacement
pcercuei 0:03b5121a232e 197 */
pcercuei 0:03b5121a232e 198 size = ent->checked / 2;
pcercuei 0:03b5121a232e 199
pcercuei 0:03b5121a232e 200 /*
pcercuei 0:03b5121a232e 201 * The amount of data parsed counting entities size only once
pcercuei 0:03b5121a232e 202 */
pcercuei 0:03b5121a232e 203 if (ctxt->input != NULL) {
pcercuei 0:03b5121a232e 204 consumed = ctxt->input->consumed +
pcercuei 0:03b5121a232e 205 (ctxt->input->cur - ctxt->input->base);
pcercuei 0:03b5121a232e 206 }
pcercuei 0:03b5121a232e 207 consumed += ctxt->sizeentities;
pcercuei 0:03b5121a232e 208
pcercuei 0:03b5121a232e 209 /*
pcercuei 0:03b5121a232e 210 * Check the density of entities for the amount of data
pcercuei 0:03b5121a232e 211 * knowing an entity reference will take at least 3 bytes
pcercuei 0:03b5121a232e 212 */
pcercuei 0:03b5121a232e 213 if (size * 3 < consumed * XML_PARSER_NON_LINEAR)
pcercuei 0:03b5121a232e 214 return (0);
pcercuei 0:03b5121a232e 215 } else {
pcercuei 0:03b5121a232e 216 /*
pcercuei 0:03b5121a232e 217 * strange we got no data for checking
pcercuei 0:03b5121a232e 218 */
pcercuei 0:03b5121a232e 219 if (((ctxt->lastError.code != XML_ERR_UNDECLARED_ENTITY) &&
pcercuei 0:03b5121a232e 220 (ctxt->lastError.code != XML_WAR_UNDECLARED_ENTITY)) ||
pcercuei 0:03b5121a232e 221 (ctxt->nbentities <= 10000))
pcercuei 0:03b5121a232e 222 return (0);
pcercuei 0:03b5121a232e 223 }
pcercuei 0:03b5121a232e 224 xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
pcercuei 0:03b5121a232e 225 return (1);
pcercuei 0:03b5121a232e 226 }
pcercuei 0:03b5121a232e 227
pcercuei 0:03b5121a232e 228 /**
pcercuei 0:03b5121a232e 229 * xmlParserMaxDepth:
pcercuei 0:03b5121a232e 230 *
pcercuei 0:03b5121a232e 231 * arbitrary depth limit for the XML documents that we allow to
pcercuei 0:03b5121a232e 232 * process. This is not a limitation of the parser but a safety
pcercuei 0:03b5121a232e 233 * boundary feature. It can be disabled with the XML_PARSE_HUGE
pcercuei 0:03b5121a232e 234 * parser option.
pcercuei 0:03b5121a232e 235 */
pcercuei 0:03b5121a232e 236 unsigned int xmlParserMaxDepth = 256;
pcercuei 0:03b5121a232e 237
pcercuei 0:03b5121a232e 238
pcercuei 0:03b5121a232e 239
pcercuei 0:03b5121a232e 240 #define SAX2 1
pcercuei 0:03b5121a232e 241 #define XML_PARSER_BIG_BUFFER_SIZE 300
pcercuei 0:03b5121a232e 242 #define XML_PARSER_BUFFER_SIZE 100
pcercuei 0:03b5121a232e 243 #define SAX_COMPAT_MODE BAD_CAST "SAX compatibility mode document"
pcercuei 0:03b5121a232e 244
pcercuei 0:03b5121a232e 245 /**
pcercuei 0:03b5121a232e 246 * XML_PARSER_CHUNK_SIZE
pcercuei 0:03b5121a232e 247 *
pcercuei 0:03b5121a232e 248 * When calling GROW that's the minimal amount of data
pcercuei 0:03b5121a232e 249 * the parser expected to have received. It is not a hard
pcercuei 0:03b5121a232e 250 * limit but an optimization when reading strings like Names
pcercuei 0:03b5121a232e 251 * It is not strictly needed as long as inputs available characters
pcercuei 0:03b5121a232e 252 * are followed by 0, which should be provided by the I/O level
pcercuei 0:03b5121a232e 253 */
pcercuei 0:03b5121a232e 254 #define XML_PARSER_CHUNK_SIZE 100
pcercuei 0:03b5121a232e 255
pcercuei 0:03b5121a232e 256 /*
pcercuei 0:03b5121a232e 257 * List of XML prefixed PI allowed by W3C specs
pcercuei 0:03b5121a232e 258 */
pcercuei 0:03b5121a232e 259
pcercuei 0:03b5121a232e 260 static const char *xmlW3CPIs[] = {
pcercuei 0:03b5121a232e 261 "xml-stylesheet",
pcercuei 0:03b5121a232e 262 "xml-model",
pcercuei 0:03b5121a232e 263 NULL
pcercuei 0:03b5121a232e 264 };
pcercuei 0:03b5121a232e 265
pcercuei 0:03b5121a232e 266
pcercuei 0:03b5121a232e 267 /* DEPR void xmlParserHandleReference(xmlParserCtxtPtr ctxt); */
pcercuei 0:03b5121a232e 268 static xmlEntityPtr xmlParseStringPEReference(xmlParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 269 const xmlChar **str);
pcercuei 0:03b5121a232e 270
pcercuei 0:03b5121a232e 271 static xmlParserErrors
pcercuei 0:03b5121a232e 272 xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
pcercuei 0:03b5121a232e 273 xmlSAXHandlerPtr sax,
pcercuei 0:03b5121a232e 274 void *user_data, int depth, const xmlChar *URL,
pcercuei 0:03b5121a232e 275 const xmlChar *ID, xmlNodePtr *list);
pcercuei 0:03b5121a232e 276
pcercuei 0:03b5121a232e 277 static int
pcercuei 0:03b5121a232e 278 xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options,
pcercuei 0:03b5121a232e 279 const char *encoding);
pcercuei 0:03b5121a232e 280 #ifdef LIBXML_LEGACY_ENABLED
pcercuei 0:03b5121a232e 281 static void
pcercuei 0:03b5121a232e 282 xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
pcercuei 0:03b5121a232e 283 xmlNodePtr lastNode);
pcercuei 0:03b5121a232e 284 #endif /* LIBXML_LEGACY_ENABLED */
pcercuei 0:03b5121a232e 285
pcercuei 0:03b5121a232e 286 static xmlParserErrors
pcercuei 0:03b5121a232e 287 xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
pcercuei 0:03b5121a232e 288 const xmlChar *string, void *user_data, xmlNodePtr *lst);
pcercuei 0:03b5121a232e 289
pcercuei 0:03b5121a232e 290 static int
pcercuei 0:03b5121a232e 291 xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity);
pcercuei 0:03b5121a232e 292
pcercuei 0:03b5121a232e 293 /************************************************************************
pcercuei 0:03b5121a232e 294 * *
pcercuei 0:03b5121a232e 295 * Some factorized error routines *
pcercuei 0:03b5121a232e 296 * *
pcercuei 0:03b5121a232e 297 ************************************************************************/
pcercuei 0:03b5121a232e 298
pcercuei 0:03b5121a232e 299 /**
pcercuei 0:03b5121a232e 300 * xmlErrAttributeDup:
pcercuei 0:03b5121a232e 301 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 302 * @prefix: the attribute prefix
pcercuei 0:03b5121a232e 303 * @localname: the attribute localname
pcercuei 0:03b5121a232e 304 *
pcercuei 0:03b5121a232e 305 * Handle a redefinition of attribute error
pcercuei 0:03b5121a232e 306 */
pcercuei 0:03b5121a232e 307 static void
pcercuei 0:03b5121a232e 308 xmlErrAttributeDup(xmlParserCtxtPtr ctxt, const xmlChar * prefix,
pcercuei 0:03b5121a232e 309 const xmlChar * localname)
pcercuei 0:03b5121a232e 310 {
pcercuei 0:03b5121a232e 311 if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
pcercuei 0:03b5121a232e 312 (ctxt->instate == XML_PARSER_EOF))
pcercuei 0:03b5121a232e 313 return;
pcercuei 0:03b5121a232e 314 if (ctxt != NULL)
pcercuei 0:03b5121a232e 315 ctxt->errNo = XML_ERR_ATTRIBUTE_REDEFINED;
pcercuei 0:03b5121a232e 316
pcercuei 0:03b5121a232e 317 if (prefix == NULL)
pcercuei 0:03b5121a232e 318 __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
pcercuei 0:03b5121a232e 319 XML_ERR_ATTRIBUTE_REDEFINED, XML_ERR_FATAL, NULL, 0,
pcercuei 0:03b5121a232e 320 (const char *) localname, NULL, NULL, 0, 0,
pcercuei 0:03b5121a232e 321 "Attribute %s redefined\n", localname);
pcercuei 0:03b5121a232e 322 else
pcercuei 0:03b5121a232e 323 __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
pcercuei 0:03b5121a232e 324 XML_ERR_ATTRIBUTE_REDEFINED, XML_ERR_FATAL, NULL, 0,
pcercuei 0:03b5121a232e 325 (const char *) prefix, (const char *) localname,
pcercuei 0:03b5121a232e 326 NULL, 0, 0, "Attribute %s:%s redefined\n", prefix,
pcercuei 0:03b5121a232e 327 localname);
pcercuei 0:03b5121a232e 328 if (ctxt != NULL) {
pcercuei 0:03b5121a232e 329 ctxt->wellFormed = 0;
pcercuei 0:03b5121a232e 330 if (ctxt->recovery == 0)
pcercuei 0:03b5121a232e 331 ctxt->disableSAX = 1;
pcercuei 0:03b5121a232e 332 }
pcercuei 0:03b5121a232e 333 }
pcercuei 0:03b5121a232e 334
pcercuei 0:03b5121a232e 335 /**
pcercuei 0:03b5121a232e 336 * xmlFatalErr:
pcercuei 0:03b5121a232e 337 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 338 * @error: the error number
pcercuei 0:03b5121a232e 339 * @extra: extra information string
pcercuei 0:03b5121a232e 340 *
pcercuei 0:03b5121a232e 341 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
pcercuei 0:03b5121a232e 342 */
pcercuei 0:03b5121a232e 343 static void
pcercuei 0:03b5121a232e 344 xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info)
pcercuei 0:03b5121a232e 345 {
pcercuei 0:03b5121a232e 346 const char *errmsg;
pcercuei 0:03b5121a232e 347 char errstr[129] = "";
pcercuei 0:03b5121a232e 348
pcercuei 0:03b5121a232e 349 if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
pcercuei 0:03b5121a232e 350 (ctxt->instate == XML_PARSER_EOF))
pcercuei 0:03b5121a232e 351 return;
pcercuei 0:03b5121a232e 352 switch (error) {
pcercuei 0:03b5121a232e 353 case XML_ERR_INVALID_HEX_CHARREF:
pcercuei 0:03b5121a232e 354 errmsg = "CharRef: invalid hexadecimal value";
pcercuei 0:03b5121a232e 355 break;
pcercuei 0:03b5121a232e 356 case XML_ERR_INVALID_DEC_CHARREF:
pcercuei 0:03b5121a232e 357 errmsg = "CharRef: invalid decimal value";
pcercuei 0:03b5121a232e 358 break;
pcercuei 0:03b5121a232e 359 case XML_ERR_INVALID_CHARREF:
pcercuei 0:03b5121a232e 360 errmsg = "CharRef: invalid value";
pcercuei 0:03b5121a232e 361 break;
pcercuei 0:03b5121a232e 362 case XML_ERR_INTERNAL_ERROR:
pcercuei 0:03b5121a232e 363 errmsg = "internal error";
pcercuei 0:03b5121a232e 364 break;
pcercuei 0:03b5121a232e 365 case XML_ERR_PEREF_AT_EOF:
pcercuei 0:03b5121a232e 366 errmsg = "PEReference at end of document";
pcercuei 0:03b5121a232e 367 break;
pcercuei 0:03b5121a232e 368 case XML_ERR_PEREF_IN_PROLOG:
pcercuei 0:03b5121a232e 369 errmsg = "PEReference in prolog";
pcercuei 0:03b5121a232e 370 break;
pcercuei 0:03b5121a232e 371 case XML_ERR_PEREF_IN_EPILOG:
pcercuei 0:03b5121a232e 372 errmsg = "PEReference in epilog";
pcercuei 0:03b5121a232e 373 break;
pcercuei 0:03b5121a232e 374 case XML_ERR_PEREF_NO_NAME:
pcercuei 0:03b5121a232e 375 errmsg = "PEReference: no name";
pcercuei 0:03b5121a232e 376 break;
pcercuei 0:03b5121a232e 377 case XML_ERR_PEREF_SEMICOL_MISSING:
pcercuei 0:03b5121a232e 378 errmsg = "PEReference: expecting ';'";
pcercuei 0:03b5121a232e 379 break;
pcercuei 0:03b5121a232e 380 case XML_ERR_ENTITY_LOOP:
pcercuei 0:03b5121a232e 381 errmsg = "Detected an entity reference loop";
pcercuei 0:03b5121a232e 382 break;
pcercuei 0:03b5121a232e 383 case XML_ERR_ENTITY_NOT_STARTED:
pcercuei 0:03b5121a232e 384 errmsg = "EntityValue: \" or ' expected";
pcercuei 0:03b5121a232e 385 break;
pcercuei 0:03b5121a232e 386 case XML_ERR_ENTITY_PE_INTERNAL:
pcercuei 0:03b5121a232e 387 errmsg = "PEReferences forbidden in internal subset";
pcercuei 0:03b5121a232e 388 break;
pcercuei 0:03b5121a232e 389 case XML_ERR_ENTITY_NOT_FINISHED:
pcercuei 0:03b5121a232e 390 errmsg = "EntityValue: \" or ' expected";
pcercuei 0:03b5121a232e 391 break;
pcercuei 0:03b5121a232e 392 case XML_ERR_ATTRIBUTE_NOT_STARTED:
pcercuei 0:03b5121a232e 393 errmsg = "AttValue: \" or ' expected";
pcercuei 0:03b5121a232e 394 break;
pcercuei 0:03b5121a232e 395 case XML_ERR_LT_IN_ATTRIBUTE:
pcercuei 0:03b5121a232e 396 errmsg = "Unescaped '<' not allowed in attributes values";
pcercuei 0:03b5121a232e 397 break;
pcercuei 0:03b5121a232e 398 case XML_ERR_LITERAL_NOT_STARTED:
pcercuei 0:03b5121a232e 399 errmsg = "SystemLiteral \" or ' expected";
pcercuei 0:03b5121a232e 400 break;
pcercuei 0:03b5121a232e 401 case XML_ERR_LITERAL_NOT_FINISHED:
pcercuei 0:03b5121a232e 402 errmsg = "Unfinished System or Public ID \" or ' expected";
pcercuei 0:03b5121a232e 403 break;
pcercuei 0:03b5121a232e 404 case XML_ERR_MISPLACED_CDATA_END:
pcercuei 0:03b5121a232e 405 errmsg = "Sequence ']]>' not allowed in content";
pcercuei 0:03b5121a232e 406 break;
pcercuei 0:03b5121a232e 407 case XML_ERR_URI_REQUIRED:
pcercuei 0:03b5121a232e 408 errmsg = "SYSTEM or PUBLIC, the URI is missing";
pcercuei 0:03b5121a232e 409 break;
pcercuei 0:03b5121a232e 410 case XML_ERR_PUBID_REQUIRED:
pcercuei 0:03b5121a232e 411 errmsg = "PUBLIC, the Public Identifier is missing";
pcercuei 0:03b5121a232e 412 break;
pcercuei 0:03b5121a232e 413 case XML_ERR_HYPHEN_IN_COMMENT:
pcercuei 0:03b5121a232e 414 errmsg = "Comment must not contain '--' (double-hyphen)";
pcercuei 0:03b5121a232e 415 break;
pcercuei 0:03b5121a232e 416 case XML_ERR_PI_NOT_STARTED:
pcercuei 0:03b5121a232e 417 errmsg = "xmlParsePI : no target name";
pcercuei 0:03b5121a232e 418 break;
pcercuei 0:03b5121a232e 419 case XML_ERR_RESERVED_XML_NAME:
pcercuei 0:03b5121a232e 420 errmsg = "Invalid PI name";
pcercuei 0:03b5121a232e 421 break;
pcercuei 0:03b5121a232e 422 case XML_ERR_NOTATION_NOT_STARTED:
pcercuei 0:03b5121a232e 423 errmsg = "NOTATION: Name expected here";
pcercuei 0:03b5121a232e 424 break;
pcercuei 0:03b5121a232e 425 case XML_ERR_NOTATION_NOT_FINISHED:
pcercuei 0:03b5121a232e 426 errmsg = "'>' required to close NOTATION declaration";
pcercuei 0:03b5121a232e 427 break;
pcercuei 0:03b5121a232e 428 case XML_ERR_VALUE_REQUIRED:
pcercuei 0:03b5121a232e 429 errmsg = "Entity value required";
pcercuei 0:03b5121a232e 430 break;
pcercuei 0:03b5121a232e 431 case XML_ERR_URI_FRAGMENT:
pcercuei 0:03b5121a232e 432 errmsg = "Fragment not allowed";
pcercuei 0:03b5121a232e 433 break;
pcercuei 0:03b5121a232e 434 case XML_ERR_ATTLIST_NOT_STARTED:
pcercuei 0:03b5121a232e 435 errmsg = "'(' required to start ATTLIST enumeration";
pcercuei 0:03b5121a232e 436 break;
pcercuei 0:03b5121a232e 437 case XML_ERR_NMTOKEN_REQUIRED:
pcercuei 0:03b5121a232e 438 errmsg = "NmToken expected in ATTLIST enumeration";
pcercuei 0:03b5121a232e 439 break;
pcercuei 0:03b5121a232e 440 case XML_ERR_ATTLIST_NOT_FINISHED:
pcercuei 0:03b5121a232e 441 errmsg = "')' required to finish ATTLIST enumeration";
pcercuei 0:03b5121a232e 442 break;
pcercuei 0:03b5121a232e 443 case XML_ERR_MIXED_NOT_STARTED:
pcercuei 0:03b5121a232e 444 errmsg = "MixedContentDecl : '|' or ')*' expected";
pcercuei 0:03b5121a232e 445 break;
pcercuei 0:03b5121a232e 446 case XML_ERR_PCDATA_REQUIRED:
pcercuei 0:03b5121a232e 447 errmsg = "MixedContentDecl : '#PCDATA' expected";
pcercuei 0:03b5121a232e 448 break;
pcercuei 0:03b5121a232e 449 case XML_ERR_ELEMCONTENT_NOT_STARTED:
pcercuei 0:03b5121a232e 450 errmsg = "ContentDecl : Name or '(' expected";
pcercuei 0:03b5121a232e 451 break;
pcercuei 0:03b5121a232e 452 case XML_ERR_ELEMCONTENT_NOT_FINISHED:
pcercuei 0:03b5121a232e 453 errmsg = "ContentDecl : ',' '|' or ')' expected";
pcercuei 0:03b5121a232e 454 break;
pcercuei 0:03b5121a232e 455 case XML_ERR_PEREF_IN_INT_SUBSET:
pcercuei 0:03b5121a232e 456 errmsg =
pcercuei 0:03b5121a232e 457 "PEReference: forbidden within markup decl in internal subset";
pcercuei 0:03b5121a232e 458 break;
pcercuei 0:03b5121a232e 459 case XML_ERR_GT_REQUIRED:
pcercuei 0:03b5121a232e 460 errmsg = "expected '>'";
pcercuei 0:03b5121a232e 461 break;
pcercuei 0:03b5121a232e 462 case XML_ERR_CONDSEC_INVALID:
pcercuei 0:03b5121a232e 463 errmsg = "XML conditional section '[' expected";
pcercuei 0:03b5121a232e 464 break;
pcercuei 0:03b5121a232e 465 case XML_ERR_EXT_SUBSET_NOT_FINISHED:
pcercuei 0:03b5121a232e 466 errmsg = "Content error in the external subset";
pcercuei 0:03b5121a232e 467 break;
pcercuei 0:03b5121a232e 468 case XML_ERR_CONDSEC_INVALID_KEYWORD:
pcercuei 0:03b5121a232e 469 errmsg =
pcercuei 0:03b5121a232e 470 "conditional section INCLUDE or IGNORE keyword expected";
pcercuei 0:03b5121a232e 471 break;
pcercuei 0:03b5121a232e 472 case XML_ERR_CONDSEC_NOT_FINISHED:
pcercuei 0:03b5121a232e 473 errmsg = "XML conditional section not closed";
pcercuei 0:03b5121a232e 474 break;
pcercuei 0:03b5121a232e 475 case XML_ERR_XMLDECL_NOT_STARTED:
pcercuei 0:03b5121a232e 476 errmsg = "Text declaration '<?xml' required";
pcercuei 0:03b5121a232e 477 break;
pcercuei 0:03b5121a232e 478 case XML_ERR_XMLDECL_NOT_FINISHED:
pcercuei 0:03b5121a232e 479 errmsg = "parsing XML declaration: '?>' expected";
pcercuei 0:03b5121a232e 480 break;
pcercuei 0:03b5121a232e 481 case XML_ERR_EXT_ENTITY_STANDALONE:
pcercuei 0:03b5121a232e 482 errmsg = "external parsed entities cannot be standalone";
pcercuei 0:03b5121a232e 483 break;
pcercuei 0:03b5121a232e 484 case XML_ERR_ENTITYREF_SEMICOL_MISSING:
pcercuei 0:03b5121a232e 485 errmsg = "EntityRef: expecting ';'";
pcercuei 0:03b5121a232e 486 break;
pcercuei 0:03b5121a232e 487 case XML_ERR_DOCTYPE_NOT_FINISHED:
pcercuei 0:03b5121a232e 488 errmsg = "DOCTYPE improperly terminated";
pcercuei 0:03b5121a232e 489 break;
pcercuei 0:03b5121a232e 490 case XML_ERR_LTSLASH_REQUIRED:
pcercuei 0:03b5121a232e 491 errmsg = "EndTag: '</' not found";
pcercuei 0:03b5121a232e 492 break;
pcercuei 0:03b5121a232e 493 case XML_ERR_EQUAL_REQUIRED:
pcercuei 0:03b5121a232e 494 errmsg = "expected '='";
pcercuei 0:03b5121a232e 495 break;
pcercuei 0:03b5121a232e 496 case XML_ERR_STRING_NOT_CLOSED:
pcercuei 0:03b5121a232e 497 errmsg = "String not closed expecting \" or '";
pcercuei 0:03b5121a232e 498 break;
pcercuei 0:03b5121a232e 499 case XML_ERR_STRING_NOT_STARTED:
pcercuei 0:03b5121a232e 500 errmsg = "String not started expecting ' or \"";
pcercuei 0:03b5121a232e 501 break;
pcercuei 0:03b5121a232e 502 case XML_ERR_ENCODING_NAME:
pcercuei 0:03b5121a232e 503 errmsg = "Invalid XML encoding name";
pcercuei 0:03b5121a232e 504 break;
pcercuei 0:03b5121a232e 505 case XML_ERR_STANDALONE_VALUE:
pcercuei 0:03b5121a232e 506 errmsg = "standalone accepts only 'yes' or 'no'";
pcercuei 0:03b5121a232e 507 break;
pcercuei 0:03b5121a232e 508 case XML_ERR_DOCUMENT_EMPTY:
pcercuei 0:03b5121a232e 509 errmsg = "Document is empty";
pcercuei 0:03b5121a232e 510 break;
pcercuei 0:03b5121a232e 511 case XML_ERR_DOCUMENT_END:
pcercuei 0:03b5121a232e 512 errmsg = "Extra content at the end of the document";
pcercuei 0:03b5121a232e 513 break;
pcercuei 0:03b5121a232e 514 case XML_ERR_NOT_WELL_BALANCED:
pcercuei 0:03b5121a232e 515 errmsg = "chunk is not well balanced";
pcercuei 0:03b5121a232e 516 break;
pcercuei 0:03b5121a232e 517 case XML_ERR_EXTRA_CONTENT:
pcercuei 0:03b5121a232e 518 errmsg = "extra content at the end of well balanced chunk";
pcercuei 0:03b5121a232e 519 break;
pcercuei 0:03b5121a232e 520 case XML_ERR_VERSION_MISSING:
pcercuei 0:03b5121a232e 521 errmsg = "Malformed declaration expecting version";
pcercuei 0:03b5121a232e 522 break;
pcercuei 0:03b5121a232e 523 case XML_ERR_NAME_TOO_LONG:
pcercuei 0:03b5121a232e 524 errmsg = "Name too long use XML_PARSE_HUGE option";
pcercuei 0:03b5121a232e 525 break;
pcercuei 0:03b5121a232e 526 #if 0
pcercuei 0:03b5121a232e 527 case:
pcercuei 0:03b5121a232e 528 errmsg = "";
pcercuei 0:03b5121a232e 529 break;
pcercuei 0:03b5121a232e 530 #endif
pcercuei 0:03b5121a232e 531 default:
pcercuei 0:03b5121a232e 532 errmsg = "Unregistered error message";
pcercuei 0:03b5121a232e 533 }
pcercuei 0:03b5121a232e 534 if (info == NULL)
pcercuei 0:03b5121a232e 535 snprintf(errstr, 128, "%s\n", errmsg);
pcercuei 0:03b5121a232e 536 else
pcercuei 0:03b5121a232e 537 snprintf(errstr, 128, "%s: %%s\n", errmsg);
pcercuei 0:03b5121a232e 538 if (ctxt != NULL)
pcercuei 0:03b5121a232e 539 ctxt->errNo = error;
pcercuei 0:03b5121a232e 540 __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
pcercuei 0:03b5121a232e 541 XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, &errstr[0],
pcercuei 0:03b5121a232e 542 info);
pcercuei 0:03b5121a232e 543 if (ctxt != NULL) {
pcercuei 0:03b5121a232e 544 ctxt->wellFormed = 0;
pcercuei 0:03b5121a232e 545 if (ctxt->recovery == 0)
pcercuei 0:03b5121a232e 546 ctxt->disableSAX = 1;
pcercuei 0:03b5121a232e 547 }
pcercuei 0:03b5121a232e 548 }
pcercuei 0:03b5121a232e 549
pcercuei 0:03b5121a232e 550 /**
pcercuei 0:03b5121a232e 551 * xmlFatalErrMsg:
pcercuei 0:03b5121a232e 552 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 553 * @error: the error number
pcercuei 0:03b5121a232e 554 * @msg: the error message
pcercuei 0:03b5121a232e 555 *
pcercuei 0:03b5121a232e 556 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
pcercuei 0:03b5121a232e 557 */
pcercuei 0:03b5121a232e 558 static void
pcercuei 0:03b5121a232e 559 xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
pcercuei 0:03b5121a232e 560 const char *msg)
pcercuei 0:03b5121a232e 561 {
pcercuei 0:03b5121a232e 562 if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
pcercuei 0:03b5121a232e 563 (ctxt->instate == XML_PARSER_EOF))
pcercuei 0:03b5121a232e 564 return;
pcercuei 0:03b5121a232e 565 if (ctxt != NULL)
pcercuei 0:03b5121a232e 566 ctxt->errNo = error;
pcercuei 0:03b5121a232e 567 __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
pcercuei 0:03b5121a232e 568 XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg);
pcercuei 0:03b5121a232e 569 if (ctxt != NULL) {
pcercuei 0:03b5121a232e 570 ctxt->wellFormed = 0;
pcercuei 0:03b5121a232e 571 if (ctxt->recovery == 0)
pcercuei 0:03b5121a232e 572 ctxt->disableSAX = 1;
pcercuei 0:03b5121a232e 573 }
pcercuei 0:03b5121a232e 574 }
pcercuei 0:03b5121a232e 575
pcercuei 0:03b5121a232e 576 /**
pcercuei 0:03b5121a232e 577 * xmlWarningMsg:
pcercuei 0:03b5121a232e 578 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 579 * @error: the error number
pcercuei 0:03b5121a232e 580 * @msg: the error message
pcercuei 0:03b5121a232e 581 * @str1: extra data
pcercuei 0:03b5121a232e 582 * @str2: extra data
pcercuei 0:03b5121a232e 583 *
pcercuei 0:03b5121a232e 584 * Handle a warning.
pcercuei 0:03b5121a232e 585 */
pcercuei 0:03b5121a232e 586 static void
pcercuei 0:03b5121a232e 587 xmlWarningMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
pcercuei 0:03b5121a232e 588 const char *msg, const xmlChar *str1, const xmlChar *str2)
pcercuei 0:03b5121a232e 589 {
pcercuei 0:03b5121a232e 590 xmlStructuredErrorFunc schannel = NULL;
pcercuei 0:03b5121a232e 591
pcercuei 0:03b5121a232e 592 if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
pcercuei 0:03b5121a232e 593 (ctxt->instate == XML_PARSER_EOF))
pcercuei 0:03b5121a232e 594 return;
pcercuei 0:03b5121a232e 595 if ((ctxt != NULL) && (ctxt->sax != NULL) &&
pcercuei 0:03b5121a232e 596 (ctxt->sax->initialized == XML_SAX2_MAGIC))
pcercuei 0:03b5121a232e 597 schannel = ctxt->sax->serror;
pcercuei 0:03b5121a232e 598 if (ctxt != NULL) {
pcercuei 0:03b5121a232e 599 __xmlRaiseError(schannel,
pcercuei 0:03b5121a232e 600 (ctxt->sax) ? ctxt->sax->warning : NULL,
pcercuei 0:03b5121a232e 601 ctxt->userData,
pcercuei 0:03b5121a232e 602 ctxt, NULL, XML_FROM_PARSER, error,
pcercuei 0:03b5121a232e 603 XML_ERR_WARNING, NULL, 0,
pcercuei 0:03b5121a232e 604 (const char *) str1, (const char *) str2, NULL, 0, 0,
pcercuei 0:03b5121a232e 605 msg, (const char *) str1, (const char *) str2);
pcercuei 0:03b5121a232e 606 } else {
pcercuei 0:03b5121a232e 607 __xmlRaiseError(schannel, NULL, NULL,
pcercuei 0:03b5121a232e 608 ctxt, NULL, XML_FROM_PARSER, error,
pcercuei 0:03b5121a232e 609 XML_ERR_WARNING, NULL, 0,
pcercuei 0:03b5121a232e 610 (const char *) str1, (const char *) str2, NULL, 0, 0,
pcercuei 0:03b5121a232e 611 msg, (const char *) str1, (const char *) str2);
pcercuei 0:03b5121a232e 612 }
pcercuei 0:03b5121a232e 613 }
pcercuei 0:03b5121a232e 614
pcercuei 0:03b5121a232e 615 /**
pcercuei 0:03b5121a232e 616 * xmlValidityError:
pcercuei 0:03b5121a232e 617 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 618 * @error: the error number
pcercuei 0:03b5121a232e 619 * @msg: the error message
pcercuei 0:03b5121a232e 620 * @str1: extra data
pcercuei 0:03b5121a232e 621 *
pcercuei 0:03b5121a232e 622 * Handle a validity error.
pcercuei 0:03b5121a232e 623 */
pcercuei 0:03b5121a232e 624 static void
pcercuei 0:03b5121a232e 625 xmlValidityError(xmlParserCtxtPtr ctxt, xmlParserErrors error,
pcercuei 0:03b5121a232e 626 const char *msg, const xmlChar *str1, const xmlChar *str2)
pcercuei 0:03b5121a232e 627 {
pcercuei 0:03b5121a232e 628 xmlStructuredErrorFunc schannel = NULL;
pcercuei 0:03b5121a232e 629
pcercuei 0:03b5121a232e 630 if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
pcercuei 0:03b5121a232e 631 (ctxt->instate == XML_PARSER_EOF))
pcercuei 0:03b5121a232e 632 return;
pcercuei 0:03b5121a232e 633 if (ctxt != NULL) {
pcercuei 0:03b5121a232e 634 ctxt->errNo = error;
pcercuei 0:03b5121a232e 635 if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
pcercuei 0:03b5121a232e 636 schannel = ctxt->sax->serror;
pcercuei 0:03b5121a232e 637 }
pcercuei 0:03b5121a232e 638 if (ctxt != NULL) {
pcercuei 0:03b5121a232e 639 __xmlRaiseError(schannel,
pcercuei 0:03b5121a232e 640 ctxt->vctxt.error, ctxt->vctxt.userData,
pcercuei 0:03b5121a232e 641 ctxt, NULL, XML_FROM_DTD, error,
pcercuei 0:03b5121a232e 642 XML_ERR_ERROR, NULL, 0, (const char *) str1,
pcercuei 0:03b5121a232e 643 (const char *) str2, NULL, 0, 0,
pcercuei 0:03b5121a232e 644 msg, (const char *) str1, (const char *) str2);
pcercuei 0:03b5121a232e 645 ctxt->valid = 0;
pcercuei 0:03b5121a232e 646 } else {
pcercuei 0:03b5121a232e 647 __xmlRaiseError(schannel, NULL, NULL,
pcercuei 0:03b5121a232e 648 ctxt, NULL, XML_FROM_DTD, error,
pcercuei 0:03b5121a232e 649 XML_ERR_ERROR, NULL, 0, (const char *) str1,
pcercuei 0:03b5121a232e 650 (const char *) str2, NULL, 0, 0,
pcercuei 0:03b5121a232e 651 msg, (const char *) str1, (const char *) str2);
pcercuei 0:03b5121a232e 652 }
pcercuei 0:03b5121a232e 653 }
pcercuei 0:03b5121a232e 654
pcercuei 0:03b5121a232e 655 /**
pcercuei 0:03b5121a232e 656 * xmlFatalErrMsgInt:
pcercuei 0:03b5121a232e 657 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 658 * @error: the error number
pcercuei 0:03b5121a232e 659 * @msg: the error message
pcercuei 0:03b5121a232e 660 * @val: an integer value
pcercuei 0:03b5121a232e 661 *
pcercuei 0:03b5121a232e 662 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
pcercuei 0:03b5121a232e 663 */
pcercuei 0:03b5121a232e 664 static void
pcercuei 0:03b5121a232e 665 xmlFatalErrMsgInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
pcercuei 0:03b5121a232e 666 const char *msg, int val)
pcercuei 0:03b5121a232e 667 {
pcercuei 0:03b5121a232e 668 if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
pcercuei 0:03b5121a232e 669 (ctxt->instate == XML_PARSER_EOF))
pcercuei 0:03b5121a232e 670 return;
pcercuei 0:03b5121a232e 671 if (ctxt != NULL)
pcercuei 0:03b5121a232e 672 ctxt->errNo = error;
pcercuei 0:03b5121a232e 673 __xmlRaiseError(NULL, NULL, NULL,
pcercuei 0:03b5121a232e 674 ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
pcercuei 0:03b5121a232e 675 NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
pcercuei 0:03b5121a232e 676 if (ctxt != NULL) {
pcercuei 0:03b5121a232e 677 ctxt->wellFormed = 0;
pcercuei 0:03b5121a232e 678 if (ctxt->recovery == 0)
pcercuei 0:03b5121a232e 679 ctxt->disableSAX = 1;
pcercuei 0:03b5121a232e 680 }
pcercuei 0:03b5121a232e 681 }
pcercuei 0:03b5121a232e 682
pcercuei 0:03b5121a232e 683 /**
pcercuei 0:03b5121a232e 684 * xmlFatalErrMsgStrIntStr:
pcercuei 0:03b5121a232e 685 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 686 * @error: the error number
pcercuei 0:03b5121a232e 687 * @msg: the error message
pcercuei 0:03b5121a232e 688 * @str1: an string info
pcercuei 0:03b5121a232e 689 * @val: an integer value
pcercuei 0:03b5121a232e 690 * @str2: an string info
pcercuei 0:03b5121a232e 691 *
pcercuei 0:03b5121a232e 692 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
pcercuei 0:03b5121a232e 693 */
pcercuei 0:03b5121a232e 694 static void
pcercuei 0:03b5121a232e 695 xmlFatalErrMsgStrIntStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
pcercuei 0:03b5121a232e 696 const char *msg, const xmlChar *str1, int val,
pcercuei 0:03b5121a232e 697 const xmlChar *str2)
pcercuei 0:03b5121a232e 698 {
pcercuei 0:03b5121a232e 699 if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
pcercuei 0:03b5121a232e 700 (ctxt->instate == XML_PARSER_EOF))
pcercuei 0:03b5121a232e 701 return;
pcercuei 0:03b5121a232e 702 if (ctxt != NULL)
pcercuei 0:03b5121a232e 703 ctxt->errNo = error;
pcercuei 0:03b5121a232e 704 __xmlRaiseError(NULL, NULL, NULL,
pcercuei 0:03b5121a232e 705 ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
pcercuei 0:03b5121a232e 706 NULL, 0, (const char *) str1, (const char *) str2,
pcercuei 0:03b5121a232e 707 NULL, val, 0, msg, str1, val, str2);
pcercuei 0:03b5121a232e 708 if (ctxt != NULL) {
pcercuei 0:03b5121a232e 709 ctxt->wellFormed = 0;
pcercuei 0:03b5121a232e 710 if (ctxt->recovery == 0)
pcercuei 0:03b5121a232e 711 ctxt->disableSAX = 1;
pcercuei 0:03b5121a232e 712 }
pcercuei 0:03b5121a232e 713 }
pcercuei 0:03b5121a232e 714
pcercuei 0:03b5121a232e 715 /**
pcercuei 0:03b5121a232e 716 * xmlFatalErrMsgStr:
pcercuei 0:03b5121a232e 717 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 718 * @error: the error number
pcercuei 0:03b5121a232e 719 * @msg: the error message
pcercuei 0:03b5121a232e 720 * @val: a string value
pcercuei 0:03b5121a232e 721 *
pcercuei 0:03b5121a232e 722 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
pcercuei 0:03b5121a232e 723 */
pcercuei 0:03b5121a232e 724 static void
pcercuei 0:03b5121a232e 725 xmlFatalErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
pcercuei 0:03b5121a232e 726 const char *msg, const xmlChar * val)
pcercuei 0:03b5121a232e 727 {
pcercuei 0:03b5121a232e 728 if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
pcercuei 0:03b5121a232e 729 (ctxt->instate == XML_PARSER_EOF))
pcercuei 0:03b5121a232e 730 return;
pcercuei 0:03b5121a232e 731 if (ctxt != NULL)
pcercuei 0:03b5121a232e 732 ctxt->errNo = error;
pcercuei 0:03b5121a232e 733 __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL,
pcercuei 0:03b5121a232e 734 XML_FROM_PARSER, error, XML_ERR_FATAL,
pcercuei 0:03b5121a232e 735 NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
pcercuei 0:03b5121a232e 736 val);
pcercuei 0:03b5121a232e 737 if (ctxt != NULL) {
pcercuei 0:03b5121a232e 738 ctxt->wellFormed = 0;
pcercuei 0:03b5121a232e 739 if (ctxt->recovery == 0)
pcercuei 0:03b5121a232e 740 ctxt->disableSAX = 1;
pcercuei 0:03b5121a232e 741 }
pcercuei 0:03b5121a232e 742 }
pcercuei 0:03b5121a232e 743
pcercuei 0:03b5121a232e 744 /**
pcercuei 0:03b5121a232e 745 * xmlErrMsgStr:
pcercuei 0:03b5121a232e 746 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 747 * @error: the error number
pcercuei 0:03b5121a232e 748 * @msg: the error message
pcercuei 0:03b5121a232e 749 * @val: a string value
pcercuei 0:03b5121a232e 750 *
pcercuei 0:03b5121a232e 751 * Handle a non fatal parser error
pcercuei 0:03b5121a232e 752 */
pcercuei 0:03b5121a232e 753 static void
pcercuei 0:03b5121a232e 754 xmlErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
pcercuei 0:03b5121a232e 755 const char *msg, const xmlChar * val)
pcercuei 0:03b5121a232e 756 {
pcercuei 0:03b5121a232e 757 if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
pcercuei 0:03b5121a232e 758 (ctxt->instate == XML_PARSER_EOF))
pcercuei 0:03b5121a232e 759 return;
pcercuei 0:03b5121a232e 760 if (ctxt != NULL)
pcercuei 0:03b5121a232e 761 ctxt->errNo = error;
pcercuei 0:03b5121a232e 762 __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL,
pcercuei 0:03b5121a232e 763 XML_FROM_PARSER, error, XML_ERR_ERROR,
pcercuei 0:03b5121a232e 764 NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
pcercuei 0:03b5121a232e 765 val);
pcercuei 0:03b5121a232e 766 }
pcercuei 0:03b5121a232e 767
pcercuei 0:03b5121a232e 768 /**
pcercuei 0:03b5121a232e 769 * xmlNsErr:
pcercuei 0:03b5121a232e 770 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 771 * @error: the error number
pcercuei 0:03b5121a232e 772 * @msg: the message
pcercuei 0:03b5121a232e 773 * @info1: extra information string
pcercuei 0:03b5121a232e 774 * @info2: extra information string
pcercuei 0:03b5121a232e 775 *
pcercuei 0:03b5121a232e 776 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
pcercuei 0:03b5121a232e 777 */
pcercuei 0:03b5121a232e 778 static void
pcercuei 0:03b5121a232e 779 xmlNsErr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
pcercuei 0:03b5121a232e 780 const char *msg,
pcercuei 0:03b5121a232e 781 const xmlChar * info1, const xmlChar * info2,
pcercuei 0:03b5121a232e 782 const xmlChar * info3)
pcercuei 0:03b5121a232e 783 {
pcercuei 0:03b5121a232e 784 if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
pcercuei 0:03b5121a232e 785 (ctxt->instate == XML_PARSER_EOF))
pcercuei 0:03b5121a232e 786 return;
pcercuei 0:03b5121a232e 787 if (ctxt != NULL)
pcercuei 0:03b5121a232e 788 ctxt->errNo = error;
pcercuei 0:03b5121a232e 789 __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
pcercuei 0:03b5121a232e 790 XML_ERR_ERROR, NULL, 0, (const char *) info1,
pcercuei 0:03b5121a232e 791 (const char *) info2, (const char *) info3, 0, 0, msg,
pcercuei 0:03b5121a232e 792 info1, info2, info3);
pcercuei 0:03b5121a232e 793 if (ctxt != NULL)
pcercuei 0:03b5121a232e 794 ctxt->nsWellFormed = 0;
pcercuei 0:03b5121a232e 795 }
pcercuei 0:03b5121a232e 796
pcercuei 0:03b5121a232e 797 /**
pcercuei 0:03b5121a232e 798 * xmlNsWarn
pcercuei 0:03b5121a232e 799 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 800 * @error: the error number
pcercuei 0:03b5121a232e 801 * @msg: the message
pcercuei 0:03b5121a232e 802 * @info1: extra information string
pcercuei 0:03b5121a232e 803 * @info2: extra information string
pcercuei 0:03b5121a232e 804 *
pcercuei 0:03b5121a232e 805 * Handle a namespace warning error
pcercuei 0:03b5121a232e 806 */
pcercuei 0:03b5121a232e 807 static void
pcercuei 0:03b5121a232e 808 xmlNsWarn(xmlParserCtxtPtr ctxt, xmlParserErrors error,
pcercuei 0:03b5121a232e 809 const char *msg,
pcercuei 0:03b5121a232e 810 const xmlChar * info1, const xmlChar * info2,
pcercuei 0:03b5121a232e 811 const xmlChar * info3)
pcercuei 0:03b5121a232e 812 {
pcercuei 0:03b5121a232e 813 if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
pcercuei 0:03b5121a232e 814 (ctxt->instate == XML_PARSER_EOF))
pcercuei 0:03b5121a232e 815 return;
pcercuei 0:03b5121a232e 816 __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
pcercuei 0:03b5121a232e 817 XML_ERR_WARNING, NULL, 0, (const char *) info1,
pcercuei 0:03b5121a232e 818 (const char *) info2, (const char *) info3, 0, 0, msg,
pcercuei 0:03b5121a232e 819 info1, info2, info3);
pcercuei 0:03b5121a232e 820 }
pcercuei 0:03b5121a232e 821
pcercuei 0:03b5121a232e 822 /************************************************************************
pcercuei 0:03b5121a232e 823 * *
pcercuei 0:03b5121a232e 824 * Library wide options *
pcercuei 0:03b5121a232e 825 * *
pcercuei 0:03b5121a232e 826 ************************************************************************/
pcercuei 0:03b5121a232e 827
pcercuei 0:03b5121a232e 828 /**
pcercuei 0:03b5121a232e 829 * xmlHasFeature:
pcercuei 0:03b5121a232e 830 * @feature: the feature to be examined
pcercuei 0:03b5121a232e 831 *
pcercuei 0:03b5121a232e 832 * Examines if the library has been compiled with a given feature.
pcercuei 0:03b5121a232e 833 *
pcercuei 0:03b5121a232e 834 * Returns a non-zero value if the feature exist, otherwise zero.
pcercuei 0:03b5121a232e 835 * Returns zero (0) if the feature does not exist or an unknown
pcercuei 0:03b5121a232e 836 * unknown feature is requested, non-zero otherwise.
pcercuei 0:03b5121a232e 837 */
pcercuei 0:03b5121a232e 838 int
pcercuei 0:03b5121a232e 839 xmlHasFeature(xmlFeature feature)
pcercuei 0:03b5121a232e 840 {
pcercuei 0:03b5121a232e 841 switch (feature) {
pcercuei 0:03b5121a232e 842 case XML_WITH_THREAD:
pcercuei 0:03b5121a232e 843 #ifdef LIBXML_THREAD_ENABLED
pcercuei 0:03b5121a232e 844 return(1);
pcercuei 0:03b5121a232e 845 #else
pcercuei 0:03b5121a232e 846 return(0);
pcercuei 0:03b5121a232e 847 #endif
pcercuei 0:03b5121a232e 848 case XML_WITH_TREE:
pcercuei 0:03b5121a232e 849 #ifdef LIBXML_TREE_ENABLED
pcercuei 0:03b5121a232e 850 return(1);
pcercuei 0:03b5121a232e 851 #else
pcercuei 0:03b5121a232e 852 return(0);
pcercuei 0:03b5121a232e 853 #endif
pcercuei 0:03b5121a232e 854 case XML_WITH_OUTPUT:
pcercuei 0:03b5121a232e 855 #ifdef LIBXML_OUTPUT_ENABLED
pcercuei 0:03b5121a232e 856 return(1);
pcercuei 0:03b5121a232e 857 #else
pcercuei 0:03b5121a232e 858 return(0);
pcercuei 0:03b5121a232e 859 #endif
pcercuei 0:03b5121a232e 860 case XML_WITH_PUSH:
pcercuei 0:03b5121a232e 861 #ifdef LIBXML_PUSH_ENABLED
pcercuei 0:03b5121a232e 862 return(1);
pcercuei 0:03b5121a232e 863 #else
pcercuei 0:03b5121a232e 864 return(0);
pcercuei 0:03b5121a232e 865 #endif
pcercuei 0:03b5121a232e 866 case XML_WITH_READER:
pcercuei 0:03b5121a232e 867 #ifdef LIBXML_READER_ENABLED
pcercuei 0:03b5121a232e 868 return(1);
pcercuei 0:03b5121a232e 869 #else
pcercuei 0:03b5121a232e 870 return(0);
pcercuei 0:03b5121a232e 871 #endif
pcercuei 0:03b5121a232e 872 case XML_WITH_PATTERN:
pcercuei 0:03b5121a232e 873 #ifdef LIBXML_PATTERN_ENABLED
pcercuei 0:03b5121a232e 874 return(1);
pcercuei 0:03b5121a232e 875 #else
pcercuei 0:03b5121a232e 876 return(0);
pcercuei 0:03b5121a232e 877 #endif
pcercuei 0:03b5121a232e 878 case XML_WITH_WRITER:
pcercuei 0:03b5121a232e 879 #ifdef LIBXML_WRITER_ENABLED
pcercuei 0:03b5121a232e 880 return(1);
pcercuei 0:03b5121a232e 881 #else
pcercuei 0:03b5121a232e 882 return(0);
pcercuei 0:03b5121a232e 883 #endif
pcercuei 0:03b5121a232e 884 case XML_WITH_SAX1:
pcercuei 0:03b5121a232e 885 #ifdef LIBXML_SAX1_ENABLED
pcercuei 0:03b5121a232e 886 return(1);
pcercuei 0:03b5121a232e 887 #else
pcercuei 0:03b5121a232e 888 return(0);
pcercuei 0:03b5121a232e 889 #endif
pcercuei 0:03b5121a232e 890 case XML_WITH_FTP:
pcercuei 0:03b5121a232e 891 #ifdef LIBXML_FTP_ENABLED
pcercuei 0:03b5121a232e 892 return(1);
pcercuei 0:03b5121a232e 893 #else
pcercuei 0:03b5121a232e 894 return(0);
pcercuei 0:03b5121a232e 895 #endif
pcercuei 0:03b5121a232e 896 case XML_WITH_HTTP:
pcercuei 0:03b5121a232e 897 #ifdef LIBXML_HTTP_ENABLED
pcercuei 0:03b5121a232e 898 return(1);
pcercuei 0:03b5121a232e 899 #else
pcercuei 0:03b5121a232e 900 return(0);
pcercuei 0:03b5121a232e 901 #endif
pcercuei 0:03b5121a232e 902 case XML_WITH_VALID:
pcercuei 0:03b5121a232e 903 #ifdef LIBXML_VALID_ENABLED
pcercuei 0:03b5121a232e 904 return(1);
pcercuei 0:03b5121a232e 905 #else
pcercuei 0:03b5121a232e 906 return(0);
pcercuei 0:03b5121a232e 907 #endif
pcercuei 0:03b5121a232e 908 case XML_WITH_HTML:
pcercuei 0:03b5121a232e 909 #ifdef LIBXML_HTML_ENABLED
pcercuei 0:03b5121a232e 910 return(1);
pcercuei 0:03b5121a232e 911 #else
pcercuei 0:03b5121a232e 912 return(0);
pcercuei 0:03b5121a232e 913 #endif
pcercuei 0:03b5121a232e 914 case XML_WITH_LEGACY:
pcercuei 0:03b5121a232e 915 #ifdef LIBXML_LEGACY_ENABLED
pcercuei 0:03b5121a232e 916 return(1);
pcercuei 0:03b5121a232e 917 #else
pcercuei 0:03b5121a232e 918 return(0);
pcercuei 0:03b5121a232e 919 #endif
pcercuei 0:03b5121a232e 920 case XML_WITH_C14N:
pcercuei 0:03b5121a232e 921 #ifdef LIBXML_C14N_ENABLED
pcercuei 0:03b5121a232e 922 return(1);
pcercuei 0:03b5121a232e 923 #else
pcercuei 0:03b5121a232e 924 return(0);
pcercuei 0:03b5121a232e 925 #endif
pcercuei 0:03b5121a232e 926 case XML_WITH_CATALOG:
pcercuei 0:03b5121a232e 927 #ifdef LIBXML_CATALOG_ENABLED
pcercuei 0:03b5121a232e 928 return(1);
pcercuei 0:03b5121a232e 929 #else
pcercuei 0:03b5121a232e 930 return(0);
pcercuei 0:03b5121a232e 931 #endif
pcercuei 0:03b5121a232e 932 case XML_WITH_XPATH:
pcercuei 0:03b5121a232e 933 #ifdef LIBXML_XPATH_ENABLED
pcercuei 0:03b5121a232e 934 return(1);
pcercuei 0:03b5121a232e 935 #else
pcercuei 0:03b5121a232e 936 return(0);
pcercuei 0:03b5121a232e 937 #endif
pcercuei 0:03b5121a232e 938 case XML_WITH_XPTR:
pcercuei 0:03b5121a232e 939 #ifdef LIBXML_XPTR_ENABLED
pcercuei 0:03b5121a232e 940 return(1);
pcercuei 0:03b5121a232e 941 #else
pcercuei 0:03b5121a232e 942 return(0);
pcercuei 0:03b5121a232e 943 #endif
pcercuei 0:03b5121a232e 944 case XML_WITH_XINCLUDE:
pcercuei 0:03b5121a232e 945 #ifdef LIBXML_XINCLUDE_ENABLED
pcercuei 0:03b5121a232e 946 return(1);
pcercuei 0:03b5121a232e 947 #else
pcercuei 0:03b5121a232e 948 return(0);
pcercuei 0:03b5121a232e 949 #endif
pcercuei 0:03b5121a232e 950 case XML_WITH_ICONV:
pcercuei 0:03b5121a232e 951 #ifdef LIBXML_ICONV_ENABLED
pcercuei 0:03b5121a232e 952 return(1);
pcercuei 0:03b5121a232e 953 #else
pcercuei 0:03b5121a232e 954 return(0);
pcercuei 0:03b5121a232e 955 #endif
pcercuei 0:03b5121a232e 956 case XML_WITH_ISO8859X:
pcercuei 0:03b5121a232e 957 #ifdef LIBXML_ISO8859X_ENABLED
pcercuei 0:03b5121a232e 958 return(1);
pcercuei 0:03b5121a232e 959 #else
pcercuei 0:03b5121a232e 960 return(0);
pcercuei 0:03b5121a232e 961 #endif
pcercuei 0:03b5121a232e 962 case XML_WITH_UNICODE:
pcercuei 0:03b5121a232e 963 #ifdef LIBXML_UNICODE_ENABLED
pcercuei 0:03b5121a232e 964 return(1);
pcercuei 0:03b5121a232e 965 #else
pcercuei 0:03b5121a232e 966 return(0);
pcercuei 0:03b5121a232e 967 #endif
pcercuei 0:03b5121a232e 968 case XML_WITH_REGEXP:
pcercuei 0:03b5121a232e 969 #ifdef LIBXML_REGEXP_ENABLED
pcercuei 0:03b5121a232e 970 return(1);
pcercuei 0:03b5121a232e 971 #else
pcercuei 0:03b5121a232e 972 return(0);
pcercuei 0:03b5121a232e 973 #endif
pcercuei 0:03b5121a232e 974 case XML_WITH_AUTOMATA:
pcercuei 0:03b5121a232e 975 #ifdef LIBXML_AUTOMATA_ENABLED
pcercuei 0:03b5121a232e 976 return(1);
pcercuei 0:03b5121a232e 977 #else
pcercuei 0:03b5121a232e 978 return(0);
pcercuei 0:03b5121a232e 979 #endif
pcercuei 0:03b5121a232e 980 case XML_WITH_EXPR:
pcercuei 0:03b5121a232e 981 #ifdef LIBXML_EXPR_ENABLED
pcercuei 0:03b5121a232e 982 return(1);
pcercuei 0:03b5121a232e 983 #else
pcercuei 0:03b5121a232e 984 return(0);
pcercuei 0:03b5121a232e 985 #endif
pcercuei 0:03b5121a232e 986 case XML_WITH_SCHEMAS:
pcercuei 0:03b5121a232e 987 #ifdef LIBXML_SCHEMAS_ENABLED
pcercuei 0:03b5121a232e 988 return(1);
pcercuei 0:03b5121a232e 989 #else
pcercuei 0:03b5121a232e 990 return(0);
pcercuei 0:03b5121a232e 991 #endif
pcercuei 0:03b5121a232e 992 case XML_WITH_SCHEMATRON:
pcercuei 0:03b5121a232e 993 #ifdef LIBXML_SCHEMATRON_ENABLED
pcercuei 0:03b5121a232e 994 return(1);
pcercuei 0:03b5121a232e 995 #else
pcercuei 0:03b5121a232e 996 return(0);
pcercuei 0:03b5121a232e 997 #endif
pcercuei 0:03b5121a232e 998 case XML_WITH_MODULES:
pcercuei 0:03b5121a232e 999 #ifdef LIBXML_MODULES_ENABLED
pcercuei 0:03b5121a232e 1000 return(1);
pcercuei 0:03b5121a232e 1001 #else
pcercuei 0:03b5121a232e 1002 return(0);
pcercuei 0:03b5121a232e 1003 #endif
pcercuei 0:03b5121a232e 1004 case XML_WITH_DEBUG:
pcercuei 0:03b5121a232e 1005 #ifdef LIBXML_DEBUG_ENABLED
pcercuei 0:03b5121a232e 1006 return(1);
pcercuei 0:03b5121a232e 1007 #else
pcercuei 0:03b5121a232e 1008 return(0);
pcercuei 0:03b5121a232e 1009 #endif
pcercuei 0:03b5121a232e 1010 case XML_WITH_DEBUG_MEM:
pcercuei 0:03b5121a232e 1011 #ifdef DEBUG_MEMORY_LOCATION
pcercuei 0:03b5121a232e 1012 return(1);
pcercuei 0:03b5121a232e 1013 #else
pcercuei 0:03b5121a232e 1014 return(0);
pcercuei 0:03b5121a232e 1015 #endif
pcercuei 0:03b5121a232e 1016 case XML_WITH_DEBUG_RUN:
pcercuei 0:03b5121a232e 1017 #ifdef LIBXML_DEBUG_RUNTIME
pcercuei 0:03b5121a232e 1018 return(1);
pcercuei 0:03b5121a232e 1019 #else
pcercuei 0:03b5121a232e 1020 return(0);
pcercuei 0:03b5121a232e 1021 #endif
pcercuei 0:03b5121a232e 1022 case XML_WITH_ZLIB:
pcercuei 0:03b5121a232e 1023 #ifdef LIBXML_ZLIB_ENABLED
pcercuei 0:03b5121a232e 1024 return(1);
pcercuei 0:03b5121a232e 1025 #else
pcercuei 0:03b5121a232e 1026 return(0);
pcercuei 0:03b5121a232e 1027 #endif
pcercuei 0:03b5121a232e 1028 case XML_WITH_LZMA:
pcercuei 0:03b5121a232e 1029 #ifdef LIBXML_LZMA_ENABLED
pcercuei 0:03b5121a232e 1030 return(1);
pcercuei 0:03b5121a232e 1031 #else
pcercuei 0:03b5121a232e 1032 return(0);
pcercuei 0:03b5121a232e 1033 #endif
pcercuei 0:03b5121a232e 1034 case XML_WITH_ICU:
pcercuei 0:03b5121a232e 1035 #ifdef LIBXML_ICU_ENABLED
pcercuei 0:03b5121a232e 1036 return(1);
pcercuei 0:03b5121a232e 1037 #else
pcercuei 0:03b5121a232e 1038 return(0);
pcercuei 0:03b5121a232e 1039 #endif
pcercuei 0:03b5121a232e 1040 default:
pcercuei 0:03b5121a232e 1041 break;
pcercuei 0:03b5121a232e 1042 }
pcercuei 0:03b5121a232e 1043 return(0);
pcercuei 0:03b5121a232e 1044 }
pcercuei 0:03b5121a232e 1045
pcercuei 0:03b5121a232e 1046 /************************************************************************
pcercuei 0:03b5121a232e 1047 * *
pcercuei 0:03b5121a232e 1048 * SAX2 defaulted attributes handling *
pcercuei 0:03b5121a232e 1049 * *
pcercuei 0:03b5121a232e 1050 ************************************************************************/
pcercuei 0:03b5121a232e 1051
pcercuei 0:03b5121a232e 1052 /**
pcercuei 0:03b5121a232e 1053 * xmlDetectSAX2:
pcercuei 0:03b5121a232e 1054 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 1055 *
pcercuei 0:03b5121a232e 1056 * Do the SAX2 detection and specific intialization
pcercuei 0:03b5121a232e 1057 */
pcercuei 0:03b5121a232e 1058 static void
pcercuei 0:03b5121a232e 1059 xmlDetectSAX2(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 1060 if (ctxt == NULL) return;
pcercuei 0:03b5121a232e 1061 #ifdef LIBXML_SAX1_ENABLED
pcercuei 0:03b5121a232e 1062 if ((ctxt->sax) && (ctxt->sax->initialized == XML_SAX2_MAGIC) &&
pcercuei 0:03b5121a232e 1063 ((ctxt->sax->startElementNs != NULL) ||
pcercuei 0:03b5121a232e 1064 (ctxt->sax->endElementNs != NULL))) ctxt->sax2 = 1;
pcercuei 0:03b5121a232e 1065 #else
pcercuei 0:03b5121a232e 1066 ctxt->sax2 = 1;
pcercuei 0:03b5121a232e 1067 #endif /* LIBXML_SAX1_ENABLED */
pcercuei 0:03b5121a232e 1068
pcercuei 0:03b5121a232e 1069 ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
pcercuei 0:03b5121a232e 1070 ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
pcercuei 0:03b5121a232e 1071 ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
pcercuei 0:03b5121a232e 1072 if ((ctxt->str_xml==NULL) || (ctxt->str_xmlns==NULL) ||
pcercuei 0:03b5121a232e 1073 (ctxt->str_xml_ns == NULL)) {
pcercuei 0:03b5121a232e 1074 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 1075 }
pcercuei 0:03b5121a232e 1076 }
pcercuei 0:03b5121a232e 1077
pcercuei 0:03b5121a232e 1078 typedef struct _xmlDefAttrs xmlDefAttrs;
pcercuei 0:03b5121a232e 1079 typedef xmlDefAttrs *xmlDefAttrsPtr;
pcercuei 0:03b5121a232e 1080 struct _xmlDefAttrs {
pcercuei 0:03b5121a232e 1081 int nbAttrs; /* number of defaulted attributes on that element */
pcercuei 0:03b5121a232e 1082 int maxAttrs; /* the size of the array */
pcercuei 0:03b5121a232e 1083 const xmlChar *values[5]; /* array of localname/prefix/values/external */
pcercuei 0:03b5121a232e 1084 };
pcercuei 0:03b5121a232e 1085
pcercuei 0:03b5121a232e 1086 /**
pcercuei 0:03b5121a232e 1087 * xmlAttrNormalizeSpace:
pcercuei 0:03b5121a232e 1088 * @src: the source string
pcercuei 0:03b5121a232e 1089 * @dst: the target string
pcercuei 0:03b5121a232e 1090 *
pcercuei 0:03b5121a232e 1091 * Normalize the space in non CDATA attribute values:
pcercuei 0:03b5121a232e 1092 * If the attribute type is not CDATA, then the XML processor MUST further
pcercuei 0:03b5121a232e 1093 * process the normalized attribute value by discarding any leading and
pcercuei 0:03b5121a232e 1094 * trailing space (#x20) characters, and by replacing sequences of space
pcercuei 0:03b5121a232e 1095 * (#x20) characters by a single space (#x20) character.
pcercuei 0:03b5121a232e 1096 * Note that the size of dst need to be at least src, and if one doesn't need
pcercuei 0:03b5121a232e 1097 * to preserve dst (and it doesn't come from a dictionary or read-only) then
pcercuei 0:03b5121a232e 1098 * passing src as dst is just fine.
pcercuei 0:03b5121a232e 1099 *
pcercuei 0:03b5121a232e 1100 * Returns a pointer to the normalized value (dst) or NULL if no conversion
pcercuei 0:03b5121a232e 1101 * is needed.
pcercuei 0:03b5121a232e 1102 */
pcercuei 0:03b5121a232e 1103 static xmlChar *
pcercuei 0:03b5121a232e 1104 xmlAttrNormalizeSpace(const xmlChar *src, xmlChar *dst)
pcercuei 0:03b5121a232e 1105 {
pcercuei 0:03b5121a232e 1106 if ((src == NULL) || (dst == NULL))
pcercuei 0:03b5121a232e 1107 return(NULL);
pcercuei 0:03b5121a232e 1108
pcercuei 0:03b5121a232e 1109 while (*src == 0x20) src++;
pcercuei 0:03b5121a232e 1110 while (*src != 0) {
pcercuei 0:03b5121a232e 1111 if (*src == 0x20) {
pcercuei 0:03b5121a232e 1112 while (*src == 0x20) src++;
pcercuei 0:03b5121a232e 1113 if (*src != 0)
pcercuei 0:03b5121a232e 1114 *dst++ = 0x20;
pcercuei 0:03b5121a232e 1115 } else {
pcercuei 0:03b5121a232e 1116 *dst++ = *src++;
pcercuei 0:03b5121a232e 1117 }
pcercuei 0:03b5121a232e 1118 }
pcercuei 0:03b5121a232e 1119 *dst = 0;
pcercuei 0:03b5121a232e 1120 if (dst == src)
pcercuei 0:03b5121a232e 1121 return(NULL);
pcercuei 0:03b5121a232e 1122 return(dst);
pcercuei 0:03b5121a232e 1123 }
pcercuei 0:03b5121a232e 1124
pcercuei 0:03b5121a232e 1125 /**
pcercuei 0:03b5121a232e 1126 * xmlAttrNormalizeSpace2:
pcercuei 0:03b5121a232e 1127 * @src: the source string
pcercuei 0:03b5121a232e 1128 *
pcercuei 0:03b5121a232e 1129 * Normalize the space in non CDATA attribute values, a slightly more complex
pcercuei 0:03b5121a232e 1130 * front end to avoid allocation problems when running on attribute values
pcercuei 0:03b5121a232e 1131 * coming from the input.
pcercuei 0:03b5121a232e 1132 *
pcercuei 0:03b5121a232e 1133 * Returns a pointer to the normalized value (dst) or NULL if no conversion
pcercuei 0:03b5121a232e 1134 * is needed.
pcercuei 0:03b5121a232e 1135 */
pcercuei 0:03b5121a232e 1136 static const xmlChar *
pcercuei 0:03b5121a232e 1137 xmlAttrNormalizeSpace2(xmlParserCtxtPtr ctxt, xmlChar *src, int *len)
pcercuei 0:03b5121a232e 1138 {
pcercuei 0:03b5121a232e 1139 int i;
pcercuei 0:03b5121a232e 1140 int remove_head = 0;
pcercuei 0:03b5121a232e 1141 int need_realloc = 0;
pcercuei 0:03b5121a232e 1142 const xmlChar *cur;
pcercuei 0:03b5121a232e 1143
pcercuei 0:03b5121a232e 1144 if ((ctxt == NULL) || (src == NULL) || (len == NULL))
pcercuei 0:03b5121a232e 1145 return(NULL);
pcercuei 0:03b5121a232e 1146 i = *len;
pcercuei 0:03b5121a232e 1147 if (i <= 0)
pcercuei 0:03b5121a232e 1148 return(NULL);
pcercuei 0:03b5121a232e 1149
pcercuei 0:03b5121a232e 1150 cur = src;
pcercuei 0:03b5121a232e 1151 while (*cur == 0x20) {
pcercuei 0:03b5121a232e 1152 cur++;
pcercuei 0:03b5121a232e 1153 remove_head++;
pcercuei 0:03b5121a232e 1154 }
pcercuei 0:03b5121a232e 1155 while (*cur != 0) {
pcercuei 0:03b5121a232e 1156 if (*cur == 0x20) {
pcercuei 0:03b5121a232e 1157 cur++;
pcercuei 0:03b5121a232e 1158 if ((*cur == 0x20) || (*cur == 0)) {
pcercuei 0:03b5121a232e 1159 need_realloc = 1;
pcercuei 0:03b5121a232e 1160 break;
pcercuei 0:03b5121a232e 1161 }
pcercuei 0:03b5121a232e 1162 } else
pcercuei 0:03b5121a232e 1163 cur++;
pcercuei 0:03b5121a232e 1164 }
pcercuei 0:03b5121a232e 1165 if (need_realloc) {
pcercuei 0:03b5121a232e 1166 xmlChar *ret;
pcercuei 0:03b5121a232e 1167
pcercuei 0:03b5121a232e 1168 ret = xmlStrndup(src + remove_head, i - remove_head + 1);
pcercuei 0:03b5121a232e 1169 if (ret == NULL) {
pcercuei 0:03b5121a232e 1170 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 1171 return(NULL);
pcercuei 0:03b5121a232e 1172 }
pcercuei 0:03b5121a232e 1173 xmlAttrNormalizeSpace(ret, ret);
pcercuei 0:03b5121a232e 1174 *len = (int) strlen((const char *)ret);
pcercuei 0:03b5121a232e 1175 return(ret);
pcercuei 0:03b5121a232e 1176 } else if (remove_head) {
pcercuei 0:03b5121a232e 1177 *len -= remove_head;
pcercuei 0:03b5121a232e 1178 memmove(src, src + remove_head, 1 + *len);
pcercuei 0:03b5121a232e 1179 return(src);
pcercuei 0:03b5121a232e 1180 }
pcercuei 0:03b5121a232e 1181 return(NULL);
pcercuei 0:03b5121a232e 1182 }
pcercuei 0:03b5121a232e 1183
pcercuei 0:03b5121a232e 1184 /**
pcercuei 0:03b5121a232e 1185 * xmlAddDefAttrs:
pcercuei 0:03b5121a232e 1186 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 1187 * @fullname: the element fullname
pcercuei 0:03b5121a232e 1188 * @fullattr: the attribute fullname
pcercuei 0:03b5121a232e 1189 * @value: the attribute value
pcercuei 0:03b5121a232e 1190 *
pcercuei 0:03b5121a232e 1191 * Add a defaulted attribute for an element
pcercuei 0:03b5121a232e 1192 */
pcercuei 0:03b5121a232e 1193 static void
pcercuei 0:03b5121a232e 1194 xmlAddDefAttrs(xmlParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 1195 const xmlChar *fullname,
pcercuei 0:03b5121a232e 1196 const xmlChar *fullattr,
pcercuei 0:03b5121a232e 1197 const xmlChar *value) {
pcercuei 0:03b5121a232e 1198 xmlDefAttrsPtr defaults;
pcercuei 0:03b5121a232e 1199 int len;
pcercuei 0:03b5121a232e 1200 const xmlChar *name;
pcercuei 0:03b5121a232e 1201 const xmlChar *prefix;
pcercuei 0:03b5121a232e 1202
pcercuei 0:03b5121a232e 1203 /*
pcercuei 0:03b5121a232e 1204 * Allows to detect attribute redefinitions
pcercuei 0:03b5121a232e 1205 */
pcercuei 0:03b5121a232e 1206 if (ctxt->attsSpecial != NULL) {
pcercuei 0:03b5121a232e 1207 if (xmlHashLookup2(ctxt->attsSpecial, fullname, fullattr) != NULL)
pcercuei 0:03b5121a232e 1208 return;
pcercuei 0:03b5121a232e 1209 }
pcercuei 0:03b5121a232e 1210
pcercuei 0:03b5121a232e 1211 if (ctxt->attsDefault == NULL) {
pcercuei 0:03b5121a232e 1212 ctxt->attsDefault = xmlHashCreateDict(10, ctxt->dict);
pcercuei 0:03b5121a232e 1213 if (ctxt->attsDefault == NULL)
pcercuei 0:03b5121a232e 1214 goto mem_error;
pcercuei 0:03b5121a232e 1215 }
pcercuei 0:03b5121a232e 1216
pcercuei 0:03b5121a232e 1217 /*
pcercuei 0:03b5121a232e 1218 * split the element name into prefix:localname , the string found
pcercuei 0:03b5121a232e 1219 * are within the DTD and then not associated to namespace names.
pcercuei 0:03b5121a232e 1220 */
pcercuei 0:03b5121a232e 1221 name = xmlSplitQName3(fullname, &len);
pcercuei 0:03b5121a232e 1222 if (name == NULL) {
pcercuei 0:03b5121a232e 1223 name = xmlDictLookup(ctxt->dict, fullname, -1);
pcercuei 0:03b5121a232e 1224 prefix = NULL;
pcercuei 0:03b5121a232e 1225 } else {
pcercuei 0:03b5121a232e 1226 name = xmlDictLookup(ctxt->dict, name, -1);
pcercuei 0:03b5121a232e 1227 prefix = xmlDictLookup(ctxt->dict, fullname, len);
pcercuei 0:03b5121a232e 1228 }
pcercuei 0:03b5121a232e 1229
pcercuei 0:03b5121a232e 1230 /*
pcercuei 0:03b5121a232e 1231 * make sure there is some storage
pcercuei 0:03b5121a232e 1232 */
pcercuei 0:03b5121a232e 1233 defaults = xmlHashLookup2(ctxt->attsDefault, name, prefix);
pcercuei 0:03b5121a232e 1234 if (defaults == NULL) {
pcercuei 0:03b5121a232e 1235 defaults = (xmlDefAttrsPtr) xmlMalloc(sizeof(xmlDefAttrs) +
pcercuei 0:03b5121a232e 1236 (4 * 5) * sizeof(const xmlChar *));
pcercuei 0:03b5121a232e 1237 if (defaults == NULL)
pcercuei 0:03b5121a232e 1238 goto mem_error;
pcercuei 0:03b5121a232e 1239 defaults->nbAttrs = 0;
pcercuei 0:03b5121a232e 1240 defaults->maxAttrs = 4;
pcercuei 0:03b5121a232e 1241 if (xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix,
pcercuei 0:03b5121a232e 1242 defaults, NULL) < 0) {
pcercuei 0:03b5121a232e 1243 xmlFree(defaults);
pcercuei 0:03b5121a232e 1244 goto mem_error;
pcercuei 0:03b5121a232e 1245 }
pcercuei 0:03b5121a232e 1246 } else if (defaults->nbAttrs >= defaults->maxAttrs) {
pcercuei 0:03b5121a232e 1247 xmlDefAttrsPtr temp;
pcercuei 0:03b5121a232e 1248
pcercuei 0:03b5121a232e 1249 temp = (xmlDefAttrsPtr) xmlRealloc(defaults, sizeof(xmlDefAttrs) +
pcercuei 0:03b5121a232e 1250 (2 * defaults->maxAttrs * 5) * sizeof(const xmlChar *));
pcercuei 0:03b5121a232e 1251 if (temp == NULL)
pcercuei 0:03b5121a232e 1252 goto mem_error;
pcercuei 0:03b5121a232e 1253 defaults = temp;
pcercuei 0:03b5121a232e 1254 defaults->maxAttrs *= 2;
pcercuei 0:03b5121a232e 1255 if (xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix,
pcercuei 0:03b5121a232e 1256 defaults, NULL) < 0) {
pcercuei 0:03b5121a232e 1257 xmlFree(defaults);
pcercuei 0:03b5121a232e 1258 goto mem_error;
pcercuei 0:03b5121a232e 1259 }
pcercuei 0:03b5121a232e 1260 }
pcercuei 0:03b5121a232e 1261
pcercuei 0:03b5121a232e 1262 /*
pcercuei 0:03b5121a232e 1263 * Split the element name into prefix:localname , the string found
pcercuei 0:03b5121a232e 1264 * are within the DTD and hen not associated to namespace names.
pcercuei 0:03b5121a232e 1265 */
pcercuei 0:03b5121a232e 1266 name = xmlSplitQName3(fullattr, &len);
pcercuei 0:03b5121a232e 1267 if (name == NULL) {
pcercuei 0:03b5121a232e 1268 name = xmlDictLookup(ctxt->dict, fullattr, -1);
pcercuei 0:03b5121a232e 1269 prefix = NULL;
pcercuei 0:03b5121a232e 1270 } else {
pcercuei 0:03b5121a232e 1271 name = xmlDictLookup(ctxt->dict, name, -1);
pcercuei 0:03b5121a232e 1272 prefix = xmlDictLookup(ctxt->dict, fullattr, len);
pcercuei 0:03b5121a232e 1273 }
pcercuei 0:03b5121a232e 1274
pcercuei 0:03b5121a232e 1275 defaults->values[5 * defaults->nbAttrs] = name;
pcercuei 0:03b5121a232e 1276 defaults->values[5 * defaults->nbAttrs + 1] = prefix;
pcercuei 0:03b5121a232e 1277 /* intern the string and precompute the end */
pcercuei 0:03b5121a232e 1278 len = xmlStrlen(value);
pcercuei 0:03b5121a232e 1279 value = xmlDictLookup(ctxt->dict, value, len);
pcercuei 0:03b5121a232e 1280 defaults->values[5 * defaults->nbAttrs + 2] = value;
pcercuei 0:03b5121a232e 1281 defaults->values[5 * defaults->nbAttrs + 3] = value + len;
pcercuei 0:03b5121a232e 1282 if (ctxt->external)
pcercuei 0:03b5121a232e 1283 defaults->values[5 * defaults->nbAttrs + 4] = BAD_CAST "external";
pcercuei 0:03b5121a232e 1284 else
pcercuei 0:03b5121a232e 1285 defaults->values[5 * defaults->nbAttrs + 4] = NULL;
pcercuei 0:03b5121a232e 1286 defaults->nbAttrs++;
pcercuei 0:03b5121a232e 1287
pcercuei 0:03b5121a232e 1288 return;
pcercuei 0:03b5121a232e 1289
pcercuei 0:03b5121a232e 1290 mem_error:
pcercuei 0:03b5121a232e 1291 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 1292 return;
pcercuei 0:03b5121a232e 1293 }
pcercuei 0:03b5121a232e 1294
pcercuei 0:03b5121a232e 1295 /**
pcercuei 0:03b5121a232e 1296 * xmlAddSpecialAttr:
pcercuei 0:03b5121a232e 1297 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 1298 * @fullname: the element fullname
pcercuei 0:03b5121a232e 1299 * @fullattr: the attribute fullname
pcercuei 0:03b5121a232e 1300 * @type: the attribute type
pcercuei 0:03b5121a232e 1301 *
pcercuei 0:03b5121a232e 1302 * Register this attribute type
pcercuei 0:03b5121a232e 1303 */
pcercuei 0:03b5121a232e 1304 static void
pcercuei 0:03b5121a232e 1305 xmlAddSpecialAttr(xmlParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 1306 const xmlChar *fullname,
pcercuei 0:03b5121a232e 1307 const xmlChar *fullattr,
pcercuei 0:03b5121a232e 1308 int type)
pcercuei 0:03b5121a232e 1309 {
pcercuei 0:03b5121a232e 1310 if (ctxt->attsSpecial == NULL) {
pcercuei 0:03b5121a232e 1311 ctxt->attsSpecial = xmlHashCreateDict(10, ctxt->dict);
pcercuei 0:03b5121a232e 1312 if (ctxt->attsSpecial == NULL)
pcercuei 0:03b5121a232e 1313 goto mem_error;
pcercuei 0:03b5121a232e 1314 }
pcercuei 0:03b5121a232e 1315
pcercuei 0:03b5121a232e 1316 if (xmlHashLookup2(ctxt->attsSpecial, fullname, fullattr) != NULL)
pcercuei 0:03b5121a232e 1317 return;
pcercuei 0:03b5121a232e 1318
pcercuei 0:03b5121a232e 1319 xmlHashAddEntry2(ctxt->attsSpecial, fullname, fullattr,
pcercuei 0:03b5121a232e 1320 (void *) (long) type);
pcercuei 0:03b5121a232e 1321 return;
pcercuei 0:03b5121a232e 1322
pcercuei 0:03b5121a232e 1323 mem_error:
pcercuei 0:03b5121a232e 1324 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 1325 return;
pcercuei 0:03b5121a232e 1326 }
pcercuei 0:03b5121a232e 1327
pcercuei 0:03b5121a232e 1328 /**
pcercuei 0:03b5121a232e 1329 * xmlCleanSpecialAttrCallback:
pcercuei 0:03b5121a232e 1330 *
pcercuei 0:03b5121a232e 1331 * Removes CDATA attributes from the special attribute table
pcercuei 0:03b5121a232e 1332 */
pcercuei 0:03b5121a232e 1333 static void
pcercuei 0:03b5121a232e 1334 xmlCleanSpecialAttrCallback(void *payload, void *data,
pcercuei 0:03b5121a232e 1335 const xmlChar *fullname, const xmlChar *fullattr,
pcercuei 0:03b5121a232e 1336 const xmlChar *unused ATTRIBUTE_UNUSED) {
pcercuei 0:03b5121a232e 1337 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) data;
pcercuei 0:03b5121a232e 1338
pcercuei 0:03b5121a232e 1339 if (((long) payload) == XML_ATTRIBUTE_CDATA) {
pcercuei 0:03b5121a232e 1340 xmlHashRemoveEntry2(ctxt->attsSpecial, fullname, fullattr, NULL);
pcercuei 0:03b5121a232e 1341 }
pcercuei 0:03b5121a232e 1342 }
pcercuei 0:03b5121a232e 1343
pcercuei 0:03b5121a232e 1344 /**
pcercuei 0:03b5121a232e 1345 * xmlCleanSpecialAttr:
pcercuei 0:03b5121a232e 1346 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 1347 *
pcercuei 0:03b5121a232e 1348 * Trim the list of attributes defined to remove all those of type
pcercuei 0:03b5121a232e 1349 * CDATA as they are not special. This call should be done when finishing
pcercuei 0:03b5121a232e 1350 * to parse the DTD and before starting to parse the document root.
pcercuei 0:03b5121a232e 1351 */
pcercuei 0:03b5121a232e 1352 static void
pcercuei 0:03b5121a232e 1353 xmlCleanSpecialAttr(xmlParserCtxtPtr ctxt)
pcercuei 0:03b5121a232e 1354 {
pcercuei 0:03b5121a232e 1355 if (ctxt->attsSpecial == NULL)
pcercuei 0:03b5121a232e 1356 return;
pcercuei 0:03b5121a232e 1357
pcercuei 0:03b5121a232e 1358 xmlHashScanFull(ctxt->attsSpecial, xmlCleanSpecialAttrCallback, ctxt);
pcercuei 0:03b5121a232e 1359
pcercuei 0:03b5121a232e 1360 if (xmlHashSize(ctxt->attsSpecial) == 0) {
pcercuei 0:03b5121a232e 1361 xmlHashFree(ctxt->attsSpecial, NULL);
pcercuei 0:03b5121a232e 1362 ctxt->attsSpecial = NULL;
pcercuei 0:03b5121a232e 1363 }
pcercuei 0:03b5121a232e 1364 return;
pcercuei 0:03b5121a232e 1365 }
pcercuei 0:03b5121a232e 1366
pcercuei 0:03b5121a232e 1367 /**
pcercuei 0:03b5121a232e 1368 * xmlCheckLanguageID:
pcercuei 0:03b5121a232e 1369 * @lang: pointer to the string value
pcercuei 0:03b5121a232e 1370 *
pcercuei 0:03b5121a232e 1371 * Checks that the value conforms to the LanguageID production:
pcercuei 0:03b5121a232e 1372 *
pcercuei 0:03b5121a232e 1373 * NOTE: this is somewhat deprecated, those productions were removed from
pcercuei 0:03b5121a232e 1374 * the XML Second edition.
pcercuei 0:03b5121a232e 1375 *
pcercuei 0:03b5121a232e 1376 * [33] LanguageID ::= Langcode ('-' Subcode)*
pcercuei 0:03b5121a232e 1377 * [34] Langcode ::= ISO639Code | IanaCode | UserCode
pcercuei 0:03b5121a232e 1378 * [35] ISO639Code ::= ([a-z] | [A-Z]) ([a-z] | [A-Z])
pcercuei 0:03b5121a232e 1379 * [36] IanaCode ::= ('i' | 'I') '-' ([a-z] | [A-Z])+
pcercuei 0:03b5121a232e 1380 * [37] UserCode ::= ('x' | 'X') '-' ([a-z] | [A-Z])+
pcercuei 0:03b5121a232e 1381 * [38] Subcode ::= ([a-z] | [A-Z])+
pcercuei 0:03b5121a232e 1382 *
pcercuei 0:03b5121a232e 1383 * The current REC reference the sucessors of RFC 1766, currently 5646
pcercuei 0:03b5121a232e 1384 *
pcercuei 0:03b5121a232e 1385 * http://www.rfc-editor.org/rfc/rfc5646.txt
pcercuei 0:03b5121a232e 1386 * langtag = language
pcercuei 0:03b5121a232e 1387 * ["-" script]
pcercuei 0:03b5121a232e 1388 * ["-" region]
pcercuei 0:03b5121a232e 1389 * *("-" variant)
pcercuei 0:03b5121a232e 1390 * *("-" extension)
pcercuei 0:03b5121a232e 1391 * ["-" privateuse]
pcercuei 0:03b5121a232e 1392 * language = 2*3ALPHA ; shortest ISO 639 code
pcercuei 0:03b5121a232e 1393 * ["-" extlang] ; sometimes followed by
pcercuei 0:03b5121a232e 1394 * ; extended language subtags
pcercuei 0:03b5121a232e 1395 * / 4ALPHA ; or reserved for future use
pcercuei 0:03b5121a232e 1396 * / 5*8ALPHA ; or registered language subtag
pcercuei 0:03b5121a232e 1397 *
pcercuei 0:03b5121a232e 1398 * extlang = 3ALPHA ; selected ISO 639 codes
pcercuei 0:03b5121a232e 1399 * *2("-" 3ALPHA) ; permanently reserved
pcercuei 0:03b5121a232e 1400 *
pcercuei 0:03b5121a232e 1401 * script = 4ALPHA ; ISO 15924 code
pcercuei 0:03b5121a232e 1402 *
pcercuei 0:03b5121a232e 1403 * region = 2ALPHA ; ISO 3166-1 code
pcercuei 0:03b5121a232e 1404 * / 3DIGIT ; UN M.49 code
pcercuei 0:03b5121a232e 1405 *
pcercuei 0:03b5121a232e 1406 * variant = 5*8alphanum ; registered variants
pcercuei 0:03b5121a232e 1407 * / (DIGIT 3alphanum)
pcercuei 0:03b5121a232e 1408 *
pcercuei 0:03b5121a232e 1409 * extension = singleton 1*("-" (2*8alphanum))
pcercuei 0:03b5121a232e 1410 *
pcercuei 0:03b5121a232e 1411 * ; Single alphanumerics
pcercuei 0:03b5121a232e 1412 * ; "x" reserved for private use
pcercuei 0:03b5121a232e 1413 * singleton = DIGIT ; 0 - 9
pcercuei 0:03b5121a232e 1414 * / %x41-57 ; A - W
pcercuei 0:03b5121a232e 1415 * / %x59-5A ; Y - Z
pcercuei 0:03b5121a232e 1416 * / %x61-77 ; a - w
pcercuei 0:03b5121a232e 1417 * / %x79-7A ; y - z
pcercuei 0:03b5121a232e 1418 *
pcercuei 0:03b5121a232e 1419 * it sounds right to still allow Irregular i-xxx IANA and user codes too
pcercuei 0:03b5121a232e 1420 * The parser below doesn't try to cope with extension or privateuse
pcercuei 0:03b5121a232e 1421 * that could be added but that's not interoperable anyway
pcercuei 0:03b5121a232e 1422 *
pcercuei 0:03b5121a232e 1423 * Returns 1 if correct 0 otherwise
pcercuei 0:03b5121a232e 1424 **/
pcercuei 0:03b5121a232e 1425 int
pcercuei 0:03b5121a232e 1426 xmlCheckLanguageID(const xmlChar * lang)
pcercuei 0:03b5121a232e 1427 {
pcercuei 0:03b5121a232e 1428 const xmlChar *cur = lang, *nxt;
pcercuei 0:03b5121a232e 1429
pcercuei 0:03b5121a232e 1430 if (cur == NULL)
pcercuei 0:03b5121a232e 1431 return (0);
pcercuei 0:03b5121a232e 1432 if (((cur[0] == 'i') && (cur[1] == '-')) ||
pcercuei 0:03b5121a232e 1433 ((cur[0] == 'I') && (cur[1] == '-')) ||
pcercuei 0:03b5121a232e 1434 ((cur[0] == 'x') && (cur[1] == '-')) ||
pcercuei 0:03b5121a232e 1435 ((cur[0] == 'X') && (cur[1] == '-'))) {
pcercuei 0:03b5121a232e 1436 /*
pcercuei 0:03b5121a232e 1437 * Still allow IANA code and user code which were coming
pcercuei 0:03b5121a232e 1438 * from the previous version of the XML-1.0 specification
pcercuei 0:03b5121a232e 1439 * it's deprecated but we should not fail
pcercuei 0:03b5121a232e 1440 */
pcercuei 0:03b5121a232e 1441 cur += 2;
pcercuei 0:03b5121a232e 1442 while (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
pcercuei 0:03b5121a232e 1443 ((cur[0] >= 'a') && (cur[0] <= 'z')))
pcercuei 0:03b5121a232e 1444 cur++;
pcercuei 0:03b5121a232e 1445 return(cur[0] == 0);
pcercuei 0:03b5121a232e 1446 }
pcercuei 0:03b5121a232e 1447 nxt = cur;
pcercuei 0:03b5121a232e 1448 while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
pcercuei 0:03b5121a232e 1449 ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
pcercuei 0:03b5121a232e 1450 nxt++;
pcercuei 0:03b5121a232e 1451 if (nxt - cur >= 4) {
pcercuei 0:03b5121a232e 1452 /*
pcercuei 0:03b5121a232e 1453 * Reserved
pcercuei 0:03b5121a232e 1454 */
pcercuei 0:03b5121a232e 1455 if ((nxt - cur > 8) || (nxt[0] != 0))
pcercuei 0:03b5121a232e 1456 return(0);
pcercuei 0:03b5121a232e 1457 return(1);
pcercuei 0:03b5121a232e 1458 }
pcercuei 0:03b5121a232e 1459 if (nxt - cur < 2)
pcercuei 0:03b5121a232e 1460 return(0);
pcercuei 0:03b5121a232e 1461 /* we got an ISO 639 code */
pcercuei 0:03b5121a232e 1462 if (nxt[0] == 0)
pcercuei 0:03b5121a232e 1463 return(1);
pcercuei 0:03b5121a232e 1464 if (nxt[0] != '-')
pcercuei 0:03b5121a232e 1465 return(0);
pcercuei 0:03b5121a232e 1466
pcercuei 0:03b5121a232e 1467 nxt++;
pcercuei 0:03b5121a232e 1468 cur = nxt;
pcercuei 0:03b5121a232e 1469 /* now we can have extlang or script or region or variant */
pcercuei 0:03b5121a232e 1470 if ((nxt[0] >= '0') && (nxt[0] <= '9'))
pcercuei 0:03b5121a232e 1471 goto region_m49;
pcercuei 0:03b5121a232e 1472
pcercuei 0:03b5121a232e 1473 while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
pcercuei 0:03b5121a232e 1474 ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
pcercuei 0:03b5121a232e 1475 nxt++;
pcercuei 0:03b5121a232e 1476 if (nxt - cur == 4)
pcercuei 0:03b5121a232e 1477 goto script;
pcercuei 0:03b5121a232e 1478 if (nxt - cur == 2)
pcercuei 0:03b5121a232e 1479 goto region;
pcercuei 0:03b5121a232e 1480 if ((nxt - cur >= 5) && (nxt - cur <= 8))
pcercuei 0:03b5121a232e 1481 goto variant;
pcercuei 0:03b5121a232e 1482 if (nxt - cur != 3)
pcercuei 0:03b5121a232e 1483 return(0);
pcercuei 0:03b5121a232e 1484 /* we parsed an extlang */
pcercuei 0:03b5121a232e 1485 if (nxt[0] == 0)
pcercuei 0:03b5121a232e 1486 return(1);
pcercuei 0:03b5121a232e 1487 if (nxt[0] != '-')
pcercuei 0:03b5121a232e 1488 return(0);
pcercuei 0:03b5121a232e 1489
pcercuei 0:03b5121a232e 1490 nxt++;
pcercuei 0:03b5121a232e 1491 cur = nxt;
pcercuei 0:03b5121a232e 1492 /* now we can have script or region or variant */
pcercuei 0:03b5121a232e 1493 if ((nxt[0] >= '0') && (nxt[0] <= '9'))
pcercuei 0:03b5121a232e 1494 goto region_m49;
pcercuei 0:03b5121a232e 1495
pcercuei 0:03b5121a232e 1496 while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
pcercuei 0:03b5121a232e 1497 ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
pcercuei 0:03b5121a232e 1498 nxt++;
pcercuei 0:03b5121a232e 1499 if (nxt - cur == 2)
pcercuei 0:03b5121a232e 1500 goto region;
pcercuei 0:03b5121a232e 1501 if ((nxt - cur >= 5) && (nxt - cur <= 8))
pcercuei 0:03b5121a232e 1502 goto variant;
pcercuei 0:03b5121a232e 1503 if (nxt - cur != 4)
pcercuei 0:03b5121a232e 1504 return(0);
pcercuei 0:03b5121a232e 1505 /* we parsed a script */
pcercuei 0:03b5121a232e 1506 script:
pcercuei 0:03b5121a232e 1507 if (nxt[0] == 0)
pcercuei 0:03b5121a232e 1508 return(1);
pcercuei 0:03b5121a232e 1509 if (nxt[0] != '-')
pcercuei 0:03b5121a232e 1510 return(0);
pcercuei 0:03b5121a232e 1511
pcercuei 0:03b5121a232e 1512 nxt++;
pcercuei 0:03b5121a232e 1513 cur = nxt;
pcercuei 0:03b5121a232e 1514 /* now we can have region or variant */
pcercuei 0:03b5121a232e 1515 if ((nxt[0] >= '0') && (nxt[0] <= '9'))
pcercuei 0:03b5121a232e 1516 goto region_m49;
pcercuei 0:03b5121a232e 1517
pcercuei 0:03b5121a232e 1518 while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
pcercuei 0:03b5121a232e 1519 ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
pcercuei 0:03b5121a232e 1520 nxt++;
pcercuei 0:03b5121a232e 1521
pcercuei 0:03b5121a232e 1522 if ((nxt - cur >= 5) && (nxt - cur <= 8))
pcercuei 0:03b5121a232e 1523 goto variant;
pcercuei 0:03b5121a232e 1524 if (nxt - cur != 2)
pcercuei 0:03b5121a232e 1525 return(0);
pcercuei 0:03b5121a232e 1526 /* we parsed a region */
pcercuei 0:03b5121a232e 1527 region:
pcercuei 0:03b5121a232e 1528 if (nxt[0] == 0)
pcercuei 0:03b5121a232e 1529 return(1);
pcercuei 0:03b5121a232e 1530 if (nxt[0] != '-')
pcercuei 0:03b5121a232e 1531 return(0);
pcercuei 0:03b5121a232e 1532
pcercuei 0:03b5121a232e 1533 nxt++;
pcercuei 0:03b5121a232e 1534 cur = nxt;
pcercuei 0:03b5121a232e 1535 /* now we can just have a variant */
pcercuei 0:03b5121a232e 1536 while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
pcercuei 0:03b5121a232e 1537 ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
pcercuei 0:03b5121a232e 1538 nxt++;
pcercuei 0:03b5121a232e 1539
pcercuei 0:03b5121a232e 1540 if ((nxt - cur < 5) || (nxt - cur > 8))
pcercuei 0:03b5121a232e 1541 return(0);
pcercuei 0:03b5121a232e 1542
pcercuei 0:03b5121a232e 1543 /* we parsed a variant */
pcercuei 0:03b5121a232e 1544 variant:
pcercuei 0:03b5121a232e 1545 if (nxt[0] == 0)
pcercuei 0:03b5121a232e 1546 return(1);
pcercuei 0:03b5121a232e 1547 if (nxt[0] != '-')
pcercuei 0:03b5121a232e 1548 return(0);
pcercuei 0:03b5121a232e 1549 /* extensions and private use subtags not checked */
pcercuei 0:03b5121a232e 1550 return (1);
pcercuei 0:03b5121a232e 1551
pcercuei 0:03b5121a232e 1552 region_m49:
pcercuei 0:03b5121a232e 1553 if (((nxt[1] >= '0') && (nxt[1] <= '9')) &&
pcercuei 0:03b5121a232e 1554 ((nxt[2] >= '0') && (nxt[2] <= '9'))) {
pcercuei 0:03b5121a232e 1555 nxt += 3;
pcercuei 0:03b5121a232e 1556 goto region;
pcercuei 0:03b5121a232e 1557 }
pcercuei 0:03b5121a232e 1558 return(0);
pcercuei 0:03b5121a232e 1559 }
pcercuei 0:03b5121a232e 1560
pcercuei 0:03b5121a232e 1561 /************************************************************************
pcercuei 0:03b5121a232e 1562 * *
pcercuei 0:03b5121a232e 1563 * Parser stacks related functions and macros *
pcercuei 0:03b5121a232e 1564 * *
pcercuei 0:03b5121a232e 1565 ************************************************************************/
pcercuei 0:03b5121a232e 1566
pcercuei 0:03b5121a232e 1567 static xmlEntityPtr xmlParseStringEntityRef(xmlParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 1568 const xmlChar ** str);
pcercuei 0:03b5121a232e 1569
pcercuei 0:03b5121a232e 1570 #ifdef SAX2
pcercuei 0:03b5121a232e 1571 /**
pcercuei 0:03b5121a232e 1572 * nsPush:
pcercuei 0:03b5121a232e 1573 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 1574 * @prefix: the namespace prefix or NULL
pcercuei 0:03b5121a232e 1575 * @URL: the namespace name
pcercuei 0:03b5121a232e 1576 *
pcercuei 0:03b5121a232e 1577 * Pushes a new parser namespace on top of the ns stack
pcercuei 0:03b5121a232e 1578 *
pcercuei 0:03b5121a232e 1579 * Returns -1 in case of error, -2 if the namespace should be discarded
pcercuei 0:03b5121a232e 1580 * and the index in the stack otherwise.
pcercuei 0:03b5121a232e 1581 */
pcercuei 0:03b5121a232e 1582 static int
pcercuei 0:03b5121a232e 1583 nsPush(xmlParserCtxtPtr ctxt, const xmlChar *prefix, const xmlChar *URL)
pcercuei 0:03b5121a232e 1584 {
pcercuei 0:03b5121a232e 1585 if (ctxt->options & XML_PARSE_NSCLEAN) {
pcercuei 0:03b5121a232e 1586 int i;
pcercuei 0:03b5121a232e 1587 for (i = ctxt->nsNr - 2;i >= 0;i -= 2) {
pcercuei 0:03b5121a232e 1588 if (ctxt->nsTab[i] == prefix) {
pcercuei 0:03b5121a232e 1589 /* in scope */
pcercuei 0:03b5121a232e 1590 if (ctxt->nsTab[i + 1] == URL)
pcercuei 0:03b5121a232e 1591 return(-2);
pcercuei 0:03b5121a232e 1592 /* out of scope keep it */
pcercuei 0:03b5121a232e 1593 break;
pcercuei 0:03b5121a232e 1594 }
pcercuei 0:03b5121a232e 1595 }
pcercuei 0:03b5121a232e 1596 }
pcercuei 0:03b5121a232e 1597 if ((ctxt->nsMax == 0) || (ctxt->nsTab == NULL)) {
pcercuei 0:03b5121a232e 1598 ctxt->nsMax = 10;
pcercuei 0:03b5121a232e 1599 ctxt->nsNr = 0;
pcercuei 0:03b5121a232e 1600 ctxt->nsTab = (const xmlChar **)
pcercuei 0:03b5121a232e 1601 xmlMalloc(ctxt->nsMax * sizeof(xmlChar *));
pcercuei 0:03b5121a232e 1602 if (ctxt->nsTab == NULL) {
pcercuei 0:03b5121a232e 1603 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 1604 ctxt->nsMax = 0;
pcercuei 0:03b5121a232e 1605 return (-1);
pcercuei 0:03b5121a232e 1606 }
pcercuei 0:03b5121a232e 1607 } else if (ctxt->nsNr >= ctxt->nsMax) {
pcercuei 0:03b5121a232e 1608 const xmlChar ** tmp;
pcercuei 0:03b5121a232e 1609 ctxt->nsMax *= 2;
pcercuei 0:03b5121a232e 1610 tmp = (const xmlChar **) xmlRealloc((char *) ctxt->nsTab,
pcercuei 0:03b5121a232e 1611 ctxt->nsMax * sizeof(ctxt->nsTab[0]));
pcercuei 0:03b5121a232e 1612 if (tmp == NULL) {
pcercuei 0:03b5121a232e 1613 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 1614 ctxt->nsMax /= 2;
pcercuei 0:03b5121a232e 1615 return (-1);
pcercuei 0:03b5121a232e 1616 }
pcercuei 0:03b5121a232e 1617 ctxt->nsTab = tmp;
pcercuei 0:03b5121a232e 1618 }
pcercuei 0:03b5121a232e 1619 ctxt->nsTab[ctxt->nsNr++] = prefix;
pcercuei 0:03b5121a232e 1620 ctxt->nsTab[ctxt->nsNr++] = URL;
pcercuei 0:03b5121a232e 1621 return (ctxt->nsNr);
pcercuei 0:03b5121a232e 1622 }
pcercuei 0:03b5121a232e 1623 /**
pcercuei 0:03b5121a232e 1624 * nsPop:
pcercuei 0:03b5121a232e 1625 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 1626 * @nr: the number to pop
pcercuei 0:03b5121a232e 1627 *
pcercuei 0:03b5121a232e 1628 * Pops the top @nr parser prefix/namespace from the ns stack
pcercuei 0:03b5121a232e 1629 *
pcercuei 0:03b5121a232e 1630 * Returns the number of namespaces removed
pcercuei 0:03b5121a232e 1631 */
pcercuei 0:03b5121a232e 1632 static int
pcercuei 0:03b5121a232e 1633 nsPop(xmlParserCtxtPtr ctxt, int nr)
pcercuei 0:03b5121a232e 1634 {
pcercuei 0:03b5121a232e 1635 int i;
pcercuei 0:03b5121a232e 1636
pcercuei 0:03b5121a232e 1637 if (ctxt->nsTab == NULL) return(0);
pcercuei 0:03b5121a232e 1638 if (ctxt->nsNr < nr) {
pcercuei 0:03b5121a232e 1639 xmlGenericError(xmlGenericErrorContext, "Pbm popping %d NS\n", nr);
pcercuei 0:03b5121a232e 1640 nr = ctxt->nsNr;
pcercuei 0:03b5121a232e 1641 }
pcercuei 0:03b5121a232e 1642 if (ctxt->nsNr <= 0)
pcercuei 0:03b5121a232e 1643 return (0);
pcercuei 0:03b5121a232e 1644
pcercuei 0:03b5121a232e 1645 for (i = 0;i < nr;i++) {
pcercuei 0:03b5121a232e 1646 ctxt->nsNr--;
pcercuei 0:03b5121a232e 1647 ctxt->nsTab[ctxt->nsNr] = NULL;
pcercuei 0:03b5121a232e 1648 }
pcercuei 0:03b5121a232e 1649 return(nr);
pcercuei 0:03b5121a232e 1650 }
pcercuei 0:03b5121a232e 1651 #endif
pcercuei 0:03b5121a232e 1652
pcercuei 0:03b5121a232e 1653 static int
pcercuei 0:03b5121a232e 1654 xmlCtxtGrowAttrs(xmlParserCtxtPtr ctxt, int nr) {
pcercuei 0:03b5121a232e 1655 const xmlChar **atts;
pcercuei 0:03b5121a232e 1656 int *attallocs;
pcercuei 0:03b5121a232e 1657 int maxatts;
pcercuei 0:03b5121a232e 1658
pcercuei 0:03b5121a232e 1659 if (ctxt->atts == NULL) {
pcercuei 0:03b5121a232e 1660 maxatts = 55; /* allow for 10 attrs by default */
pcercuei 0:03b5121a232e 1661 atts = (const xmlChar **)
pcercuei 0:03b5121a232e 1662 xmlMalloc(maxatts * sizeof(xmlChar *));
pcercuei 0:03b5121a232e 1663 if (atts == NULL) goto mem_error;
pcercuei 0:03b5121a232e 1664 ctxt->atts = atts;
pcercuei 0:03b5121a232e 1665 attallocs = (int *) xmlMalloc((maxatts / 5) * sizeof(int));
pcercuei 0:03b5121a232e 1666 if (attallocs == NULL) goto mem_error;
pcercuei 0:03b5121a232e 1667 ctxt->attallocs = attallocs;
pcercuei 0:03b5121a232e 1668 ctxt->maxatts = maxatts;
pcercuei 0:03b5121a232e 1669 } else if (nr + 5 > ctxt->maxatts) {
pcercuei 0:03b5121a232e 1670 maxatts = (nr + 5) * 2;
pcercuei 0:03b5121a232e 1671 atts = (const xmlChar **) xmlRealloc((void *) ctxt->atts,
pcercuei 0:03b5121a232e 1672 maxatts * sizeof(const xmlChar *));
pcercuei 0:03b5121a232e 1673 if (atts == NULL) goto mem_error;
pcercuei 0:03b5121a232e 1674 ctxt->atts = atts;
pcercuei 0:03b5121a232e 1675 attallocs = (int *) xmlRealloc((void *) ctxt->attallocs,
pcercuei 0:03b5121a232e 1676 (maxatts / 5) * sizeof(int));
pcercuei 0:03b5121a232e 1677 if (attallocs == NULL) goto mem_error;
pcercuei 0:03b5121a232e 1678 ctxt->attallocs = attallocs;
pcercuei 0:03b5121a232e 1679 ctxt->maxatts = maxatts;
pcercuei 0:03b5121a232e 1680 }
pcercuei 0:03b5121a232e 1681 return(ctxt->maxatts);
pcercuei 0:03b5121a232e 1682 mem_error:
pcercuei 0:03b5121a232e 1683 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 1684 return(-1);
pcercuei 0:03b5121a232e 1685 }
pcercuei 0:03b5121a232e 1686
pcercuei 0:03b5121a232e 1687 /**
pcercuei 0:03b5121a232e 1688 * inputPush:
pcercuei 0:03b5121a232e 1689 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 1690 * @value: the parser input
pcercuei 0:03b5121a232e 1691 *
pcercuei 0:03b5121a232e 1692 * Pushes a new parser input on top of the input stack
pcercuei 0:03b5121a232e 1693 *
pcercuei 0:03b5121a232e 1694 * Returns -1 in case of error, the index in the stack otherwise
pcercuei 0:03b5121a232e 1695 */
pcercuei 0:03b5121a232e 1696 int
pcercuei 0:03b5121a232e 1697 inputPush(xmlParserCtxtPtr ctxt, xmlParserInputPtr value)
pcercuei 0:03b5121a232e 1698 {
pcercuei 0:03b5121a232e 1699 if ((ctxt == NULL) || (value == NULL))
pcercuei 0:03b5121a232e 1700 return(-1);
pcercuei 0:03b5121a232e 1701 if (ctxt->inputNr >= ctxt->inputMax) {
pcercuei 0:03b5121a232e 1702 ctxt->inputMax *= 2;
pcercuei 0:03b5121a232e 1703 ctxt->inputTab =
pcercuei 0:03b5121a232e 1704 (xmlParserInputPtr *) xmlRealloc(ctxt->inputTab,
pcercuei 0:03b5121a232e 1705 ctxt->inputMax *
pcercuei 0:03b5121a232e 1706 sizeof(ctxt->inputTab[0]));
pcercuei 0:03b5121a232e 1707 if (ctxt->inputTab == NULL) {
pcercuei 0:03b5121a232e 1708 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 1709 xmlFreeInputStream(value);
pcercuei 0:03b5121a232e 1710 ctxt->inputMax /= 2;
pcercuei 0:03b5121a232e 1711 value = NULL;
pcercuei 0:03b5121a232e 1712 return (-1);
pcercuei 0:03b5121a232e 1713 }
pcercuei 0:03b5121a232e 1714 }
pcercuei 0:03b5121a232e 1715 ctxt->inputTab[ctxt->inputNr] = value;
pcercuei 0:03b5121a232e 1716 ctxt->input = value;
pcercuei 0:03b5121a232e 1717 return (ctxt->inputNr++);
pcercuei 0:03b5121a232e 1718 }
pcercuei 0:03b5121a232e 1719 /**
pcercuei 0:03b5121a232e 1720 * inputPop:
pcercuei 0:03b5121a232e 1721 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 1722 *
pcercuei 0:03b5121a232e 1723 * Pops the top parser input from the input stack
pcercuei 0:03b5121a232e 1724 *
pcercuei 0:03b5121a232e 1725 * Returns the input just removed
pcercuei 0:03b5121a232e 1726 */
pcercuei 0:03b5121a232e 1727 xmlParserInputPtr
pcercuei 0:03b5121a232e 1728 inputPop(xmlParserCtxtPtr ctxt)
pcercuei 0:03b5121a232e 1729 {
pcercuei 0:03b5121a232e 1730 xmlParserInputPtr ret;
pcercuei 0:03b5121a232e 1731
pcercuei 0:03b5121a232e 1732 if (ctxt == NULL)
pcercuei 0:03b5121a232e 1733 return(NULL);
pcercuei 0:03b5121a232e 1734 if (ctxt->inputNr <= 0)
pcercuei 0:03b5121a232e 1735 return (NULL);
pcercuei 0:03b5121a232e 1736 ctxt->inputNr--;
pcercuei 0:03b5121a232e 1737 if (ctxt->inputNr > 0)
pcercuei 0:03b5121a232e 1738 ctxt->input = ctxt->inputTab[ctxt->inputNr - 1];
pcercuei 0:03b5121a232e 1739 else
pcercuei 0:03b5121a232e 1740 ctxt->input = NULL;
pcercuei 0:03b5121a232e 1741 ret = ctxt->inputTab[ctxt->inputNr];
pcercuei 0:03b5121a232e 1742 ctxt->inputTab[ctxt->inputNr] = NULL;
pcercuei 0:03b5121a232e 1743 return (ret);
pcercuei 0:03b5121a232e 1744 }
pcercuei 0:03b5121a232e 1745 /**
pcercuei 0:03b5121a232e 1746 * nodePush:
pcercuei 0:03b5121a232e 1747 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 1748 * @value: the element node
pcercuei 0:03b5121a232e 1749 *
pcercuei 0:03b5121a232e 1750 * Pushes a new element node on top of the node stack
pcercuei 0:03b5121a232e 1751 *
pcercuei 0:03b5121a232e 1752 * Returns -1 in case of error, the index in the stack otherwise
pcercuei 0:03b5121a232e 1753 */
pcercuei 0:03b5121a232e 1754 int
pcercuei 0:03b5121a232e 1755 nodePush(xmlParserCtxtPtr ctxt, xmlNodePtr value)
pcercuei 0:03b5121a232e 1756 {
pcercuei 0:03b5121a232e 1757 if (ctxt == NULL) return(0);
pcercuei 0:03b5121a232e 1758 if (ctxt->nodeNr >= ctxt->nodeMax) {
pcercuei 0:03b5121a232e 1759 xmlNodePtr *tmp;
pcercuei 0:03b5121a232e 1760
pcercuei 0:03b5121a232e 1761 tmp = (xmlNodePtr *) xmlRealloc(ctxt->nodeTab,
pcercuei 0:03b5121a232e 1762 ctxt->nodeMax * 2 *
pcercuei 0:03b5121a232e 1763 sizeof(ctxt->nodeTab[0]));
pcercuei 0:03b5121a232e 1764 if (tmp == NULL) {
pcercuei 0:03b5121a232e 1765 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 1766 return (-1);
pcercuei 0:03b5121a232e 1767 }
pcercuei 0:03b5121a232e 1768 ctxt->nodeTab = tmp;
pcercuei 0:03b5121a232e 1769 ctxt->nodeMax *= 2;
pcercuei 0:03b5121a232e 1770 }
pcercuei 0:03b5121a232e 1771 if ((((unsigned int) ctxt->nodeNr) > xmlParserMaxDepth) &&
pcercuei 0:03b5121a232e 1772 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
pcercuei 0:03b5121a232e 1773 xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
pcercuei 0:03b5121a232e 1774 "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
pcercuei 0:03b5121a232e 1775 xmlParserMaxDepth);
pcercuei 0:03b5121a232e 1776 xmlHaltParser(ctxt);
pcercuei 0:03b5121a232e 1777 return(-1);
pcercuei 0:03b5121a232e 1778 }
pcercuei 0:03b5121a232e 1779 ctxt->nodeTab[ctxt->nodeNr] = value;
pcercuei 0:03b5121a232e 1780 ctxt->node = value;
pcercuei 0:03b5121a232e 1781 return (ctxt->nodeNr++);
pcercuei 0:03b5121a232e 1782 }
pcercuei 0:03b5121a232e 1783
pcercuei 0:03b5121a232e 1784 /**
pcercuei 0:03b5121a232e 1785 * nodePop:
pcercuei 0:03b5121a232e 1786 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 1787 *
pcercuei 0:03b5121a232e 1788 * Pops the top element node from the node stack
pcercuei 0:03b5121a232e 1789 *
pcercuei 0:03b5121a232e 1790 * Returns the node just removed
pcercuei 0:03b5121a232e 1791 */
pcercuei 0:03b5121a232e 1792 xmlNodePtr
pcercuei 0:03b5121a232e 1793 nodePop(xmlParserCtxtPtr ctxt)
pcercuei 0:03b5121a232e 1794 {
pcercuei 0:03b5121a232e 1795 xmlNodePtr ret;
pcercuei 0:03b5121a232e 1796
pcercuei 0:03b5121a232e 1797 if (ctxt == NULL) return(NULL);
pcercuei 0:03b5121a232e 1798 if (ctxt->nodeNr <= 0)
pcercuei 0:03b5121a232e 1799 return (NULL);
pcercuei 0:03b5121a232e 1800 ctxt->nodeNr--;
pcercuei 0:03b5121a232e 1801 if (ctxt->nodeNr > 0)
pcercuei 0:03b5121a232e 1802 ctxt->node = ctxt->nodeTab[ctxt->nodeNr - 1];
pcercuei 0:03b5121a232e 1803 else
pcercuei 0:03b5121a232e 1804 ctxt->node = NULL;
pcercuei 0:03b5121a232e 1805 ret = ctxt->nodeTab[ctxt->nodeNr];
pcercuei 0:03b5121a232e 1806 ctxt->nodeTab[ctxt->nodeNr] = NULL;
pcercuei 0:03b5121a232e 1807 return (ret);
pcercuei 0:03b5121a232e 1808 }
pcercuei 0:03b5121a232e 1809
pcercuei 0:03b5121a232e 1810 #ifdef LIBXML_PUSH_ENABLED
pcercuei 0:03b5121a232e 1811 /**
pcercuei 0:03b5121a232e 1812 * nameNsPush:
pcercuei 0:03b5121a232e 1813 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 1814 * @value: the element name
pcercuei 0:03b5121a232e 1815 * @prefix: the element prefix
pcercuei 0:03b5121a232e 1816 * @URI: the element namespace name
pcercuei 0:03b5121a232e 1817 *
pcercuei 0:03b5121a232e 1818 * Pushes a new element name/prefix/URL on top of the name stack
pcercuei 0:03b5121a232e 1819 *
pcercuei 0:03b5121a232e 1820 * Returns -1 in case of error, the index in the stack otherwise
pcercuei 0:03b5121a232e 1821 */
pcercuei 0:03b5121a232e 1822 static int
pcercuei 0:03b5121a232e 1823 nameNsPush(xmlParserCtxtPtr ctxt, const xmlChar * value,
pcercuei 0:03b5121a232e 1824 const xmlChar *prefix, const xmlChar *URI, int nsNr)
pcercuei 0:03b5121a232e 1825 {
pcercuei 0:03b5121a232e 1826 if (ctxt->nameNr >= ctxt->nameMax) {
pcercuei 0:03b5121a232e 1827 const xmlChar * *tmp;
pcercuei 0:03b5121a232e 1828 void **tmp2;
pcercuei 0:03b5121a232e 1829 ctxt->nameMax *= 2;
pcercuei 0:03b5121a232e 1830 tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab,
pcercuei 0:03b5121a232e 1831 ctxt->nameMax *
pcercuei 0:03b5121a232e 1832 sizeof(ctxt->nameTab[0]));
pcercuei 0:03b5121a232e 1833 if (tmp == NULL) {
pcercuei 0:03b5121a232e 1834 ctxt->nameMax /= 2;
pcercuei 0:03b5121a232e 1835 goto mem_error;
pcercuei 0:03b5121a232e 1836 }
pcercuei 0:03b5121a232e 1837 ctxt->nameTab = tmp;
pcercuei 0:03b5121a232e 1838 tmp2 = (void **) xmlRealloc((void * *)ctxt->pushTab,
pcercuei 0:03b5121a232e 1839 ctxt->nameMax * 3 *
pcercuei 0:03b5121a232e 1840 sizeof(ctxt->pushTab[0]));
pcercuei 0:03b5121a232e 1841 if (tmp2 == NULL) {
pcercuei 0:03b5121a232e 1842 ctxt->nameMax /= 2;
pcercuei 0:03b5121a232e 1843 goto mem_error;
pcercuei 0:03b5121a232e 1844 }
pcercuei 0:03b5121a232e 1845 ctxt->pushTab = tmp2;
pcercuei 0:03b5121a232e 1846 }
pcercuei 0:03b5121a232e 1847 ctxt->nameTab[ctxt->nameNr] = value;
pcercuei 0:03b5121a232e 1848 ctxt->name = value;
pcercuei 0:03b5121a232e 1849 ctxt->pushTab[ctxt->nameNr * 3] = (void *) prefix;
pcercuei 0:03b5121a232e 1850 ctxt->pushTab[ctxt->nameNr * 3 + 1] = (void *) URI;
pcercuei 0:03b5121a232e 1851 ctxt->pushTab[ctxt->nameNr * 3 + 2] = (void *) (long) nsNr;
pcercuei 0:03b5121a232e 1852 return (ctxt->nameNr++);
pcercuei 0:03b5121a232e 1853 mem_error:
pcercuei 0:03b5121a232e 1854 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 1855 return (-1);
pcercuei 0:03b5121a232e 1856 }
pcercuei 0:03b5121a232e 1857 /**
pcercuei 0:03b5121a232e 1858 * nameNsPop:
pcercuei 0:03b5121a232e 1859 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 1860 *
pcercuei 0:03b5121a232e 1861 * Pops the top element/prefix/URI name from the name stack
pcercuei 0:03b5121a232e 1862 *
pcercuei 0:03b5121a232e 1863 * Returns the name just removed
pcercuei 0:03b5121a232e 1864 */
pcercuei 0:03b5121a232e 1865 static const xmlChar *
pcercuei 0:03b5121a232e 1866 nameNsPop(xmlParserCtxtPtr ctxt)
pcercuei 0:03b5121a232e 1867 {
pcercuei 0:03b5121a232e 1868 const xmlChar *ret;
pcercuei 0:03b5121a232e 1869
pcercuei 0:03b5121a232e 1870 if (ctxt->nameNr <= 0)
pcercuei 0:03b5121a232e 1871 return (NULL);
pcercuei 0:03b5121a232e 1872 ctxt->nameNr--;
pcercuei 0:03b5121a232e 1873 if (ctxt->nameNr > 0)
pcercuei 0:03b5121a232e 1874 ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
pcercuei 0:03b5121a232e 1875 else
pcercuei 0:03b5121a232e 1876 ctxt->name = NULL;
pcercuei 0:03b5121a232e 1877 ret = ctxt->nameTab[ctxt->nameNr];
pcercuei 0:03b5121a232e 1878 ctxt->nameTab[ctxt->nameNr] = NULL;
pcercuei 0:03b5121a232e 1879 return (ret);
pcercuei 0:03b5121a232e 1880 }
pcercuei 0:03b5121a232e 1881 #endif /* LIBXML_PUSH_ENABLED */
pcercuei 0:03b5121a232e 1882
pcercuei 0:03b5121a232e 1883 /**
pcercuei 0:03b5121a232e 1884 * namePush:
pcercuei 0:03b5121a232e 1885 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 1886 * @value: the element name
pcercuei 0:03b5121a232e 1887 *
pcercuei 0:03b5121a232e 1888 * Pushes a new element name on top of the name stack
pcercuei 0:03b5121a232e 1889 *
pcercuei 0:03b5121a232e 1890 * Returns -1 in case of error, the index in the stack otherwise
pcercuei 0:03b5121a232e 1891 */
pcercuei 0:03b5121a232e 1892 int
pcercuei 0:03b5121a232e 1893 namePush(xmlParserCtxtPtr ctxt, const xmlChar * value)
pcercuei 0:03b5121a232e 1894 {
pcercuei 0:03b5121a232e 1895 if (ctxt == NULL) return (-1);
pcercuei 0:03b5121a232e 1896
pcercuei 0:03b5121a232e 1897 if (ctxt->nameNr >= ctxt->nameMax) {
pcercuei 0:03b5121a232e 1898 const xmlChar * *tmp;
pcercuei 0:03b5121a232e 1899 tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab,
pcercuei 0:03b5121a232e 1900 ctxt->nameMax * 2 *
pcercuei 0:03b5121a232e 1901 sizeof(ctxt->nameTab[0]));
pcercuei 0:03b5121a232e 1902 if (tmp == NULL) {
pcercuei 0:03b5121a232e 1903 goto mem_error;
pcercuei 0:03b5121a232e 1904 }
pcercuei 0:03b5121a232e 1905 ctxt->nameTab = tmp;
pcercuei 0:03b5121a232e 1906 ctxt->nameMax *= 2;
pcercuei 0:03b5121a232e 1907 }
pcercuei 0:03b5121a232e 1908 ctxt->nameTab[ctxt->nameNr] = value;
pcercuei 0:03b5121a232e 1909 ctxt->name = value;
pcercuei 0:03b5121a232e 1910 return (ctxt->nameNr++);
pcercuei 0:03b5121a232e 1911 mem_error:
pcercuei 0:03b5121a232e 1912 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 1913 return (-1);
pcercuei 0:03b5121a232e 1914 }
pcercuei 0:03b5121a232e 1915 /**
pcercuei 0:03b5121a232e 1916 * namePop:
pcercuei 0:03b5121a232e 1917 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 1918 *
pcercuei 0:03b5121a232e 1919 * Pops the top element name from the name stack
pcercuei 0:03b5121a232e 1920 *
pcercuei 0:03b5121a232e 1921 * Returns the name just removed
pcercuei 0:03b5121a232e 1922 */
pcercuei 0:03b5121a232e 1923 const xmlChar *
pcercuei 0:03b5121a232e 1924 namePop(xmlParserCtxtPtr ctxt)
pcercuei 0:03b5121a232e 1925 {
pcercuei 0:03b5121a232e 1926 const xmlChar *ret;
pcercuei 0:03b5121a232e 1927
pcercuei 0:03b5121a232e 1928 if ((ctxt == NULL) || (ctxt->nameNr <= 0))
pcercuei 0:03b5121a232e 1929 return (NULL);
pcercuei 0:03b5121a232e 1930 ctxt->nameNr--;
pcercuei 0:03b5121a232e 1931 if (ctxt->nameNr > 0)
pcercuei 0:03b5121a232e 1932 ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
pcercuei 0:03b5121a232e 1933 else
pcercuei 0:03b5121a232e 1934 ctxt->name = NULL;
pcercuei 0:03b5121a232e 1935 ret = ctxt->nameTab[ctxt->nameNr];
pcercuei 0:03b5121a232e 1936 ctxt->nameTab[ctxt->nameNr] = NULL;
pcercuei 0:03b5121a232e 1937 return (ret);
pcercuei 0:03b5121a232e 1938 }
pcercuei 0:03b5121a232e 1939
pcercuei 0:03b5121a232e 1940 static int spacePush(xmlParserCtxtPtr ctxt, int val) {
pcercuei 0:03b5121a232e 1941 if (ctxt->spaceNr >= ctxt->spaceMax) {
pcercuei 0:03b5121a232e 1942 int *tmp;
pcercuei 0:03b5121a232e 1943
pcercuei 0:03b5121a232e 1944 ctxt->spaceMax *= 2;
pcercuei 0:03b5121a232e 1945 tmp = (int *) xmlRealloc(ctxt->spaceTab,
pcercuei 0:03b5121a232e 1946 ctxt->spaceMax * sizeof(ctxt->spaceTab[0]));
pcercuei 0:03b5121a232e 1947 if (tmp == NULL) {
pcercuei 0:03b5121a232e 1948 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 1949 ctxt->spaceMax /=2;
pcercuei 0:03b5121a232e 1950 return(-1);
pcercuei 0:03b5121a232e 1951 }
pcercuei 0:03b5121a232e 1952 ctxt->spaceTab = tmp;
pcercuei 0:03b5121a232e 1953 }
pcercuei 0:03b5121a232e 1954 ctxt->spaceTab[ctxt->spaceNr] = val;
pcercuei 0:03b5121a232e 1955 ctxt->space = &ctxt->spaceTab[ctxt->spaceNr];
pcercuei 0:03b5121a232e 1956 return(ctxt->spaceNr++);
pcercuei 0:03b5121a232e 1957 }
pcercuei 0:03b5121a232e 1958
pcercuei 0:03b5121a232e 1959 static int spacePop(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 1960 int ret;
pcercuei 0:03b5121a232e 1961 if (ctxt->spaceNr <= 0) return(0);
pcercuei 0:03b5121a232e 1962 ctxt->spaceNr--;
pcercuei 0:03b5121a232e 1963 if (ctxt->spaceNr > 0)
pcercuei 0:03b5121a232e 1964 ctxt->space = &ctxt->spaceTab[ctxt->spaceNr - 1];
pcercuei 0:03b5121a232e 1965 else
pcercuei 0:03b5121a232e 1966 ctxt->space = &ctxt->spaceTab[0];
pcercuei 0:03b5121a232e 1967 ret = ctxt->spaceTab[ctxt->spaceNr];
pcercuei 0:03b5121a232e 1968 ctxt->spaceTab[ctxt->spaceNr] = -1;
pcercuei 0:03b5121a232e 1969 return(ret);
pcercuei 0:03b5121a232e 1970 }
pcercuei 0:03b5121a232e 1971
pcercuei 0:03b5121a232e 1972 /*
pcercuei 0:03b5121a232e 1973 * Macros for accessing the content. Those should be used only by the parser,
pcercuei 0:03b5121a232e 1974 * and not exported.
pcercuei 0:03b5121a232e 1975 *
pcercuei 0:03b5121a232e 1976 * Dirty macros, i.e. one often need to make assumption on the context to
pcercuei 0:03b5121a232e 1977 * use them
pcercuei 0:03b5121a232e 1978 *
pcercuei 0:03b5121a232e 1979 * CUR_PTR return the current pointer to the xmlChar to be parsed.
pcercuei 0:03b5121a232e 1980 * To be used with extreme caution since operations consuming
pcercuei 0:03b5121a232e 1981 * characters may move the input buffer to a different location !
pcercuei 0:03b5121a232e 1982 * CUR returns the current xmlChar value, i.e. a 8 bit value if compiled
pcercuei 0:03b5121a232e 1983 * This should be used internally by the parser
pcercuei 0:03b5121a232e 1984 * only to compare to ASCII values otherwise it would break when
pcercuei 0:03b5121a232e 1985 * running with UTF-8 encoding.
pcercuei 0:03b5121a232e 1986 * RAW same as CUR but in the input buffer, bypass any token
pcercuei 0:03b5121a232e 1987 * extraction that may have been done
pcercuei 0:03b5121a232e 1988 * NXT(n) returns the n'th next xmlChar. Same as CUR is should be used only
pcercuei 0:03b5121a232e 1989 * to compare on ASCII based substring.
pcercuei 0:03b5121a232e 1990 * SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
pcercuei 0:03b5121a232e 1991 * strings without newlines within the parser.
pcercuei 0:03b5121a232e 1992 * NEXT1(l) Skip 1 xmlChar, and must also be used only to skip 1 non-newline ASCII
pcercuei 0:03b5121a232e 1993 * defined char within the parser.
pcercuei 0:03b5121a232e 1994 * Clean macros, not dependent of an ASCII context, expect UTF-8 encoding
pcercuei 0:03b5121a232e 1995 *
pcercuei 0:03b5121a232e 1996 * NEXT Skip to the next character, this does the proper decoding
pcercuei 0:03b5121a232e 1997 * in UTF-8 mode. It also pop-up unfinished entities on the fly.
pcercuei 0:03b5121a232e 1998 * NEXTL(l) Skip the current unicode character of l xmlChars long.
pcercuei 0:03b5121a232e 1999 * CUR_CHAR(l) returns the current unicode character (int), set l
pcercuei 0:03b5121a232e 2000 * to the number of xmlChars used for the encoding [0-5].
pcercuei 0:03b5121a232e 2001 * CUR_SCHAR same but operate on a string instead of the context
pcercuei 0:03b5121a232e 2002 * COPY_BUF copy the current unicode char to the target buffer, increment
pcercuei 0:03b5121a232e 2003 * the index
pcercuei 0:03b5121a232e 2004 * GROW, SHRINK handling of input buffers
pcercuei 0:03b5121a232e 2005 */
pcercuei 0:03b5121a232e 2006
pcercuei 0:03b5121a232e 2007 #define RAW (*ctxt->input->cur)
pcercuei 0:03b5121a232e 2008 #define CUR (*ctxt->input->cur)
pcercuei 0:03b5121a232e 2009 #define NXT(val) ctxt->input->cur[(val)]
pcercuei 0:03b5121a232e 2010 #define CUR_PTR ctxt->input->cur
pcercuei 0:03b5121a232e 2011
pcercuei 0:03b5121a232e 2012 #define CMP4( s, c1, c2, c3, c4 ) \
pcercuei 0:03b5121a232e 2013 ( ((unsigned char *) s)[ 0 ] == c1 && ((unsigned char *) s)[ 1 ] == c2 && \
pcercuei 0:03b5121a232e 2014 ((unsigned char *) s)[ 2 ] == c3 && ((unsigned char *) s)[ 3 ] == c4 )
pcercuei 0:03b5121a232e 2015 #define CMP5( s, c1, c2, c3, c4, c5 ) \
pcercuei 0:03b5121a232e 2016 ( CMP4( s, c1, c2, c3, c4 ) && ((unsigned char *) s)[ 4 ] == c5 )
pcercuei 0:03b5121a232e 2017 #define CMP6( s, c1, c2, c3, c4, c5, c6 ) \
pcercuei 0:03b5121a232e 2018 ( CMP5( s, c1, c2, c3, c4, c5 ) && ((unsigned char *) s)[ 5 ] == c6 )
pcercuei 0:03b5121a232e 2019 #define CMP7( s, c1, c2, c3, c4, c5, c6, c7 ) \
pcercuei 0:03b5121a232e 2020 ( CMP6( s, c1, c2, c3, c4, c5, c6 ) && ((unsigned char *) s)[ 6 ] == c7 )
pcercuei 0:03b5121a232e 2021 #define CMP8( s, c1, c2, c3, c4, c5, c6, c7, c8 ) \
pcercuei 0:03b5121a232e 2022 ( CMP7( s, c1, c2, c3, c4, c5, c6, c7 ) && ((unsigned char *) s)[ 7 ] == c8 )
pcercuei 0:03b5121a232e 2023 #define CMP9( s, c1, c2, c3, c4, c5, c6, c7, c8, c9 ) \
pcercuei 0:03b5121a232e 2024 ( CMP8( s, c1, c2, c3, c4, c5, c6, c7, c8 ) && \
pcercuei 0:03b5121a232e 2025 ((unsigned char *) s)[ 8 ] == c9 )
pcercuei 0:03b5121a232e 2026 #define CMP10( s, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10 ) \
pcercuei 0:03b5121a232e 2027 ( CMP9( s, c1, c2, c3, c4, c5, c6, c7, c8, c9 ) && \
pcercuei 0:03b5121a232e 2028 ((unsigned char *) s)[ 9 ] == c10 )
pcercuei 0:03b5121a232e 2029
pcercuei 0:03b5121a232e 2030 #define SKIP(val) do { \
pcercuei 0:03b5121a232e 2031 ctxt->nbChars += (val),ctxt->input->cur += (val),ctxt->input->col+=(val); \
pcercuei 0:03b5121a232e 2032 if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt); \
pcercuei 0:03b5121a232e 2033 if ((*ctxt->input->cur == 0) && \
pcercuei 0:03b5121a232e 2034 (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) \
pcercuei 0:03b5121a232e 2035 xmlPopInput(ctxt); \
pcercuei 0:03b5121a232e 2036 } while (0)
pcercuei 0:03b5121a232e 2037
pcercuei 0:03b5121a232e 2038 #define SKIPL(val) do { \
pcercuei 0:03b5121a232e 2039 int skipl; \
pcercuei 0:03b5121a232e 2040 for(skipl=0; skipl<val; skipl++) { \
pcercuei 0:03b5121a232e 2041 if (*(ctxt->input->cur) == '\n') { \
pcercuei 0:03b5121a232e 2042 ctxt->input->line++; ctxt->input->col = 1; \
pcercuei 0:03b5121a232e 2043 } else ctxt->input->col++; \
pcercuei 0:03b5121a232e 2044 ctxt->nbChars++; \
pcercuei 0:03b5121a232e 2045 ctxt->input->cur++; \
pcercuei 0:03b5121a232e 2046 } \
pcercuei 0:03b5121a232e 2047 if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt); \
pcercuei 0:03b5121a232e 2048 if ((*ctxt->input->cur == 0) && \
pcercuei 0:03b5121a232e 2049 (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) \
pcercuei 0:03b5121a232e 2050 xmlPopInput(ctxt); \
pcercuei 0:03b5121a232e 2051 } while (0)
pcercuei 0:03b5121a232e 2052
pcercuei 0:03b5121a232e 2053 #define SHRINK if ((ctxt->progressive == 0) && \
pcercuei 0:03b5121a232e 2054 (ctxt->input->cur - ctxt->input->base > 2 * INPUT_CHUNK) && \
pcercuei 0:03b5121a232e 2055 (ctxt->input->end - ctxt->input->cur < 2 * INPUT_CHUNK)) \
pcercuei 0:03b5121a232e 2056 xmlSHRINK (ctxt);
pcercuei 0:03b5121a232e 2057
pcercuei 0:03b5121a232e 2058 static void xmlSHRINK (xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 2059 xmlParserInputShrink(ctxt->input);
pcercuei 0:03b5121a232e 2060 if ((*ctxt->input->cur == 0) &&
pcercuei 0:03b5121a232e 2061 (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
pcercuei 0:03b5121a232e 2062 xmlPopInput(ctxt);
pcercuei 0:03b5121a232e 2063 }
pcercuei 0:03b5121a232e 2064
pcercuei 0:03b5121a232e 2065 #define GROW if ((ctxt->progressive == 0) && \
pcercuei 0:03b5121a232e 2066 (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK)) \
pcercuei 0:03b5121a232e 2067 xmlGROW (ctxt);
pcercuei 0:03b5121a232e 2068
pcercuei 0:03b5121a232e 2069 static void xmlGROW (xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 2070 unsigned long curEnd = ctxt->input->end - ctxt->input->cur;
pcercuei 0:03b5121a232e 2071 unsigned long curBase = ctxt->input->cur - ctxt->input->base;
pcercuei 0:03b5121a232e 2072
pcercuei 0:03b5121a232e 2073 if (((curEnd > (unsigned long) XML_MAX_LOOKUP_LIMIT) ||
pcercuei 0:03b5121a232e 2074 (curBase > (unsigned long) XML_MAX_LOOKUP_LIMIT)) &&
pcercuei 0:03b5121a232e 2075 ((ctxt->input->buf) && (ctxt->input->buf->readcallback != (xmlInputReadCallback) xmlNop)) &&
pcercuei 0:03b5121a232e 2076 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
pcercuei 0:03b5121a232e 2077 xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "Huge input lookup");
pcercuei 0:03b5121a232e 2078 xmlHaltParser(ctxt);
pcercuei 0:03b5121a232e 2079 return;
pcercuei 0:03b5121a232e 2080 }
pcercuei 0:03b5121a232e 2081 xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
pcercuei 0:03b5121a232e 2082 if ((ctxt->input->cur > ctxt->input->end) ||
pcercuei 0:03b5121a232e 2083 (ctxt->input->cur < ctxt->input->base)) {
pcercuei 0:03b5121a232e 2084 xmlHaltParser(ctxt);
pcercuei 0:03b5121a232e 2085 xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "cur index out of bound");
pcercuei 0:03b5121a232e 2086 return;
pcercuei 0:03b5121a232e 2087 }
pcercuei 0:03b5121a232e 2088 if ((ctxt->input->cur != NULL) && (*ctxt->input->cur == 0) &&
pcercuei 0:03b5121a232e 2089 (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
pcercuei 0:03b5121a232e 2090 xmlPopInput(ctxt);
pcercuei 0:03b5121a232e 2091 }
pcercuei 0:03b5121a232e 2092
pcercuei 0:03b5121a232e 2093 #define SKIP_BLANKS xmlSkipBlankChars(ctxt)
pcercuei 0:03b5121a232e 2094
pcercuei 0:03b5121a232e 2095 #define NEXT xmlNextChar(ctxt)
pcercuei 0:03b5121a232e 2096
pcercuei 0:03b5121a232e 2097 #define NEXT1 { \
pcercuei 0:03b5121a232e 2098 ctxt->input->col++; \
pcercuei 0:03b5121a232e 2099 ctxt->input->cur++; \
pcercuei 0:03b5121a232e 2100 ctxt->nbChars++; \
pcercuei 0:03b5121a232e 2101 if (*ctxt->input->cur == 0) \
pcercuei 0:03b5121a232e 2102 xmlParserInputGrow(ctxt->input, INPUT_CHUNK); \
pcercuei 0:03b5121a232e 2103 }
pcercuei 0:03b5121a232e 2104
pcercuei 0:03b5121a232e 2105 #define NEXTL(l) do { \
pcercuei 0:03b5121a232e 2106 if (*(ctxt->input->cur) == '\n') { \
pcercuei 0:03b5121a232e 2107 ctxt->input->line++; ctxt->input->col = 1; \
pcercuei 0:03b5121a232e 2108 } else ctxt->input->col++; \
pcercuei 0:03b5121a232e 2109 ctxt->input->cur += l; \
pcercuei 0:03b5121a232e 2110 if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt); \
pcercuei 0:03b5121a232e 2111 } while (0)
pcercuei 0:03b5121a232e 2112
pcercuei 0:03b5121a232e 2113 #define CUR_CHAR(l) xmlCurrentChar(ctxt, &l)
pcercuei 0:03b5121a232e 2114 #define CUR_SCHAR(s, l) xmlStringCurrentChar(ctxt, s, &l)
pcercuei 0:03b5121a232e 2115
pcercuei 0:03b5121a232e 2116 #define COPY_BUF(l,b,i,v) \
pcercuei 0:03b5121a232e 2117 if (l == 1) b[i++] = (xmlChar) v; \
pcercuei 0:03b5121a232e 2118 else i += xmlCopyCharMultiByte(&b[i],v)
pcercuei 0:03b5121a232e 2119
pcercuei 0:03b5121a232e 2120 /**
pcercuei 0:03b5121a232e 2121 * xmlSkipBlankChars:
pcercuei 0:03b5121a232e 2122 * @ctxt: the XML parser context
pcercuei 0:03b5121a232e 2123 *
pcercuei 0:03b5121a232e 2124 * skip all blanks character found at that point in the input streams.
pcercuei 0:03b5121a232e 2125 * It pops up finished entities in the process if allowable at that point.
pcercuei 0:03b5121a232e 2126 *
pcercuei 0:03b5121a232e 2127 * Returns the number of space chars skipped
pcercuei 0:03b5121a232e 2128 */
pcercuei 0:03b5121a232e 2129
pcercuei 0:03b5121a232e 2130 int
pcercuei 0:03b5121a232e 2131 xmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 2132 int res = 0;
pcercuei 0:03b5121a232e 2133
pcercuei 0:03b5121a232e 2134 /*
pcercuei 0:03b5121a232e 2135 * It's Okay to use CUR/NEXT here since all the blanks are on
pcercuei 0:03b5121a232e 2136 * the ASCII range.
pcercuei 0:03b5121a232e 2137 */
pcercuei 0:03b5121a232e 2138 if ((ctxt->inputNr == 1) && (ctxt->instate != XML_PARSER_DTD)) {
pcercuei 0:03b5121a232e 2139 const xmlChar *cur;
pcercuei 0:03b5121a232e 2140 /*
pcercuei 0:03b5121a232e 2141 * if we are in the document content, go really fast
pcercuei 0:03b5121a232e 2142 */
pcercuei 0:03b5121a232e 2143 cur = ctxt->input->cur;
pcercuei 0:03b5121a232e 2144 while (IS_BLANK_CH(*cur)) {
pcercuei 0:03b5121a232e 2145 if (*cur == '\n') {
pcercuei 0:03b5121a232e 2146 ctxt->input->line++; ctxt->input->col = 1;
pcercuei 0:03b5121a232e 2147 } else {
pcercuei 0:03b5121a232e 2148 ctxt->input->col++;
pcercuei 0:03b5121a232e 2149 }
pcercuei 0:03b5121a232e 2150 cur++;
pcercuei 0:03b5121a232e 2151 res++;
pcercuei 0:03b5121a232e 2152 if (*cur == 0) {
pcercuei 0:03b5121a232e 2153 ctxt->input->cur = cur;
pcercuei 0:03b5121a232e 2154 xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
pcercuei 0:03b5121a232e 2155 cur = ctxt->input->cur;
pcercuei 0:03b5121a232e 2156 }
pcercuei 0:03b5121a232e 2157 }
pcercuei 0:03b5121a232e 2158 ctxt->input->cur = cur;
pcercuei 0:03b5121a232e 2159 } else {
pcercuei 0:03b5121a232e 2160 int cur;
pcercuei 0:03b5121a232e 2161 do {
pcercuei 0:03b5121a232e 2162 cur = CUR;
pcercuei 0:03b5121a232e 2163 while ((IS_BLANK_CH(cur) && /* CHECKED tstblanks.xml */
pcercuei 0:03b5121a232e 2164 (ctxt->instate != XML_PARSER_EOF))) {
pcercuei 0:03b5121a232e 2165 NEXT;
pcercuei 0:03b5121a232e 2166 cur = CUR;
pcercuei 0:03b5121a232e 2167 res++;
pcercuei 0:03b5121a232e 2168 }
pcercuei 0:03b5121a232e 2169 while ((cur == 0) && (ctxt->inputNr > 1) &&
pcercuei 0:03b5121a232e 2170 (ctxt->instate != XML_PARSER_COMMENT)) {
pcercuei 0:03b5121a232e 2171 xmlPopInput(ctxt);
pcercuei 0:03b5121a232e 2172 cur = CUR;
pcercuei 0:03b5121a232e 2173 }
pcercuei 0:03b5121a232e 2174 /*
pcercuei 0:03b5121a232e 2175 * Need to handle support of entities branching here
pcercuei 0:03b5121a232e 2176 */
pcercuei 0:03b5121a232e 2177 if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);
pcercuei 0:03b5121a232e 2178 } while ((IS_BLANK(cur)) && /* CHECKED tstblanks.xml */
pcercuei 0:03b5121a232e 2179 (ctxt->instate != XML_PARSER_EOF));
pcercuei 0:03b5121a232e 2180 }
pcercuei 0:03b5121a232e 2181 return(res);
pcercuei 0:03b5121a232e 2182 }
pcercuei 0:03b5121a232e 2183
pcercuei 0:03b5121a232e 2184 /************************************************************************
pcercuei 0:03b5121a232e 2185 * *
pcercuei 0:03b5121a232e 2186 * Commodity functions to handle entities *
pcercuei 0:03b5121a232e 2187 * *
pcercuei 0:03b5121a232e 2188 ************************************************************************/
pcercuei 0:03b5121a232e 2189
pcercuei 0:03b5121a232e 2190 /**
pcercuei 0:03b5121a232e 2191 * xmlPopInput:
pcercuei 0:03b5121a232e 2192 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 2193 *
pcercuei 0:03b5121a232e 2194 * xmlPopInput: the current input pointed by ctxt->input came to an end
pcercuei 0:03b5121a232e 2195 * pop it and return the next char.
pcercuei 0:03b5121a232e 2196 *
pcercuei 0:03b5121a232e 2197 * Returns the current xmlChar in the parser context
pcercuei 0:03b5121a232e 2198 */
pcercuei 0:03b5121a232e 2199 xmlChar
pcercuei 0:03b5121a232e 2200 xmlPopInput(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 2201 if ((ctxt == NULL) || (ctxt->inputNr <= 1)) return(0);
pcercuei 0:03b5121a232e 2202 if (xmlParserDebugEntities)
pcercuei 0:03b5121a232e 2203 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 2204 "Popping input %d\n", ctxt->inputNr);
pcercuei 0:03b5121a232e 2205 xmlFreeInputStream(inputPop(ctxt));
pcercuei 0:03b5121a232e 2206 if ((*ctxt->input->cur == 0) &&
pcercuei 0:03b5121a232e 2207 (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
pcercuei 0:03b5121a232e 2208 return(xmlPopInput(ctxt));
pcercuei 0:03b5121a232e 2209 return(CUR);
pcercuei 0:03b5121a232e 2210 }
pcercuei 0:03b5121a232e 2211
pcercuei 0:03b5121a232e 2212 /**
pcercuei 0:03b5121a232e 2213 * xmlPushInput:
pcercuei 0:03b5121a232e 2214 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 2215 * @input: an XML parser input fragment (entity, XML fragment ...).
pcercuei 0:03b5121a232e 2216 *
pcercuei 0:03b5121a232e 2217 * xmlPushInput: switch to a new input stream which is stacked on top
pcercuei 0:03b5121a232e 2218 * of the previous one(s).
pcercuei 0:03b5121a232e 2219 * Returns -1 in case of error or the index in the input stack
pcercuei 0:03b5121a232e 2220 */
pcercuei 0:03b5121a232e 2221 int
pcercuei 0:03b5121a232e 2222 xmlPushInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr input) {
pcercuei 0:03b5121a232e 2223 int ret;
pcercuei 0:03b5121a232e 2224 if (input == NULL) return(-1);
pcercuei 0:03b5121a232e 2225
pcercuei 0:03b5121a232e 2226 if (xmlParserDebugEntities) {
pcercuei 0:03b5121a232e 2227 if ((ctxt->input != NULL) && (ctxt->input->filename))
pcercuei 0:03b5121a232e 2228 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 2229 "%s(%d): ", ctxt->input->filename,
pcercuei 0:03b5121a232e 2230 ctxt->input->line);
pcercuei 0:03b5121a232e 2231 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 2232 "Pushing input %d : %.30s\n", ctxt->inputNr+1, input->cur);
pcercuei 0:03b5121a232e 2233 }
pcercuei 0:03b5121a232e 2234 ret = inputPush(ctxt, input);
pcercuei 0:03b5121a232e 2235 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 2236 return(-1);
pcercuei 0:03b5121a232e 2237 GROW;
pcercuei 0:03b5121a232e 2238 return(ret);
pcercuei 0:03b5121a232e 2239 }
pcercuei 0:03b5121a232e 2240
pcercuei 0:03b5121a232e 2241 /**
pcercuei 0:03b5121a232e 2242 * xmlParseCharRef:
pcercuei 0:03b5121a232e 2243 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 2244 *
pcercuei 0:03b5121a232e 2245 * parse Reference declarations
pcercuei 0:03b5121a232e 2246 *
pcercuei 0:03b5121a232e 2247 * [66] CharRef ::= '&#' [0-9]+ ';' |
pcercuei 0:03b5121a232e 2248 * '&#x' [0-9a-fA-F]+ ';'
pcercuei 0:03b5121a232e 2249 *
pcercuei 0:03b5121a232e 2250 * [ WFC: Legal Character ]
pcercuei 0:03b5121a232e 2251 * Characters referred to using character references must match the
pcercuei 0:03b5121a232e 2252 * production for Char.
pcercuei 0:03b5121a232e 2253 *
pcercuei 0:03b5121a232e 2254 * Returns the value parsed (as an int), 0 in case of error
pcercuei 0:03b5121a232e 2255 */
pcercuei 0:03b5121a232e 2256 int
pcercuei 0:03b5121a232e 2257 xmlParseCharRef(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 2258 unsigned int val = 0;
pcercuei 0:03b5121a232e 2259 int count = 0;
pcercuei 0:03b5121a232e 2260 unsigned int outofrange = 0;
pcercuei 0:03b5121a232e 2261
pcercuei 0:03b5121a232e 2262 /*
pcercuei 0:03b5121a232e 2263 * Using RAW/CUR/NEXT is okay since we are working on ASCII range here
pcercuei 0:03b5121a232e 2264 */
pcercuei 0:03b5121a232e 2265 if ((RAW == '&') && (NXT(1) == '#') &&
pcercuei 0:03b5121a232e 2266 (NXT(2) == 'x')) {
pcercuei 0:03b5121a232e 2267 SKIP(3);
pcercuei 0:03b5121a232e 2268 GROW;
pcercuei 0:03b5121a232e 2269 while (RAW != ';') { /* loop blocked by count */
pcercuei 0:03b5121a232e 2270 if (count++ > 20) {
pcercuei 0:03b5121a232e 2271 count = 0;
pcercuei 0:03b5121a232e 2272 GROW;
pcercuei 0:03b5121a232e 2273 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 2274 return(0);
pcercuei 0:03b5121a232e 2275 }
pcercuei 0:03b5121a232e 2276 if ((RAW >= '0') && (RAW <= '9'))
pcercuei 0:03b5121a232e 2277 val = val * 16 + (CUR - '0');
pcercuei 0:03b5121a232e 2278 else if ((RAW >= 'a') && (RAW <= 'f') && (count < 20))
pcercuei 0:03b5121a232e 2279 val = val * 16 + (CUR - 'a') + 10;
pcercuei 0:03b5121a232e 2280 else if ((RAW >= 'A') && (RAW <= 'F') && (count < 20))
pcercuei 0:03b5121a232e 2281 val = val * 16 + (CUR - 'A') + 10;
pcercuei 0:03b5121a232e 2282 else {
pcercuei 0:03b5121a232e 2283 xmlFatalErr(ctxt, XML_ERR_INVALID_HEX_CHARREF, NULL);
pcercuei 0:03b5121a232e 2284 val = 0;
pcercuei 0:03b5121a232e 2285 break;
pcercuei 0:03b5121a232e 2286 }
pcercuei 0:03b5121a232e 2287 if (val > 0x10FFFF)
pcercuei 0:03b5121a232e 2288 outofrange = val;
pcercuei 0:03b5121a232e 2289
pcercuei 0:03b5121a232e 2290 NEXT;
pcercuei 0:03b5121a232e 2291 count++;
pcercuei 0:03b5121a232e 2292 }
pcercuei 0:03b5121a232e 2293 if (RAW == ';') {
pcercuei 0:03b5121a232e 2294 /* on purpose to avoid reentrancy problems with NEXT and SKIP */
pcercuei 0:03b5121a232e 2295 ctxt->input->col++;
pcercuei 0:03b5121a232e 2296 ctxt->nbChars ++;
pcercuei 0:03b5121a232e 2297 ctxt->input->cur++;
pcercuei 0:03b5121a232e 2298 }
pcercuei 0:03b5121a232e 2299 } else if ((RAW == '&') && (NXT(1) == '#')) {
pcercuei 0:03b5121a232e 2300 SKIP(2);
pcercuei 0:03b5121a232e 2301 GROW;
pcercuei 0:03b5121a232e 2302 while (RAW != ';') { /* loop blocked by count */
pcercuei 0:03b5121a232e 2303 if (count++ > 20) {
pcercuei 0:03b5121a232e 2304 count = 0;
pcercuei 0:03b5121a232e 2305 GROW;
pcercuei 0:03b5121a232e 2306 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 2307 return(0);
pcercuei 0:03b5121a232e 2308 }
pcercuei 0:03b5121a232e 2309 if ((RAW >= '0') && (RAW <= '9'))
pcercuei 0:03b5121a232e 2310 val = val * 10 + (CUR - '0');
pcercuei 0:03b5121a232e 2311 else {
pcercuei 0:03b5121a232e 2312 xmlFatalErr(ctxt, XML_ERR_INVALID_DEC_CHARREF, NULL);
pcercuei 0:03b5121a232e 2313 val = 0;
pcercuei 0:03b5121a232e 2314 break;
pcercuei 0:03b5121a232e 2315 }
pcercuei 0:03b5121a232e 2316 if (val > 0x10FFFF)
pcercuei 0:03b5121a232e 2317 outofrange = val;
pcercuei 0:03b5121a232e 2318
pcercuei 0:03b5121a232e 2319 NEXT;
pcercuei 0:03b5121a232e 2320 count++;
pcercuei 0:03b5121a232e 2321 }
pcercuei 0:03b5121a232e 2322 if (RAW == ';') {
pcercuei 0:03b5121a232e 2323 /* on purpose to avoid reentrancy problems with NEXT and SKIP */
pcercuei 0:03b5121a232e 2324 ctxt->input->col++;
pcercuei 0:03b5121a232e 2325 ctxt->nbChars ++;
pcercuei 0:03b5121a232e 2326 ctxt->input->cur++;
pcercuei 0:03b5121a232e 2327 }
pcercuei 0:03b5121a232e 2328 } else {
pcercuei 0:03b5121a232e 2329 xmlFatalErr(ctxt, XML_ERR_INVALID_CHARREF, NULL);
pcercuei 0:03b5121a232e 2330 }
pcercuei 0:03b5121a232e 2331
pcercuei 0:03b5121a232e 2332 /*
pcercuei 0:03b5121a232e 2333 * [ WFC: Legal Character ]
pcercuei 0:03b5121a232e 2334 * Characters referred to using character references must match the
pcercuei 0:03b5121a232e 2335 * production for Char.
pcercuei 0:03b5121a232e 2336 */
pcercuei 0:03b5121a232e 2337 if ((IS_CHAR(val) && (outofrange == 0))) {
pcercuei 0:03b5121a232e 2338 return(val);
pcercuei 0:03b5121a232e 2339 } else {
pcercuei 0:03b5121a232e 2340 xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
pcercuei 0:03b5121a232e 2341 "xmlParseCharRef: invalid xmlChar value %d\n",
pcercuei 0:03b5121a232e 2342 val);
pcercuei 0:03b5121a232e 2343 }
pcercuei 0:03b5121a232e 2344 return(0);
pcercuei 0:03b5121a232e 2345 }
pcercuei 0:03b5121a232e 2346
pcercuei 0:03b5121a232e 2347 /**
pcercuei 0:03b5121a232e 2348 * xmlParseStringCharRef:
pcercuei 0:03b5121a232e 2349 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 2350 * @str: a pointer to an index in the string
pcercuei 0:03b5121a232e 2351 *
pcercuei 0:03b5121a232e 2352 * parse Reference declarations, variant parsing from a string rather
pcercuei 0:03b5121a232e 2353 * than an an input flow.
pcercuei 0:03b5121a232e 2354 *
pcercuei 0:03b5121a232e 2355 * [66] CharRef ::= '&#' [0-9]+ ';' |
pcercuei 0:03b5121a232e 2356 * '&#x' [0-9a-fA-F]+ ';'
pcercuei 0:03b5121a232e 2357 *
pcercuei 0:03b5121a232e 2358 * [ WFC: Legal Character ]
pcercuei 0:03b5121a232e 2359 * Characters referred to using character references must match the
pcercuei 0:03b5121a232e 2360 * production for Char.
pcercuei 0:03b5121a232e 2361 *
pcercuei 0:03b5121a232e 2362 * Returns the value parsed (as an int), 0 in case of error, str will be
pcercuei 0:03b5121a232e 2363 * updated to the current value of the index
pcercuei 0:03b5121a232e 2364 */
pcercuei 0:03b5121a232e 2365 static int
pcercuei 0:03b5121a232e 2366 xmlParseStringCharRef(xmlParserCtxtPtr ctxt, const xmlChar **str) {
pcercuei 0:03b5121a232e 2367 const xmlChar *ptr;
pcercuei 0:03b5121a232e 2368 xmlChar cur;
pcercuei 0:03b5121a232e 2369 unsigned int val = 0;
pcercuei 0:03b5121a232e 2370 unsigned int outofrange = 0;
pcercuei 0:03b5121a232e 2371
pcercuei 0:03b5121a232e 2372 if ((str == NULL) || (*str == NULL)) return(0);
pcercuei 0:03b5121a232e 2373 ptr = *str;
pcercuei 0:03b5121a232e 2374 cur = *ptr;
pcercuei 0:03b5121a232e 2375 if ((cur == '&') && (ptr[1] == '#') && (ptr[2] == 'x')) {
pcercuei 0:03b5121a232e 2376 ptr += 3;
pcercuei 0:03b5121a232e 2377 cur = *ptr;
pcercuei 0:03b5121a232e 2378 while (cur != ';') { /* Non input consuming loop */
pcercuei 0:03b5121a232e 2379 if ((cur >= '0') && (cur <= '9'))
pcercuei 0:03b5121a232e 2380 val = val * 16 + (cur - '0');
pcercuei 0:03b5121a232e 2381 else if ((cur >= 'a') && (cur <= 'f'))
pcercuei 0:03b5121a232e 2382 val = val * 16 + (cur - 'a') + 10;
pcercuei 0:03b5121a232e 2383 else if ((cur >= 'A') && (cur <= 'F'))
pcercuei 0:03b5121a232e 2384 val = val * 16 + (cur - 'A') + 10;
pcercuei 0:03b5121a232e 2385 else {
pcercuei 0:03b5121a232e 2386 xmlFatalErr(ctxt, XML_ERR_INVALID_HEX_CHARREF, NULL);
pcercuei 0:03b5121a232e 2387 val = 0;
pcercuei 0:03b5121a232e 2388 break;
pcercuei 0:03b5121a232e 2389 }
pcercuei 0:03b5121a232e 2390 if (val > 0x10FFFF)
pcercuei 0:03b5121a232e 2391 outofrange = val;
pcercuei 0:03b5121a232e 2392
pcercuei 0:03b5121a232e 2393 ptr++;
pcercuei 0:03b5121a232e 2394 cur = *ptr;
pcercuei 0:03b5121a232e 2395 }
pcercuei 0:03b5121a232e 2396 if (cur == ';')
pcercuei 0:03b5121a232e 2397 ptr++;
pcercuei 0:03b5121a232e 2398 } else if ((cur == '&') && (ptr[1] == '#')){
pcercuei 0:03b5121a232e 2399 ptr += 2;
pcercuei 0:03b5121a232e 2400 cur = *ptr;
pcercuei 0:03b5121a232e 2401 while (cur != ';') { /* Non input consuming loops */
pcercuei 0:03b5121a232e 2402 if ((cur >= '0') && (cur <= '9'))
pcercuei 0:03b5121a232e 2403 val = val * 10 + (cur - '0');
pcercuei 0:03b5121a232e 2404 else {
pcercuei 0:03b5121a232e 2405 xmlFatalErr(ctxt, XML_ERR_INVALID_DEC_CHARREF, NULL);
pcercuei 0:03b5121a232e 2406 val = 0;
pcercuei 0:03b5121a232e 2407 break;
pcercuei 0:03b5121a232e 2408 }
pcercuei 0:03b5121a232e 2409 if (val > 0x10FFFF)
pcercuei 0:03b5121a232e 2410 outofrange = val;
pcercuei 0:03b5121a232e 2411
pcercuei 0:03b5121a232e 2412 ptr++;
pcercuei 0:03b5121a232e 2413 cur = *ptr;
pcercuei 0:03b5121a232e 2414 }
pcercuei 0:03b5121a232e 2415 if (cur == ';')
pcercuei 0:03b5121a232e 2416 ptr++;
pcercuei 0:03b5121a232e 2417 } else {
pcercuei 0:03b5121a232e 2418 xmlFatalErr(ctxt, XML_ERR_INVALID_CHARREF, NULL);
pcercuei 0:03b5121a232e 2419 return(0);
pcercuei 0:03b5121a232e 2420 }
pcercuei 0:03b5121a232e 2421 *str = ptr;
pcercuei 0:03b5121a232e 2422
pcercuei 0:03b5121a232e 2423 /*
pcercuei 0:03b5121a232e 2424 * [ WFC: Legal Character ]
pcercuei 0:03b5121a232e 2425 * Characters referred to using character references must match the
pcercuei 0:03b5121a232e 2426 * production for Char.
pcercuei 0:03b5121a232e 2427 */
pcercuei 0:03b5121a232e 2428 if ((IS_CHAR(val) && (outofrange == 0))) {
pcercuei 0:03b5121a232e 2429 return(val);
pcercuei 0:03b5121a232e 2430 } else {
pcercuei 0:03b5121a232e 2431 xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
pcercuei 0:03b5121a232e 2432 "xmlParseStringCharRef: invalid xmlChar value %d\n",
pcercuei 0:03b5121a232e 2433 val);
pcercuei 0:03b5121a232e 2434 }
pcercuei 0:03b5121a232e 2435 return(0);
pcercuei 0:03b5121a232e 2436 }
pcercuei 0:03b5121a232e 2437
pcercuei 0:03b5121a232e 2438 /**
pcercuei 0:03b5121a232e 2439 * xmlNewBlanksWrapperInputStream:
pcercuei 0:03b5121a232e 2440 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 2441 * @entity: an Entity pointer
pcercuei 0:03b5121a232e 2442 *
pcercuei 0:03b5121a232e 2443 * Create a new input stream for wrapping
pcercuei 0:03b5121a232e 2444 * blanks around a PEReference
pcercuei 0:03b5121a232e 2445 *
pcercuei 0:03b5121a232e 2446 * Returns the new input stream or NULL
pcercuei 0:03b5121a232e 2447 */
pcercuei 0:03b5121a232e 2448
pcercuei 0:03b5121a232e 2449 static void deallocblankswrapper (xmlChar *str) {xmlFree(str);}
pcercuei 0:03b5121a232e 2450
pcercuei 0:03b5121a232e 2451 static xmlParserInputPtr
pcercuei 0:03b5121a232e 2452 xmlNewBlanksWrapperInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
pcercuei 0:03b5121a232e 2453 xmlParserInputPtr input;
pcercuei 0:03b5121a232e 2454 xmlChar *buffer;
pcercuei 0:03b5121a232e 2455 size_t length;
pcercuei 0:03b5121a232e 2456 if (entity == NULL) {
pcercuei 0:03b5121a232e 2457 xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
pcercuei 0:03b5121a232e 2458 "xmlNewBlanksWrapperInputStream entity\n");
pcercuei 0:03b5121a232e 2459 return(NULL);
pcercuei 0:03b5121a232e 2460 }
pcercuei 0:03b5121a232e 2461 if (xmlParserDebugEntities)
pcercuei 0:03b5121a232e 2462 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 2463 "new blanks wrapper for entity: %s\n", entity->name);
pcercuei 0:03b5121a232e 2464 input = xmlNewInputStream(ctxt);
pcercuei 0:03b5121a232e 2465 if (input == NULL) {
pcercuei 0:03b5121a232e 2466 return(NULL);
pcercuei 0:03b5121a232e 2467 }
pcercuei 0:03b5121a232e 2468 length = xmlStrlen(entity->name) + 5;
pcercuei 0:03b5121a232e 2469 buffer = xmlMallocAtomic(length);
pcercuei 0:03b5121a232e 2470 if (buffer == NULL) {
pcercuei 0:03b5121a232e 2471 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 2472 xmlFree(input);
pcercuei 0:03b5121a232e 2473 return(NULL);
pcercuei 0:03b5121a232e 2474 }
pcercuei 0:03b5121a232e 2475 buffer [0] = ' ';
pcercuei 0:03b5121a232e 2476 buffer [1] = '%';
pcercuei 0:03b5121a232e 2477 buffer [length-3] = ';';
pcercuei 0:03b5121a232e 2478 buffer [length-2] = ' ';
pcercuei 0:03b5121a232e 2479 buffer [length-1] = 0;
pcercuei 0:03b5121a232e 2480 memcpy(buffer + 2, entity->name, length - 5);
pcercuei 0:03b5121a232e 2481 input->free = deallocblankswrapper;
pcercuei 0:03b5121a232e 2482 input->base = buffer;
pcercuei 0:03b5121a232e 2483 input->cur = buffer;
pcercuei 0:03b5121a232e 2484 input->length = length;
pcercuei 0:03b5121a232e 2485 input->end = &buffer[length];
pcercuei 0:03b5121a232e 2486 return(input);
pcercuei 0:03b5121a232e 2487 }
pcercuei 0:03b5121a232e 2488
pcercuei 0:03b5121a232e 2489 /**
pcercuei 0:03b5121a232e 2490 * xmlParserHandlePEReference:
pcercuei 0:03b5121a232e 2491 * @ctxt: the parser context
pcercuei 0:03b5121a232e 2492 *
pcercuei 0:03b5121a232e 2493 * [69] PEReference ::= '%' Name ';'
pcercuei 0:03b5121a232e 2494 *
pcercuei 0:03b5121a232e 2495 * [ WFC: No Recursion ]
pcercuei 0:03b5121a232e 2496 * A parsed entity must not contain a recursive
pcercuei 0:03b5121a232e 2497 * reference to itself, either directly or indirectly.
pcercuei 0:03b5121a232e 2498 *
pcercuei 0:03b5121a232e 2499 * [ WFC: Entity Declared ]
pcercuei 0:03b5121a232e 2500 * In a document without any DTD, a document with only an internal DTD
pcercuei 0:03b5121a232e 2501 * subset which contains no parameter entity references, or a document
pcercuei 0:03b5121a232e 2502 * with "standalone='yes'", ... ... The declaration of a parameter
pcercuei 0:03b5121a232e 2503 * entity must precede any reference to it...
pcercuei 0:03b5121a232e 2504 *
pcercuei 0:03b5121a232e 2505 * [ VC: Entity Declared ]
pcercuei 0:03b5121a232e 2506 * In a document with an external subset or external parameter entities
pcercuei 0:03b5121a232e 2507 * with "standalone='no'", ... ... The declaration of a parameter entity
pcercuei 0:03b5121a232e 2508 * must precede any reference to it...
pcercuei 0:03b5121a232e 2509 *
pcercuei 0:03b5121a232e 2510 * [ WFC: In DTD ]
pcercuei 0:03b5121a232e 2511 * Parameter-entity references may only appear in the DTD.
pcercuei 0:03b5121a232e 2512 * NOTE: misleading but this is handled.
pcercuei 0:03b5121a232e 2513 *
pcercuei 0:03b5121a232e 2514 * A PEReference may have been detected in the current input stream
pcercuei 0:03b5121a232e 2515 * the handling is done accordingly to
pcercuei 0:03b5121a232e 2516 * http://www.w3.org/TR/REC-xml#entproc
pcercuei 0:03b5121a232e 2517 * i.e.
pcercuei 0:03b5121a232e 2518 * - Included in literal in entity values
pcercuei 0:03b5121a232e 2519 * - Included as Parameter Entity reference within DTDs
pcercuei 0:03b5121a232e 2520 */
pcercuei 0:03b5121a232e 2521 void
pcercuei 0:03b5121a232e 2522 xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 2523 const xmlChar *name;
pcercuei 0:03b5121a232e 2524 xmlEntityPtr entity = NULL;
pcercuei 0:03b5121a232e 2525 xmlParserInputPtr input;
pcercuei 0:03b5121a232e 2526
pcercuei 0:03b5121a232e 2527 if (RAW != '%') return;
pcercuei 0:03b5121a232e 2528 switch(ctxt->instate) {
pcercuei 0:03b5121a232e 2529 case XML_PARSER_CDATA_SECTION:
pcercuei 0:03b5121a232e 2530 return;
pcercuei 0:03b5121a232e 2531 case XML_PARSER_COMMENT:
pcercuei 0:03b5121a232e 2532 return;
pcercuei 0:03b5121a232e 2533 case XML_PARSER_START_TAG:
pcercuei 0:03b5121a232e 2534 return;
pcercuei 0:03b5121a232e 2535 case XML_PARSER_END_TAG:
pcercuei 0:03b5121a232e 2536 return;
pcercuei 0:03b5121a232e 2537 case XML_PARSER_EOF:
pcercuei 0:03b5121a232e 2538 xmlFatalErr(ctxt, XML_ERR_PEREF_AT_EOF, NULL);
pcercuei 0:03b5121a232e 2539 return;
pcercuei 0:03b5121a232e 2540 case XML_PARSER_PROLOG:
pcercuei 0:03b5121a232e 2541 case XML_PARSER_START:
pcercuei 0:03b5121a232e 2542 case XML_PARSER_MISC:
pcercuei 0:03b5121a232e 2543 xmlFatalErr(ctxt, XML_ERR_PEREF_IN_PROLOG, NULL);
pcercuei 0:03b5121a232e 2544 return;
pcercuei 0:03b5121a232e 2545 case XML_PARSER_ENTITY_DECL:
pcercuei 0:03b5121a232e 2546 case XML_PARSER_CONTENT:
pcercuei 0:03b5121a232e 2547 case XML_PARSER_ATTRIBUTE_VALUE:
pcercuei 0:03b5121a232e 2548 case XML_PARSER_PI:
pcercuei 0:03b5121a232e 2549 case XML_PARSER_SYSTEM_LITERAL:
pcercuei 0:03b5121a232e 2550 case XML_PARSER_PUBLIC_LITERAL:
pcercuei 0:03b5121a232e 2551 /* we just ignore it there */
pcercuei 0:03b5121a232e 2552 return;
pcercuei 0:03b5121a232e 2553 case XML_PARSER_EPILOG:
pcercuei 0:03b5121a232e 2554 xmlFatalErr(ctxt, XML_ERR_PEREF_IN_EPILOG, NULL);
pcercuei 0:03b5121a232e 2555 return;
pcercuei 0:03b5121a232e 2556 case XML_PARSER_ENTITY_VALUE:
pcercuei 0:03b5121a232e 2557 /*
pcercuei 0:03b5121a232e 2558 * NOTE: in the case of entity values, we don't do the
pcercuei 0:03b5121a232e 2559 * substitution here since we need the literal
pcercuei 0:03b5121a232e 2560 * entity value to be able to save the internal
pcercuei 0:03b5121a232e 2561 * subset of the document.
pcercuei 0:03b5121a232e 2562 * This will be handled by xmlStringDecodeEntities
pcercuei 0:03b5121a232e 2563 */
pcercuei 0:03b5121a232e 2564 return;
pcercuei 0:03b5121a232e 2565 case XML_PARSER_DTD:
pcercuei 0:03b5121a232e 2566 /*
pcercuei 0:03b5121a232e 2567 * [WFC: Well-Formedness Constraint: PEs in Internal Subset]
pcercuei 0:03b5121a232e 2568 * In the internal DTD subset, parameter-entity references
pcercuei 0:03b5121a232e 2569 * can occur only where markup declarations can occur, not
pcercuei 0:03b5121a232e 2570 * within markup declarations.
pcercuei 0:03b5121a232e 2571 * In that case this is handled in xmlParseMarkupDecl
pcercuei 0:03b5121a232e 2572 */
pcercuei 0:03b5121a232e 2573 if ((ctxt->external == 0) && (ctxt->inputNr == 1))
pcercuei 0:03b5121a232e 2574 return;
pcercuei 0:03b5121a232e 2575 if (IS_BLANK_CH(NXT(1)) || NXT(1) == 0)
pcercuei 0:03b5121a232e 2576 return;
pcercuei 0:03b5121a232e 2577 break;
pcercuei 0:03b5121a232e 2578 case XML_PARSER_IGNORE:
pcercuei 0:03b5121a232e 2579 return;
pcercuei 0:03b5121a232e 2580 }
pcercuei 0:03b5121a232e 2581
pcercuei 0:03b5121a232e 2582 NEXT;
pcercuei 0:03b5121a232e 2583 name = xmlParseName(ctxt);
pcercuei 0:03b5121a232e 2584 if (xmlParserDebugEntities)
pcercuei 0:03b5121a232e 2585 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 2586 "PEReference: %s\n", name);
pcercuei 0:03b5121a232e 2587 if (name == NULL) {
pcercuei 0:03b5121a232e 2588 xmlFatalErr(ctxt, XML_ERR_PEREF_NO_NAME, NULL);
pcercuei 0:03b5121a232e 2589 } else {
pcercuei 0:03b5121a232e 2590 if (RAW == ';') {
pcercuei 0:03b5121a232e 2591 NEXT;
pcercuei 0:03b5121a232e 2592 if ((ctxt->sax != NULL) && (ctxt->sax->getParameterEntity != NULL))
pcercuei 0:03b5121a232e 2593 entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
pcercuei 0:03b5121a232e 2594 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 2595 return;
pcercuei 0:03b5121a232e 2596 if (entity == NULL) {
pcercuei 0:03b5121a232e 2597
pcercuei 0:03b5121a232e 2598 /*
pcercuei 0:03b5121a232e 2599 * [ WFC: Entity Declared ]
pcercuei 0:03b5121a232e 2600 * In a document without any DTD, a document with only an
pcercuei 0:03b5121a232e 2601 * internal DTD subset which contains no parameter entity
pcercuei 0:03b5121a232e 2602 * references, or a document with "standalone='yes'", ...
pcercuei 0:03b5121a232e 2603 * ... The declaration of a parameter entity must precede
pcercuei 0:03b5121a232e 2604 * any reference to it...
pcercuei 0:03b5121a232e 2605 */
pcercuei 0:03b5121a232e 2606 if ((ctxt->standalone == 1) ||
pcercuei 0:03b5121a232e 2607 ((ctxt->hasExternalSubset == 0) &&
pcercuei 0:03b5121a232e 2608 (ctxt->hasPErefs == 0))) {
pcercuei 0:03b5121a232e 2609 xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
pcercuei 0:03b5121a232e 2610 "PEReference: %%%s; not found\n", name);
pcercuei 0:03b5121a232e 2611 } else {
pcercuei 0:03b5121a232e 2612 /*
pcercuei 0:03b5121a232e 2613 * [ VC: Entity Declared ]
pcercuei 0:03b5121a232e 2614 * In a document with an external subset or external
pcercuei 0:03b5121a232e 2615 * parameter entities with "standalone='no'", ...
pcercuei 0:03b5121a232e 2616 * ... The declaration of a parameter entity must precede
pcercuei 0:03b5121a232e 2617 * any reference to it...
pcercuei 0:03b5121a232e 2618 */
pcercuei 0:03b5121a232e 2619 if ((ctxt->validate) && (ctxt->vctxt.error != NULL)) {
pcercuei 0:03b5121a232e 2620 xmlValidityError(ctxt, XML_WAR_UNDECLARED_ENTITY,
pcercuei 0:03b5121a232e 2621 "PEReference: %%%s; not found\n",
pcercuei 0:03b5121a232e 2622 name, NULL);
pcercuei 0:03b5121a232e 2623 } else
pcercuei 0:03b5121a232e 2624 xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
pcercuei 0:03b5121a232e 2625 "PEReference: %%%s; not found\n",
pcercuei 0:03b5121a232e 2626 name, NULL);
pcercuei 0:03b5121a232e 2627 ctxt->valid = 0;
pcercuei 0:03b5121a232e 2628 }
pcercuei 0:03b5121a232e 2629 xmlParserEntityCheck(ctxt, 0, NULL, 0);
pcercuei 0:03b5121a232e 2630 } else if (ctxt->input->free != deallocblankswrapper) {
pcercuei 0:03b5121a232e 2631 input = xmlNewBlanksWrapperInputStream(ctxt, entity);
pcercuei 0:03b5121a232e 2632 if (xmlPushInput(ctxt, input) < 0)
pcercuei 0:03b5121a232e 2633 return;
pcercuei 0:03b5121a232e 2634 } else {
pcercuei 0:03b5121a232e 2635 if ((entity->etype == XML_INTERNAL_PARAMETER_ENTITY) ||
pcercuei 0:03b5121a232e 2636 (entity->etype == XML_EXTERNAL_PARAMETER_ENTITY)) {
pcercuei 0:03b5121a232e 2637 xmlChar start[4];
pcercuei 0:03b5121a232e 2638 xmlCharEncoding enc;
pcercuei 0:03b5121a232e 2639
pcercuei 0:03b5121a232e 2640 /*
pcercuei 0:03b5121a232e 2641 * Note: external parameter entities will not be loaded, it
pcercuei 0:03b5121a232e 2642 * is not required for a non-validating parser, unless the
pcercuei 0:03b5121a232e 2643 * option of validating, or substituting entities were
pcercuei 0:03b5121a232e 2644 * given. Doing so is far more secure as the parser will
pcercuei 0:03b5121a232e 2645 * only process data coming from the document entity by
pcercuei 0:03b5121a232e 2646 * default.
pcercuei 0:03b5121a232e 2647 */
pcercuei 0:03b5121a232e 2648 if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
pcercuei 0:03b5121a232e 2649 ((ctxt->options & XML_PARSE_NOENT) == 0) &&
pcercuei 0:03b5121a232e 2650 ((ctxt->options & XML_PARSE_DTDVALID) == 0) &&
pcercuei 0:03b5121a232e 2651 ((ctxt->options & XML_PARSE_DTDLOAD) == 0) &&
pcercuei 0:03b5121a232e 2652 ((ctxt->options & XML_PARSE_DTDATTR) == 0) &&
pcercuei 0:03b5121a232e 2653 (ctxt->replaceEntities == 0) &&
pcercuei 0:03b5121a232e 2654 (ctxt->validate == 0))
pcercuei 0:03b5121a232e 2655 return;
pcercuei 0:03b5121a232e 2656
pcercuei 0:03b5121a232e 2657 /*
pcercuei 0:03b5121a232e 2658 * handle the extra spaces added before and after
pcercuei 0:03b5121a232e 2659 * c.f. http://www.w3.org/TR/REC-xml#as-PE
pcercuei 0:03b5121a232e 2660 * this is done independently.
pcercuei 0:03b5121a232e 2661 */
pcercuei 0:03b5121a232e 2662 input = xmlNewEntityInputStream(ctxt, entity);
pcercuei 0:03b5121a232e 2663 if (xmlPushInput(ctxt, input) < 0)
pcercuei 0:03b5121a232e 2664 return;
pcercuei 0:03b5121a232e 2665
pcercuei 0:03b5121a232e 2666 /*
pcercuei 0:03b5121a232e 2667 * Get the 4 first bytes and decode the charset
pcercuei 0:03b5121a232e 2668 * if enc != XML_CHAR_ENCODING_NONE
pcercuei 0:03b5121a232e 2669 * plug some encoding conversion routines.
pcercuei 0:03b5121a232e 2670 * Note that, since we may have some non-UTF8
pcercuei 0:03b5121a232e 2671 * encoding (like UTF16, bug 135229), the 'length'
pcercuei 0:03b5121a232e 2672 * is not known, but we can calculate based upon
pcercuei 0:03b5121a232e 2673 * the amount of data in the buffer.
pcercuei 0:03b5121a232e 2674 */
pcercuei 0:03b5121a232e 2675 GROW
pcercuei 0:03b5121a232e 2676 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 2677 return;
pcercuei 0:03b5121a232e 2678 if ((ctxt->input->end - ctxt->input->cur)>=4) {
pcercuei 0:03b5121a232e 2679 start[0] = RAW;
pcercuei 0:03b5121a232e 2680 start[1] = NXT(1);
pcercuei 0:03b5121a232e 2681 start[2] = NXT(2);
pcercuei 0:03b5121a232e 2682 start[3] = NXT(3);
pcercuei 0:03b5121a232e 2683 enc = xmlDetectCharEncoding(start, 4);
pcercuei 0:03b5121a232e 2684 if (enc != XML_CHAR_ENCODING_NONE) {
pcercuei 0:03b5121a232e 2685 xmlSwitchEncoding(ctxt, enc);
pcercuei 0:03b5121a232e 2686 }
pcercuei 0:03b5121a232e 2687 }
pcercuei 0:03b5121a232e 2688
pcercuei 0:03b5121a232e 2689 if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
pcercuei 0:03b5121a232e 2690 (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l' )) &&
pcercuei 0:03b5121a232e 2691 (IS_BLANK_CH(NXT(5)))) {
pcercuei 0:03b5121a232e 2692 xmlParseTextDecl(ctxt);
pcercuei 0:03b5121a232e 2693 }
pcercuei 0:03b5121a232e 2694 } else {
pcercuei 0:03b5121a232e 2695 xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
pcercuei 0:03b5121a232e 2696 "PEReference: %s is not a parameter entity\n",
pcercuei 0:03b5121a232e 2697 name);
pcercuei 0:03b5121a232e 2698 }
pcercuei 0:03b5121a232e 2699 }
pcercuei 0:03b5121a232e 2700 } else {
pcercuei 0:03b5121a232e 2701 xmlFatalErr(ctxt, XML_ERR_PEREF_SEMICOL_MISSING, NULL);
pcercuei 0:03b5121a232e 2702 }
pcercuei 0:03b5121a232e 2703 }
pcercuei 0:03b5121a232e 2704 }
pcercuei 0:03b5121a232e 2705
pcercuei 0:03b5121a232e 2706 /*
pcercuei 0:03b5121a232e 2707 * Macro used to grow the current buffer.
pcercuei 0:03b5121a232e 2708 * buffer##_size is expected to be a size_t
pcercuei 0:03b5121a232e 2709 * mem_error: is expected to handle memory allocation failures
pcercuei 0:03b5121a232e 2710 */
pcercuei 0:03b5121a232e 2711 #define growBuffer(buffer, n) { \
pcercuei 0:03b5121a232e 2712 xmlChar *tmp; \
pcercuei 0:03b5121a232e 2713 size_t new_size = buffer##_size * 2 + n; \
pcercuei 0:03b5121a232e 2714 if (new_size < buffer##_size) goto mem_error; \
pcercuei 0:03b5121a232e 2715 tmp = (xmlChar *) xmlRealloc(buffer, new_size); \
pcercuei 0:03b5121a232e 2716 if (tmp == NULL) goto mem_error; \
pcercuei 0:03b5121a232e 2717 buffer = tmp; \
pcercuei 0:03b5121a232e 2718 buffer##_size = new_size; \
pcercuei 0:03b5121a232e 2719 }
pcercuei 0:03b5121a232e 2720
pcercuei 0:03b5121a232e 2721 /**
pcercuei 0:03b5121a232e 2722 * xmlStringLenDecodeEntities:
pcercuei 0:03b5121a232e 2723 * @ctxt: the parser context
pcercuei 0:03b5121a232e 2724 * @str: the input string
pcercuei 0:03b5121a232e 2725 * @len: the string length
pcercuei 0:03b5121a232e 2726 * @what: combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
pcercuei 0:03b5121a232e 2727 * @end: an end marker xmlChar, 0 if none
pcercuei 0:03b5121a232e 2728 * @end2: an end marker xmlChar, 0 if none
pcercuei 0:03b5121a232e 2729 * @end3: an end marker xmlChar, 0 if none
pcercuei 0:03b5121a232e 2730 *
pcercuei 0:03b5121a232e 2731 * Takes a entity string content and process to do the adequate substitutions.
pcercuei 0:03b5121a232e 2732 *
pcercuei 0:03b5121a232e 2733 * [67] Reference ::= EntityRef | CharRef
pcercuei 0:03b5121a232e 2734 *
pcercuei 0:03b5121a232e 2735 * [69] PEReference ::= '%' Name ';'
pcercuei 0:03b5121a232e 2736 *
pcercuei 0:03b5121a232e 2737 * Returns A newly allocated string with the substitution done. The caller
pcercuei 0:03b5121a232e 2738 * must deallocate it !
pcercuei 0:03b5121a232e 2739 */
pcercuei 0:03b5121a232e 2740 xmlChar *
pcercuei 0:03b5121a232e 2741 xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
pcercuei 0:03b5121a232e 2742 int what, xmlChar end, xmlChar end2, xmlChar end3) {
pcercuei 0:03b5121a232e 2743 xmlChar *buffer = NULL;
pcercuei 0:03b5121a232e 2744 size_t buffer_size = 0;
pcercuei 0:03b5121a232e 2745 size_t nbchars = 0;
pcercuei 0:03b5121a232e 2746
pcercuei 0:03b5121a232e 2747 xmlChar *current = NULL;
pcercuei 0:03b5121a232e 2748 xmlChar *rep = NULL;
pcercuei 0:03b5121a232e 2749 const xmlChar *last;
pcercuei 0:03b5121a232e 2750 xmlEntityPtr ent;
pcercuei 0:03b5121a232e 2751 int c,l;
pcercuei 0:03b5121a232e 2752
pcercuei 0:03b5121a232e 2753 if ((ctxt == NULL) || (str == NULL) || (len < 0))
pcercuei 0:03b5121a232e 2754 return(NULL);
pcercuei 0:03b5121a232e 2755 last = str + len;
pcercuei 0:03b5121a232e 2756
pcercuei 0:03b5121a232e 2757 if (((ctxt->depth > 40) &&
pcercuei 0:03b5121a232e 2758 ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
pcercuei 0:03b5121a232e 2759 (ctxt->depth > 1024)) {
pcercuei 0:03b5121a232e 2760 xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
pcercuei 0:03b5121a232e 2761 return(NULL);
pcercuei 0:03b5121a232e 2762 }
pcercuei 0:03b5121a232e 2763
pcercuei 0:03b5121a232e 2764 /*
pcercuei 0:03b5121a232e 2765 * allocate a translation buffer.
pcercuei 0:03b5121a232e 2766 */
pcercuei 0:03b5121a232e 2767 buffer_size = XML_PARSER_BIG_BUFFER_SIZE;
pcercuei 0:03b5121a232e 2768 buffer = (xmlChar *) xmlMallocAtomic(buffer_size);
pcercuei 0:03b5121a232e 2769 if (buffer == NULL) goto mem_error;
pcercuei 0:03b5121a232e 2770
pcercuei 0:03b5121a232e 2771 /*
pcercuei 0:03b5121a232e 2772 * OK loop until we reach one of the ending char or a size limit.
pcercuei 0:03b5121a232e 2773 * we are operating on already parsed values.
pcercuei 0:03b5121a232e 2774 */
pcercuei 0:03b5121a232e 2775 if (str < last)
pcercuei 0:03b5121a232e 2776 c = CUR_SCHAR(str, l);
pcercuei 0:03b5121a232e 2777 else
pcercuei 0:03b5121a232e 2778 c = 0;
pcercuei 0:03b5121a232e 2779 while ((c != 0) && (c != end) && /* non input consuming loop */
pcercuei 0:03b5121a232e 2780 (c != end2) && (c != end3)) {
pcercuei 0:03b5121a232e 2781
pcercuei 0:03b5121a232e 2782 if (c == 0) break;
pcercuei 0:03b5121a232e 2783 if ((c == '&') && (str[1] == '#')) {
pcercuei 0:03b5121a232e 2784 int val = xmlParseStringCharRef(ctxt, &str);
pcercuei 0:03b5121a232e 2785 if (val != 0) {
pcercuei 0:03b5121a232e 2786 COPY_BUF(0,buffer,nbchars,val);
pcercuei 0:03b5121a232e 2787 }
pcercuei 0:03b5121a232e 2788 if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
pcercuei 0:03b5121a232e 2789 growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
pcercuei 0:03b5121a232e 2790 }
pcercuei 0:03b5121a232e 2791 } else if ((c == '&') && (what & XML_SUBSTITUTE_REF)) {
pcercuei 0:03b5121a232e 2792 if (xmlParserDebugEntities)
pcercuei 0:03b5121a232e 2793 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 2794 "String decoding Entity Reference: %.30s\n",
pcercuei 0:03b5121a232e 2795 str);
pcercuei 0:03b5121a232e 2796 ent = xmlParseStringEntityRef(ctxt, &str);
pcercuei 0:03b5121a232e 2797 if ((ctxt->lastError.code == XML_ERR_ENTITY_LOOP) ||
pcercuei 0:03b5121a232e 2798 (ctxt->lastError.code == XML_ERR_INTERNAL_ERROR))
pcercuei 0:03b5121a232e 2799 goto int_error;
pcercuei 0:03b5121a232e 2800 xmlParserEntityCheck(ctxt, 0, ent, 0);
pcercuei 0:03b5121a232e 2801 if (ent != NULL)
pcercuei 0:03b5121a232e 2802 ctxt->nbentities += ent->checked / 2;
pcercuei 0:03b5121a232e 2803 if ((ent != NULL) &&
pcercuei 0:03b5121a232e 2804 (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
pcercuei 0:03b5121a232e 2805 if (ent->content != NULL) {
pcercuei 0:03b5121a232e 2806 COPY_BUF(0,buffer,nbchars,ent->content[0]);
pcercuei 0:03b5121a232e 2807 if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
pcercuei 0:03b5121a232e 2808 growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
pcercuei 0:03b5121a232e 2809 }
pcercuei 0:03b5121a232e 2810 } else {
pcercuei 0:03b5121a232e 2811 xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
pcercuei 0:03b5121a232e 2812 "predefined entity has no content\n");
pcercuei 0:03b5121a232e 2813 }
pcercuei 0:03b5121a232e 2814 } else if ((ent != NULL) && (ent->content != NULL)) {
pcercuei 0:03b5121a232e 2815 ctxt->depth++;
pcercuei 0:03b5121a232e 2816 rep = xmlStringDecodeEntities(ctxt, ent->content, what,
pcercuei 0:03b5121a232e 2817 0, 0, 0);
pcercuei 0:03b5121a232e 2818 ctxt->depth--;
pcercuei 0:03b5121a232e 2819
pcercuei 0:03b5121a232e 2820 if ((ctxt->lastError.code == XML_ERR_ENTITY_LOOP) ||
pcercuei 0:03b5121a232e 2821 (ctxt->lastError.code == XML_ERR_INTERNAL_ERROR))
pcercuei 0:03b5121a232e 2822 goto int_error;
pcercuei 0:03b5121a232e 2823
pcercuei 0:03b5121a232e 2824 if (rep != NULL) {
pcercuei 0:03b5121a232e 2825 current = rep;
pcercuei 0:03b5121a232e 2826 while (*current != 0) { /* non input consuming loop */
pcercuei 0:03b5121a232e 2827 buffer[nbchars++] = *current++;
pcercuei 0:03b5121a232e 2828 if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
pcercuei 0:03b5121a232e 2829 if (xmlParserEntityCheck(ctxt, nbchars, ent, 0))
pcercuei 0:03b5121a232e 2830 goto int_error;
pcercuei 0:03b5121a232e 2831 growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
pcercuei 0:03b5121a232e 2832 }
pcercuei 0:03b5121a232e 2833 }
pcercuei 0:03b5121a232e 2834 xmlFree(rep);
pcercuei 0:03b5121a232e 2835 rep = NULL;
pcercuei 0:03b5121a232e 2836 }
pcercuei 0:03b5121a232e 2837 } else if (ent != NULL) {
pcercuei 0:03b5121a232e 2838 int i = xmlStrlen(ent->name);
pcercuei 0:03b5121a232e 2839 const xmlChar *cur = ent->name;
pcercuei 0:03b5121a232e 2840
pcercuei 0:03b5121a232e 2841 buffer[nbchars++] = '&';
pcercuei 0:03b5121a232e 2842 if (nbchars + i + XML_PARSER_BUFFER_SIZE > buffer_size) {
pcercuei 0:03b5121a232e 2843 growBuffer(buffer, i + XML_PARSER_BUFFER_SIZE);
pcercuei 0:03b5121a232e 2844 }
pcercuei 0:03b5121a232e 2845 for (;i > 0;i--)
pcercuei 0:03b5121a232e 2846 buffer[nbchars++] = *cur++;
pcercuei 0:03b5121a232e 2847 buffer[nbchars++] = ';';
pcercuei 0:03b5121a232e 2848 }
pcercuei 0:03b5121a232e 2849 } else if (c == '%' && (what & XML_SUBSTITUTE_PEREF)) {
pcercuei 0:03b5121a232e 2850 if (xmlParserDebugEntities)
pcercuei 0:03b5121a232e 2851 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 2852 "String decoding PE Reference: %.30s\n", str);
pcercuei 0:03b5121a232e 2853 ent = xmlParseStringPEReference(ctxt, &str);
pcercuei 0:03b5121a232e 2854 if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
pcercuei 0:03b5121a232e 2855 goto int_error;
pcercuei 0:03b5121a232e 2856 xmlParserEntityCheck(ctxt, 0, ent, 0);
pcercuei 0:03b5121a232e 2857 if (ent != NULL)
pcercuei 0:03b5121a232e 2858 ctxt->nbentities += ent->checked / 2;
pcercuei 0:03b5121a232e 2859 if (ent != NULL) {
pcercuei 0:03b5121a232e 2860 if (ent->content == NULL) {
pcercuei 0:03b5121a232e 2861 xmlLoadEntityContent(ctxt, ent);
pcercuei 0:03b5121a232e 2862 }
pcercuei 0:03b5121a232e 2863 ctxt->depth++;
pcercuei 0:03b5121a232e 2864 rep = xmlStringDecodeEntities(ctxt, ent->content, what,
pcercuei 0:03b5121a232e 2865 0, 0, 0);
pcercuei 0:03b5121a232e 2866 ctxt->depth--;
pcercuei 0:03b5121a232e 2867 if (rep != NULL) {
pcercuei 0:03b5121a232e 2868 current = rep;
pcercuei 0:03b5121a232e 2869 while (*current != 0) { /* non input consuming loop */
pcercuei 0:03b5121a232e 2870 buffer[nbchars++] = *current++;
pcercuei 0:03b5121a232e 2871 if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
pcercuei 0:03b5121a232e 2872 if (xmlParserEntityCheck(ctxt, nbchars, ent, 0))
pcercuei 0:03b5121a232e 2873 goto int_error;
pcercuei 0:03b5121a232e 2874 growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
pcercuei 0:03b5121a232e 2875 }
pcercuei 0:03b5121a232e 2876 }
pcercuei 0:03b5121a232e 2877 xmlFree(rep);
pcercuei 0:03b5121a232e 2878 rep = NULL;
pcercuei 0:03b5121a232e 2879 }
pcercuei 0:03b5121a232e 2880 }
pcercuei 0:03b5121a232e 2881 } else {
pcercuei 0:03b5121a232e 2882 COPY_BUF(l,buffer,nbchars,c);
pcercuei 0:03b5121a232e 2883 str += l;
pcercuei 0:03b5121a232e 2884 if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
pcercuei 0:03b5121a232e 2885 growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
pcercuei 0:03b5121a232e 2886 }
pcercuei 0:03b5121a232e 2887 }
pcercuei 0:03b5121a232e 2888 if (str < last)
pcercuei 0:03b5121a232e 2889 c = CUR_SCHAR(str, l);
pcercuei 0:03b5121a232e 2890 else
pcercuei 0:03b5121a232e 2891 c = 0;
pcercuei 0:03b5121a232e 2892 }
pcercuei 0:03b5121a232e 2893 buffer[nbchars] = 0;
pcercuei 0:03b5121a232e 2894 return(buffer);
pcercuei 0:03b5121a232e 2895
pcercuei 0:03b5121a232e 2896 mem_error:
pcercuei 0:03b5121a232e 2897 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 2898 int_error:
pcercuei 0:03b5121a232e 2899 if (rep != NULL)
pcercuei 0:03b5121a232e 2900 xmlFree(rep);
pcercuei 0:03b5121a232e 2901 if (buffer != NULL)
pcercuei 0:03b5121a232e 2902 xmlFree(buffer);
pcercuei 0:03b5121a232e 2903 return(NULL);
pcercuei 0:03b5121a232e 2904 }
pcercuei 0:03b5121a232e 2905
pcercuei 0:03b5121a232e 2906 /**
pcercuei 0:03b5121a232e 2907 * xmlStringDecodeEntities:
pcercuei 0:03b5121a232e 2908 * @ctxt: the parser context
pcercuei 0:03b5121a232e 2909 * @str: the input string
pcercuei 0:03b5121a232e 2910 * @what: combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
pcercuei 0:03b5121a232e 2911 * @end: an end marker xmlChar, 0 if none
pcercuei 0:03b5121a232e 2912 * @end2: an end marker xmlChar, 0 if none
pcercuei 0:03b5121a232e 2913 * @end3: an end marker xmlChar, 0 if none
pcercuei 0:03b5121a232e 2914 *
pcercuei 0:03b5121a232e 2915 * Takes a entity string content and process to do the adequate substitutions.
pcercuei 0:03b5121a232e 2916 *
pcercuei 0:03b5121a232e 2917 * [67] Reference ::= EntityRef | CharRef
pcercuei 0:03b5121a232e 2918 *
pcercuei 0:03b5121a232e 2919 * [69] PEReference ::= '%' Name ';'
pcercuei 0:03b5121a232e 2920 *
pcercuei 0:03b5121a232e 2921 * Returns A newly allocated string with the substitution done. The caller
pcercuei 0:03b5121a232e 2922 * must deallocate it !
pcercuei 0:03b5121a232e 2923 */
pcercuei 0:03b5121a232e 2924 xmlChar *
pcercuei 0:03b5121a232e 2925 xmlStringDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int what,
pcercuei 0:03b5121a232e 2926 xmlChar end, xmlChar end2, xmlChar end3) {
pcercuei 0:03b5121a232e 2927 if ((ctxt == NULL) || (str == NULL)) return(NULL);
pcercuei 0:03b5121a232e 2928 return(xmlStringLenDecodeEntities(ctxt, str, xmlStrlen(str), what,
pcercuei 0:03b5121a232e 2929 end, end2, end3));
pcercuei 0:03b5121a232e 2930 }
pcercuei 0:03b5121a232e 2931
pcercuei 0:03b5121a232e 2932 /************************************************************************
pcercuei 0:03b5121a232e 2933 * *
pcercuei 0:03b5121a232e 2934 * Commodity functions, cleanup needed ? *
pcercuei 0:03b5121a232e 2935 * *
pcercuei 0:03b5121a232e 2936 ************************************************************************/
pcercuei 0:03b5121a232e 2937
pcercuei 0:03b5121a232e 2938 /**
pcercuei 0:03b5121a232e 2939 * areBlanks:
pcercuei 0:03b5121a232e 2940 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 2941 * @str: a xmlChar *
pcercuei 0:03b5121a232e 2942 * @len: the size of @str
pcercuei 0:03b5121a232e 2943 * @blank_chars: we know the chars are blanks
pcercuei 0:03b5121a232e 2944 *
pcercuei 0:03b5121a232e 2945 * Is this a sequence of blank chars that one can ignore ?
pcercuei 0:03b5121a232e 2946 *
pcercuei 0:03b5121a232e 2947 * Returns 1 if ignorable 0 otherwise.
pcercuei 0:03b5121a232e 2948 */
pcercuei 0:03b5121a232e 2949
pcercuei 0:03b5121a232e 2950 static int areBlanks(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
pcercuei 0:03b5121a232e 2951 int blank_chars) {
pcercuei 0:03b5121a232e 2952 int i, ret;
pcercuei 0:03b5121a232e 2953 xmlNodePtr lastChild;
pcercuei 0:03b5121a232e 2954
pcercuei 0:03b5121a232e 2955 /*
pcercuei 0:03b5121a232e 2956 * Don't spend time trying to differentiate them, the same callback is
pcercuei 0:03b5121a232e 2957 * used !
pcercuei 0:03b5121a232e 2958 */
pcercuei 0:03b5121a232e 2959 if (ctxt->sax->ignorableWhitespace == ctxt->sax->characters)
pcercuei 0:03b5121a232e 2960 return(0);
pcercuei 0:03b5121a232e 2961
pcercuei 0:03b5121a232e 2962 /*
pcercuei 0:03b5121a232e 2963 * Check for xml:space value.
pcercuei 0:03b5121a232e 2964 */
pcercuei 0:03b5121a232e 2965 if ((ctxt->space == NULL) || (*(ctxt->space) == 1) ||
pcercuei 0:03b5121a232e 2966 (*(ctxt->space) == -2))
pcercuei 0:03b5121a232e 2967 return(0);
pcercuei 0:03b5121a232e 2968
pcercuei 0:03b5121a232e 2969 /*
pcercuei 0:03b5121a232e 2970 * Check that the string is made of blanks
pcercuei 0:03b5121a232e 2971 */
pcercuei 0:03b5121a232e 2972 if (blank_chars == 0) {
pcercuei 0:03b5121a232e 2973 for (i = 0;i < len;i++)
pcercuei 0:03b5121a232e 2974 if (!(IS_BLANK_CH(str[i]))) return(0);
pcercuei 0:03b5121a232e 2975 }
pcercuei 0:03b5121a232e 2976
pcercuei 0:03b5121a232e 2977 /*
pcercuei 0:03b5121a232e 2978 * Look if the element is mixed content in the DTD if available
pcercuei 0:03b5121a232e 2979 */
pcercuei 0:03b5121a232e 2980 if (ctxt->node == NULL) return(0);
pcercuei 0:03b5121a232e 2981 if (ctxt->myDoc != NULL) {
pcercuei 0:03b5121a232e 2982 ret = xmlIsMixedElement(ctxt->myDoc, ctxt->node->name);
pcercuei 0:03b5121a232e 2983 if (ret == 0) return(1);
pcercuei 0:03b5121a232e 2984 if (ret == 1) return(0);
pcercuei 0:03b5121a232e 2985 }
pcercuei 0:03b5121a232e 2986
pcercuei 0:03b5121a232e 2987 /*
pcercuei 0:03b5121a232e 2988 * Otherwise, heuristic :-\
pcercuei 0:03b5121a232e 2989 */
pcercuei 0:03b5121a232e 2990 if ((RAW != '<') && (RAW != 0xD)) return(0);
pcercuei 0:03b5121a232e 2991 if ((ctxt->node->children == NULL) &&
pcercuei 0:03b5121a232e 2992 (RAW == '<') && (NXT(1) == '/')) return(0);
pcercuei 0:03b5121a232e 2993
pcercuei 0:03b5121a232e 2994 lastChild = xmlGetLastChild(ctxt->node);
pcercuei 0:03b5121a232e 2995 if (lastChild == NULL) {
pcercuei 0:03b5121a232e 2996 if ((ctxt->node->type != XML_ELEMENT_NODE) &&
pcercuei 0:03b5121a232e 2997 (ctxt->node->content != NULL)) return(0);
pcercuei 0:03b5121a232e 2998 } else if (xmlNodeIsText(lastChild))
pcercuei 0:03b5121a232e 2999 return(0);
pcercuei 0:03b5121a232e 3000 else if ((ctxt->node->children != NULL) &&
pcercuei 0:03b5121a232e 3001 (xmlNodeIsText(ctxt->node->children)))
pcercuei 0:03b5121a232e 3002 return(0);
pcercuei 0:03b5121a232e 3003 return(1);
pcercuei 0:03b5121a232e 3004 }
pcercuei 0:03b5121a232e 3005
pcercuei 0:03b5121a232e 3006 /************************************************************************
pcercuei 0:03b5121a232e 3007 * *
pcercuei 0:03b5121a232e 3008 * Extra stuff for namespace support *
pcercuei 0:03b5121a232e 3009 * Relates to http://www.w3.org/TR/WD-xml-names *
pcercuei 0:03b5121a232e 3010 * *
pcercuei 0:03b5121a232e 3011 ************************************************************************/
pcercuei 0:03b5121a232e 3012
pcercuei 0:03b5121a232e 3013 /**
pcercuei 0:03b5121a232e 3014 * xmlSplitQName:
pcercuei 0:03b5121a232e 3015 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 3016 * @name: an XML parser context
pcercuei 0:03b5121a232e 3017 * @prefix: a xmlChar **
pcercuei 0:03b5121a232e 3018 *
pcercuei 0:03b5121a232e 3019 * parse an UTF8 encoded XML qualified name string
pcercuei 0:03b5121a232e 3020 *
pcercuei 0:03b5121a232e 3021 * [NS 5] QName ::= (Prefix ':')? LocalPart
pcercuei 0:03b5121a232e 3022 *
pcercuei 0:03b5121a232e 3023 * [NS 6] Prefix ::= NCName
pcercuei 0:03b5121a232e 3024 *
pcercuei 0:03b5121a232e 3025 * [NS 7] LocalPart ::= NCName
pcercuei 0:03b5121a232e 3026 *
pcercuei 0:03b5121a232e 3027 * Returns the local part, and prefix is updated
pcercuei 0:03b5121a232e 3028 * to get the Prefix if any.
pcercuei 0:03b5121a232e 3029 */
pcercuei 0:03b5121a232e 3030
pcercuei 0:03b5121a232e 3031 xmlChar *
pcercuei 0:03b5121a232e 3032 xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefix) {
pcercuei 0:03b5121a232e 3033 xmlChar buf[XML_MAX_NAMELEN + 5];
pcercuei 0:03b5121a232e 3034 xmlChar *buffer = NULL;
pcercuei 0:03b5121a232e 3035 int len = 0;
pcercuei 0:03b5121a232e 3036 int max = XML_MAX_NAMELEN;
pcercuei 0:03b5121a232e 3037 xmlChar *ret = NULL;
pcercuei 0:03b5121a232e 3038 const xmlChar *cur = name;
pcercuei 0:03b5121a232e 3039 int c;
pcercuei 0:03b5121a232e 3040
pcercuei 0:03b5121a232e 3041 if (prefix == NULL) return(NULL);
pcercuei 0:03b5121a232e 3042 *prefix = NULL;
pcercuei 0:03b5121a232e 3043
pcercuei 0:03b5121a232e 3044 if (cur == NULL) return(NULL);
pcercuei 0:03b5121a232e 3045
pcercuei 0:03b5121a232e 3046 #ifndef XML_XML_NAMESPACE
pcercuei 0:03b5121a232e 3047 /* xml: prefix is not really a namespace */
pcercuei 0:03b5121a232e 3048 if ((cur[0] == 'x') && (cur[1] == 'm') &&
pcercuei 0:03b5121a232e 3049 (cur[2] == 'l') && (cur[3] == ':'))
pcercuei 0:03b5121a232e 3050 return(xmlStrdup(name));
pcercuei 0:03b5121a232e 3051 #endif
pcercuei 0:03b5121a232e 3052
pcercuei 0:03b5121a232e 3053 /* nasty but well=formed */
pcercuei 0:03b5121a232e 3054 if (cur[0] == ':')
pcercuei 0:03b5121a232e 3055 return(xmlStrdup(name));
pcercuei 0:03b5121a232e 3056
pcercuei 0:03b5121a232e 3057 c = *cur++;
pcercuei 0:03b5121a232e 3058 while ((c != 0) && (c != ':') && (len < max)) { /* tested bigname.xml */
pcercuei 0:03b5121a232e 3059 buf[len++] = c;
pcercuei 0:03b5121a232e 3060 c = *cur++;
pcercuei 0:03b5121a232e 3061 }
pcercuei 0:03b5121a232e 3062 if (len >= max) {
pcercuei 0:03b5121a232e 3063 /*
pcercuei 0:03b5121a232e 3064 * Okay someone managed to make a huge name, so he's ready to pay
pcercuei 0:03b5121a232e 3065 * for the processing speed.
pcercuei 0:03b5121a232e 3066 */
pcercuei 0:03b5121a232e 3067 max = len * 2;
pcercuei 0:03b5121a232e 3068
pcercuei 0:03b5121a232e 3069 buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
pcercuei 0:03b5121a232e 3070 if (buffer == NULL) {
pcercuei 0:03b5121a232e 3071 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 3072 return(NULL);
pcercuei 0:03b5121a232e 3073 }
pcercuei 0:03b5121a232e 3074 memcpy(buffer, buf, len);
pcercuei 0:03b5121a232e 3075 while ((c != 0) && (c != ':')) { /* tested bigname.xml */
pcercuei 0:03b5121a232e 3076 if (len + 10 > max) {
pcercuei 0:03b5121a232e 3077 xmlChar *tmp;
pcercuei 0:03b5121a232e 3078
pcercuei 0:03b5121a232e 3079 max *= 2;
pcercuei 0:03b5121a232e 3080 tmp = (xmlChar *) xmlRealloc(buffer,
pcercuei 0:03b5121a232e 3081 max * sizeof(xmlChar));
pcercuei 0:03b5121a232e 3082 if (tmp == NULL) {
pcercuei 0:03b5121a232e 3083 xmlFree(buffer);
pcercuei 0:03b5121a232e 3084 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 3085 return(NULL);
pcercuei 0:03b5121a232e 3086 }
pcercuei 0:03b5121a232e 3087 buffer = tmp;
pcercuei 0:03b5121a232e 3088 }
pcercuei 0:03b5121a232e 3089 buffer[len++] = c;
pcercuei 0:03b5121a232e 3090 c = *cur++;
pcercuei 0:03b5121a232e 3091 }
pcercuei 0:03b5121a232e 3092 buffer[len] = 0;
pcercuei 0:03b5121a232e 3093 }
pcercuei 0:03b5121a232e 3094
pcercuei 0:03b5121a232e 3095 if ((c == ':') && (*cur == 0)) {
pcercuei 0:03b5121a232e 3096 if (buffer != NULL)
pcercuei 0:03b5121a232e 3097 xmlFree(buffer);
pcercuei 0:03b5121a232e 3098 *prefix = NULL;
pcercuei 0:03b5121a232e 3099 return(xmlStrdup(name));
pcercuei 0:03b5121a232e 3100 }
pcercuei 0:03b5121a232e 3101
pcercuei 0:03b5121a232e 3102 if (buffer == NULL)
pcercuei 0:03b5121a232e 3103 ret = xmlStrndup(buf, len);
pcercuei 0:03b5121a232e 3104 else {
pcercuei 0:03b5121a232e 3105 ret = buffer;
pcercuei 0:03b5121a232e 3106 buffer = NULL;
pcercuei 0:03b5121a232e 3107 max = XML_MAX_NAMELEN;
pcercuei 0:03b5121a232e 3108 }
pcercuei 0:03b5121a232e 3109
pcercuei 0:03b5121a232e 3110
pcercuei 0:03b5121a232e 3111 if (c == ':') {
pcercuei 0:03b5121a232e 3112 c = *cur;
pcercuei 0:03b5121a232e 3113 *prefix = ret;
pcercuei 0:03b5121a232e 3114 if (c == 0) {
pcercuei 0:03b5121a232e 3115 return(xmlStrndup(BAD_CAST "", 0));
pcercuei 0:03b5121a232e 3116 }
pcercuei 0:03b5121a232e 3117 len = 0;
pcercuei 0:03b5121a232e 3118
pcercuei 0:03b5121a232e 3119 /*
pcercuei 0:03b5121a232e 3120 * Check that the first character is proper to start
pcercuei 0:03b5121a232e 3121 * a new name
pcercuei 0:03b5121a232e 3122 */
pcercuei 0:03b5121a232e 3123 if (!(((c >= 0x61) && (c <= 0x7A)) ||
pcercuei 0:03b5121a232e 3124 ((c >= 0x41) && (c <= 0x5A)) ||
pcercuei 0:03b5121a232e 3125 (c == '_') || (c == ':'))) {
pcercuei 0:03b5121a232e 3126 int l;
pcercuei 0:03b5121a232e 3127 int first = CUR_SCHAR(cur, l);
pcercuei 0:03b5121a232e 3128
pcercuei 0:03b5121a232e 3129 if (!IS_LETTER(first) && (first != '_')) {
pcercuei 0:03b5121a232e 3130 xmlFatalErrMsgStr(ctxt, XML_NS_ERR_QNAME,
pcercuei 0:03b5121a232e 3131 "Name %s is not XML Namespace compliant\n",
pcercuei 0:03b5121a232e 3132 name);
pcercuei 0:03b5121a232e 3133 }
pcercuei 0:03b5121a232e 3134 }
pcercuei 0:03b5121a232e 3135 cur++;
pcercuei 0:03b5121a232e 3136
pcercuei 0:03b5121a232e 3137 while ((c != 0) && (len < max)) { /* tested bigname2.xml */
pcercuei 0:03b5121a232e 3138 buf[len++] = c;
pcercuei 0:03b5121a232e 3139 c = *cur++;
pcercuei 0:03b5121a232e 3140 }
pcercuei 0:03b5121a232e 3141 if (len >= max) {
pcercuei 0:03b5121a232e 3142 /*
pcercuei 0:03b5121a232e 3143 * Okay someone managed to make a huge name, so he's ready to pay
pcercuei 0:03b5121a232e 3144 * for the processing speed.
pcercuei 0:03b5121a232e 3145 */
pcercuei 0:03b5121a232e 3146 max = len * 2;
pcercuei 0:03b5121a232e 3147
pcercuei 0:03b5121a232e 3148 buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
pcercuei 0:03b5121a232e 3149 if (buffer == NULL) {
pcercuei 0:03b5121a232e 3150 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 3151 return(NULL);
pcercuei 0:03b5121a232e 3152 }
pcercuei 0:03b5121a232e 3153 memcpy(buffer, buf, len);
pcercuei 0:03b5121a232e 3154 while (c != 0) { /* tested bigname2.xml */
pcercuei 0:03b5121a232e 3155 if (len + 10 > max) {
pcercuei 0:03b5121a232e 3156 xmlChar *tmp;
pcercuei 0:03b5121a232e 3157
pcercuei 0:03b5121a232e 3158 max *= 2;
pcercuei 0:03b5121a232e 3159 tmp = (xmlChar *) xmlRealloc(buffer,
pcercuei 0:03b5121a232e 3160 max * sizeof(xmlChar));
pcercuei 0:03b5121a232e 3161 if (tmp == NULL) {
pcercuei 0:03b5121a232e 3162 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 3163 xmlFree(buffer);
pcercuei 0:03b5121a232e 3164 return(NULL);
pcercuei 0:03b5121a232e 3165 }
pcercuei 0:03b5121a232e 3166 buffer = tmp;
pcercuei 0:03b5121a232e 3167 }
pcercuei 0:03b5121a232e 3168 buffer[len++] = c;
pcercuei 0:03b5121a232e 3169 c = *cur++;
pcercuei 0:03b5121a232e 3170 }
pcercuei 0:03b5121a232e 3171 buffer[len] = 0;
pcercuei 0:03b5121a232e 3172 }
pcercuei 0:03b5121a232e 3173
pcercuei 0:03b5121a232e 3174 if (buffer == NULL)
pcercuei 0:03b5121a232e 3175 ret = xmlStrndup(buf, len);
pcercuei 0:03b5121a232e 3176 else {
pcercuei 0:03b5121a232e 3177 ret = buffer;
pcercuei 0:03b5121a232e 3178 }
pcercuei 0:03b5121a232e 3179 }
pcercuei 0:03b5121a232e 3180
pcercuei 0:03b5121a232e 3181 return(ret);
pcercuei 0:03b5121a232e 3182 }
pcercuei 0:03b5121a232e 3183
pcercuei 0:03b5121a232e 3184 /************************************************************************
pcercuei 0:03b5121a232e 3185 * *
pcercuei 0:03b5121a232e 3186 * The parser itself *
pcercuei 0:03b5121a232e 3187 * Relates to http://www.w3.org/TR/REC-xml *
pcercuei 0:03b5121a232e 3188 * *
pcercuei 0:03b5121a232e 3189 ************************************************************************/
pcercuei 0:03b5121a232e 3190
pcercuei 0:03b5121a232e 3191 /************************************************************************
pcercuei 0:03b5121a232e 3192 * *
pcercuei 0:03b5121a232e 3193 * Routines to parse Name, NCName and NmToken *
pcercuei 0:03b5121a232e 3194 * *
pcercuei 0:03b5121a232e 3195 ************************************************************************/
pcercuei 0:03b5121a232e 3196 #ifdef DEBUG
pcercuei 0:03b5121a232e 3197 static unsigned long nbParseName = 0;
pcercuei 0:03b5121a232e 3198 static unsigned long nbParseNmToken = 0;
pcercuei 0:03b5121a232e 3199 static unsigned long nbParseNCName = 0;
pcercuei 0:03b5121a232e 3200 static unsigned long nbParseNCNameComplex = 0;
pcercuei 0:03b5121a232e 3201 static unsigned long nbParseNameComplex = 0;
pcercuei 0:03b5121a232e 3202 static unsigned long nbParseStringName = 0;
pcercuei 0:03b5121a232e 3203 #endif
pcercuei 0:03b5121a232e 3204
pcercuei 0:03b5121a232e 3205 /*
pcercuei 0:03b5121a232e 3206 * The two following functions are related to the change of accepted
pcercuei 0:03b5121a232e 3207 * characters for Name and NmToken in the Revision 5 of XML-1.0
pcercuei 0:03b5121a232e 3208 * They correspond to the modified production [4] and the new production [4a]
pcercuei 0:03b5121a232e 3209 * changes in that revision. Also note that the macros used for the
pcercuei 0:03b5121a232e 3210 * productions Letter, Digit, CombiningChar and Extender are not needed
pcercuei 0:03b5121a232e 3211 * anymore.
pcercuei 0:03b5121a232e 3212 * We still keep compatibility to pre-revision5 parsing semantic if the
pcercuei 0:03b5121a232e 3213 * new XML_PARSE_OLD10 option is given to the parser.
pcercuei 0:03b5121a232e 3214 */
pcercuei 0:03b5121a232e 3215 static int
pcercuei 0:03b5121a232e 3216 xmlIsNameStartChar(xmlParserCtxtPtr ctxt, int c) {
pcercuei 0:03b5121a232e 3217 if ((ctxt->options & XML_PARSE_OLD10) == 0) {
pcercuei 0:03b5121a232e 3218 /*
pcercuei 0:03b5121a232e 3219 * Use the new checks of production [4] [4a] amd [5] of the
pcercuei 0:03b5121a232e 3220 * Update 5 of XML-1.0
pcercuei 0:03b5121a232e 3221 */
pcercuei 0:03b5121a232e 3222 if ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
pcercuei 0:03b5121a232e 3223 (((c >= 'a') && (c <= 'z')) ||
pcercuei 0:03b5121a232e 3224 ((c >= 'A') && (c <= 'Z')) ||
pcercuei 0:03b5121a232e 3225 (c == '_') || (c == ':') ||
pcercuei 0:03b5121a232e 3226 ((c >= 0xC0) && (c <= 0xD6)) ||
pcercuei 0:03b5121a232e 3227 ((c >= 0xD8) && (c <= 0xF6)) ||
pcercuei 0:03b5121a232e 3228 ((c >= 0xF8) && (c <= 0x2FF)) ||
pcercuei 0:03b5121a232e 3229 ((c >= 0x370) && (c <= 0x37D)) ||
pcercuei 0:03b5121a232e 3230 ((c >= 0x37F) && (c <= 0x1FFF)) ||
pcercuei 0:03b5121a232e 3231 ((c >= 0x200C) && (c <= 0x200D)) ||
pcercuei 0:03b5121a232e 3232 ((c >= 0x2070) && (c <= 0x218F)) ||
pcercuei 0:03b5121a232e 3233 ((c >= 0x2C00) && (c <= 0x2FEF)) ||
pcercuei 0:03b5121a232e 3234 ((c >= 0x3001) && (c <= 0xD7FF)) ||
pcercuei 0:03b5121a232e 3235 ((c >= 0xF900) && (c <= 0xFDCF)) ||
pcercuei 0:03b5121a232e 3236 ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
pcercuei 0:03b5121a232e 3237 ((c >= 0x10000) && (c <= 0xEFFFF))))
pcercuei 0:03b5121a232e 3238 return(1);
pcercuei 0:03b5121a232e 3239 } else {
pcercuei 0:03b5121a232e 3240 if (IS_LETTER(c) || (c == '_') || (c == ':'))
pcercuei 0:03b5121a232e 3241 return(1);
pcercuei 0:03b5121a232e 3242 }
pcercuei 0:03b5121a232e 3243 return(0);
pcercuei 0:03b5121a232e 3244 }
pcercuei 0:03b5121a232e 3245
pcercuei 0:03b5121a232e 3246 static int
pcercuei 0:03b5121a232e 3247 xmlIsNameChar(xmlParserCtxtPtr ctxt, int c) {
pcercuei 0:03b5121a232e 3248 if ((ctxt->options & XML_PARSE_OLD10) == 0) {
pcercuei 0:03b5121a232e 3249 /*
pcercuei 0:03b5121a232e 3250 * Use the new checks of production [4] [4a] amd [5] of the
pcercuei 0:03b5121a232e 3251 * Update 5 of XML-1.0
pcercuei 0:03b5121a232e 3252 */
pcercuei 0:03b5121a232e 3253 if ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
pcercuei 0:03b5121a232e 3254 (((c >= 'a') && (c <= 'z')) ||
pcercuei 0:03b5121a232e 3255 ((c >= 'A') && (c <= 'Z')) ||
pcercuei 0:03b5121a232e 3256 ((c >= '0') && (c <= '9')) || /* !start */
pcercuei 0:03b5121a232e 3257 (c == '_') || (c == ':') ||
pcercuei 0:03b5121a232e 3258 (c == '-') || (c == '.') || (c == 0xB7) || /* !start */
pcercuei 0:03b5121a232e 3259 ((c >= 0xC0) && (c <= 0xD6)) ||
pcercuei 0:03b5121a232e 3260 ((c >= 0xD8) && (c <= 0xF6)) ||
pcercuei 0:03b5121a232e 3261 ((c >= 0xF8) && (c <= 0x2FF)) ||
pcercuei 0:03b5121a232e 3262 ((c >= 0x300) && (c <= 0x36F)) || /* !start */
pcercuei 0:03b5121a232e 3263 ((c >= 0x370) && (c <= 0x37D)) ||
pcercuei 0:03b5121a232e 3264 ((c >= 0x37F) && (c <= 0x1FFF)) ||
pcercuei 0:03b5121a232e 3265 ((c >= 0x200C) && (c <= 0x200D)) ||
pcercuei 0:03b5121a232e 3266 ((c >= 0x203F) && (c <= 0x2040)) || /* !start */
pcercuei 0:03b5121a232e 3267 ((c >= 0x2070) && (c <= 0x218F)) ||
pcercuei 0:03b5121a232e 3268 ((c >= 0x2C00) && (c <= 0x2FEF)) ||
pcercuei 0:03b5121a232e 3269 ((c >= 0x3001) && (c <= 0xD7FF)) ||
pcercuei 0:03b5121a232e 3270 ((c >= 0xF900) && (c <= 0xFDCF)) ||
pcercuei 0:03b5121a232e 3271 ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
pcercuei 0:03b5121a232e 3272 ((c >= 0x10000) && (c <= 0xEFFFF))))
pcercuei 0:03b5121a232e 3273 return(1);
pcercuei 0:03b5121a232e 3274 } else {
pcercuei 0:03b5121a232e 3275 if ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
pcercuei 0:03b5121a232e 3276 (c == '.') || (c == '-') ||
pcercuei 0:03b5121a232e 3277 (c == '_') || (c == ':') ||
pcercuei 0:03b5121a232e 3278 (IS_COMBINING(c)) ||
pcercuei 0:03b5121a232e 3279 (IS_EXTENDER(c)))
pcercuei 0:03b5121a232e 3280 return(1);
pcercuei 0:03b5121a232e 3281 }
pcercuei 0:03b5121a232e 3282 return(0);
pcercuei 0:03b5121a232e 3283 }
pcercuei 0:03b5121a232e 3284
pcercuei 0:03b5121a232e 3285 static xmlChar * xmlParseAttValueInternal(xmlParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 3286 int *len, int *alloc, int normalize);
pcercuei 0:03b5121a232e 3287
pcercuei 0:03b5121a232e 3288 static const xmlChar *
pcercuei 0:03b5121a232e 3289 xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 3290 int len = 0, l;
pcercuei 0:03b5121a232e 3291 int c;
pcercuei 0:03b5121a232e 3292 int count = 0;
pcercuei 0:03b5121a232e 3293
pcercuei 0:03b5121a232e 3294 #ifdef DEBUG
pcercuei 0:03b5121a232e 3295 nbParseNameComplex++;
pcercuei 0:03b5121a232e 3296 #endif
pcercuei 0:03b5121a232e 3297
pcercuei 0:03b5121a232e 3298 /*
pcercuei 0:03b5121a232e 3299 * Handler for more complex cases
pcercuei 0:03b5121a232e 3300 */
pcercuei 0:03b5121a232e 3301 GROW;
pcercuei 0:03b5121a232e 3302 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 3303 return(NULL);
pcercuei 0:03b5121a232e 3304 c = CUR_CHAR(l);
pcercuei 0:03b5121a232e 3305 if ((ctxt->options & XML_PARSE_OLD10) == 0) {
pcercuei 0:03b5121a232e 3306 /*
pcercuei 0:03b5121a232e 3307 * Use the new checks of production [4] [4a] amd [5] of the
pcercuei 0:03b5121a232e 3308 * Update 5 of XML-1.0
pcercuei 0:03b5121a232e 3309 */
pcercuei 0:03b5121a232e 3310 if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
pcercuei 0:03b5121a232e 3311 (!(((c >= 'a') && (c <= 'z')) ||
pcercuei 0:03b5121a232e 3312 ((c >= 'A') && (c <= 'Z')) ||
pcercuei 0:03b5121a232e 3313 (c == '_') || (c == ':') ||
pcercuei 0:03b5121a232e 3314 ((c >= 0xC0) && (c <= 0xD6)) ||
pcercuei 0:03b5121a232e 3315 ((c >= 0xD8) && (c <= 0xF6)) ||
pcercuei 0:03b5121a232e 3316 ((c >= 0xF8) && (c <= 0x2FF)) ||
pcercuei 0:03b5121a232e 3317 ((c >= 0x370) && (c <= 0x37D)) ||
pcercuei 0:03b5121a232e 3318 ((c >= 0x37F) && (c <= 0x1FFF)) ||
pcercuei 0:03b5121a232e 3319 ((c >= 0x200C) && (c <= 0x200D)) ||
pcercuei 0:03b5121a232e 3320 ((c >= 0x2070) && (c <= 0x218F)) ||
pcercuei 0:03b5121a232e 3321 ((c >= 0x2C00) && (c <= 0x2FEF)) ||
pcercuei 0:03b5121a232e 3322 ((c >= 0x3001) && (c <= 0xD7FF)) ||
pcercuei 0:03b5121a232e 3323 ((c >= 0xF900) && (c <= 0xFDCF)) ||
pcercuei 0:03b5121a232e 3324 ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
pcercuei 0:03b5121a232e 3325 ((c >= 0x10000) && (c <= 0xEFFFF))))) {
pcercuei 0:03b5121a232e 3326 return(NULL);
pcercuei 0:03b5121a232e 3327 }
pcercuei 0:03b5121a232e 3328 len += l;
pcercuei 0:03b5121a232e 3329 NEXTL(l);
pcercuei 0:03b5121a232e 3330 c = CUR_CHAR(l);
pcercuei 0:03b5121a232e 3331 while ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
pcercuei 0:03b5121a232e 3332 (((c >= 'a') && (c <= 'z')) ||
pcercuei 0:03b5121a232e 3333 ((c >= 'A') && (c <= 'Z')) ||
pcercuei 0:03b5121a232e 3334 ((c >= '0') && (c <= '9')) || /* !start */
pcercuei 0:03b5121a232e 3335 (c == '_') || (c == ':') ||
pcercuei 0:03b5121a232e 3336 (c == '-') || (c == '.') || (c == 0xB7) || /* !start */
pcercuei 0:03b5121a232e 3337 ((c >= 0xC0) && (c <= 0xD6)) ||
pcercuei 0:03b5121a232e 3338 ((c >= 0xD8) && (c <= 0xF6)) ||
pcercuei 0:03b5121a232e 3339 ((c >= 0xF8) && (c <= 0x2FF)) ||
pcercuei 0:03b5121a232e 3340 ((c >= 0x300) && (c <= 0x36F)) || /* !start */
pcercuei 0:03b5121a232e 3341 ((c >= 0x370) && (c <= 0x37D)) ||
pcercuei 0:03b5121a232e 3342 ((c >= 0x37F) && (c <= 0x1FFF)) ||
pcercuei 0:03b5121a232e 3343 ((c >= 0x200C) && (c <= 0x200D)) ||
pcercuei 0:03b5121a232e 3344 ((c >= 0x203F) && (c <= 0x2040)) || /* !start */
pcercuei 0:03b5121a232e 3345 ((c >= 0x2070) && (c <= 0x218F)) ||
pcercuei 0:03b5121a232e 3346 ((c >= 0x2C00) && (c <= 0x2FEF)) ||
pcercuei 0:03b5121a232e 3347 ((c >= 0x3001) && (c <= 0xD7FF)) ||
pcercuei 0:03b5121a232e 3348 ((c >= 0xF900) && (c <= 0xFDCF)) ||
pcercuei 0:03b5121a232e 3349 ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
pcercuei 0:03b5121a232e 3350 ((c >= 0x10000) && (c <= 0xEFFFF))
pcercuei 0:03b5121a232e 3351 )) {
pcercuei 0:03b5121a232e 3352 if (count++ > XML_PARSER_CHUNK_SIZE) {
pcercuei 0:03b5121a232e 3353 count = 0;
pcercuei 0:03b5121a232e 3354 GROW;
pcercuei 0:03b5121a232e 3355 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 3356 return(NULL);
pcercuei 0:03b5121a232e 3357 }
pcercuei 0:03b5121a232e 3358 len += l;
pcercuei 0:03b5121a232e 3359 NEXTL(l);
pcercuei 0:03b5121a232e 3360 c = CUR_CHAR(l);
pcercuei 0:03b5121a232e 3361 }
pcercuei 0:03b5121a232e 3362 } else {
pcercuei 0:03b5121a232e 3363 if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
pcercuei 0:03b5121a232e 3364 (!IS_LETTER(c) && (c != '_') &&
pcercuei 0:03b5121a232e 3365 (c != ':'))) {
pcercuei 0:03b5121a232e 3366 return(NULL);
pcercuei 0:03b5121a232e 3367 }
pcercuei 0:03b5121a232e 3368 len += l;
pcercuei 0:03b5121a232e 3369 NEXTL(l);
pcercuei 0:03b5121a232e 3370 c = CUR_CHAR(l);
pcercuei 0:03b5121a232e 3371
pcercuei 0:03b5121a232e 3372 while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
pcercuei 0:03b5121a232e 3373 ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
pcercuei 0:03b5121a232e 3374 (c == '.') || (c == '-') ||
pcercuei 0:03b5121a232e 3375 (c == '_') || (c == ':') ||
pcercuei 0:03b5121a232e 3376 (IS_COMBINING(c)) ||
pcercuei 0:03b5121a232e 3377 (IS_EXTENDER(c)))) {
pcercuei 0:03b5121a232e 3378 if (count++ > XML_PARSER_CHUNK_SIZE) {
pcercuei 0:03b5121a232e 3379 count = 0;
pcercuei 0:03b5121a232e 3380 GROW;
pcercuei 0:03b5121a232e 3381 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 3382 return(NULL);
pcercuei 0:03b5121a232e 3383 }
pcercuei 0:03b5121a232e 3384 len += l;
pcercuei 0:03b5121a232e 3385 NEXTL(l);
pcercuei 0:03b5121a232e 3386 c = CUR_CHAR(l);
pcercuei 0:03b5121a232e 3387 if (c == 0) {
pcercuei 0:03b5121a232e 3388 count = 0;
pcercuei 0:03b5121a232e 3389 GROW;
pcercuei 0:03b5121a232e 3390 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 3391 return(NULL);
pcercuei 0:03b5121a232e 3392 c = CUR_CHAR(l);
pcercuei 0:03b5121a232e 3393 }
pcercuei 0:03b5121a232e 3394 }
pcercuei 0:03b5121a232e 3395 }
pcercuei 0:03b5121a232e 3396 if ((len > XML_MAX_NAME_LENGTH) &&
pcercuei 0:03b5121a232e 3397 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
pcercuei 0:03b5121a232e 3398 xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name");
pcercuei 0:03b5121a232e 3399 return(NULL);
pcercuei 0:03b5121a232e 3400 }
pcercuei 0:03b5121a232e 3401 if ((*ctxt->input->cur == '\n') && (ctxt->input->cur[-1] == '\r'))
pcercuei 0:03b5121a232e 3402 return(xmlDictLookup(ctxt->dict, ctxt->input->cur - (len + 1), len));
pcercuei 0:03b5121a232e 3403 return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
pcercuei 0:03b5121a232e 3404 }
pcercuei 0:03b5121a232e 3405
pcercuei 0:03b5121a232e 3406 /**
pcercuei 0:03b5121a232e 3407 * xmlParseName:
pcercuei 0:03b5121a232e 3408 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 3409 *
pcercuei 0:03b5121a232e 3410 * parse an XML name.
pcercuei 0:03b5121a232e 3411 *
pcercuei 0:03b5121a232e 3412 * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
pcercuei 0:03b5121a232e 3413 * CombiningChar | Extender
pcercuei 0:03b5121a232e 3414 *
pcercuei 0:03b5121a232e 3415 * [5] Name ::= (Letter | '_' | ':') (NameChar)*
pcercuei 0:03b5121a232e 3416 *
pcercuei 0:03b5121a232e 3417 * [6] Names ::= Name (#x20 Name)*
pcercuei 0:03b5121a232e 3418 *
pcercuei 0:03b5121a232e 3419 * Returns the Name parsed or NULL
pcercuei 0:03b5121a232e 3420 */
pcercuei 0:03b5121a232e 3421
pcercuei 0:03b5121a232e 3422 const xmlChar *
pcercuei 0:03b5121a232e 3423 xmlParseName(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 3424 const xmlChar *in;
pcercuei 0:03b5121a232e 3425 const xmlChar *ret;
pcercuei 0:03b5121a232e 3426 int count = 0;
pcercuei 0:03b5121a232e 3427
pcercuei 0:03b5121a232e 3428 GROW;
pcercuei 0:03b5121a232e 3429
pcercuei 0:03b5121a232e 3430 #ifdef DEBUG
pcercuei 0:03b5121a232e 3431 nbParseName++;
pcercuei 0:03b5121a232e 3432 #endif
pcercuei 0:03b5121a232e 3433
pcercuei 0:03b5121a232e 3434 /*
pcercuei 0:03b5121a232e 3435 * Accelerator for simple ASCII names
pcercuei 0:03b5121a232e 3436 */
pcercuei 0:03b5121a232e 3437 in = ctxt->input->cur;
pcercuei 0:03b5121a232e 3438 if (((*in >= 0x61) && (*in <= 0x7A)) ||
pcercuei 0:03b5121a232e 3439 ((*in >= 0x41) && (*in <= 0x5A)) ||
pcercuei 0:03b5121a232e 3440 (*in == '_') || (*in == ':')) {
pcercuei 0:03b5121a232e 3441 in++;
pcercuei 0:03b5121a232e 3442 while (((*in >= 0x61) && (*in <= 0x7A)) ||
pcercuei 0:03b5121a232e 3443 ((*in >= 0x41) && (*in <= 0x5A)) ||
pcercuei 0:03b5121a232e 3444 ((*in >= 0x30) && (*in <= 0x39)) ||
pcercuei 0:03b5121a232e 3445 (*in == '_') || (*in == '-') ||
pcercuei 0:03b5121a232e 3446 (*in == ':') || (*in == '.'))
pcercuei 0:03b5121a232e 3447 in++;
pcercuei 0:03b5121a232e 3448 if ((*in > 0) && (*in < 0x80)) {
pcercuei 0:03b5121a232e 3449 count = in - ctxt->input->cur;
pcercuei 0:03b5121a232e 3450 if ((count > XML_MAX_NAME_LENGTH) &&
pcercuei 0:03b5121a232e 3451 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
pcercuei 0:03b5121a232e 3452 xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name");
pcercuei 0:03b5121a232e 3453 return(NULL);
pcercuei 0:03b5121a232e 3454 }
pcercuei 0:03b5121a232e 3455 ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
pcercuei 0:03b5121a232e 3456 ctxt->input->cur = in;
pcercuei 0:03b5121a232e 3457 ctxt->nbChars += count;
pcercuei 0:03b5121a232e 3458 ctxt->input->col += count;
pcercuei 0:03b5121a232e 3459 if (ret == NULL)
pcercuei 0:03b5121a232e 3460 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 3461 return(ret);
pcercuei 0:03b5121a232e 3462 }
pcercuei 0:03b5121a232e 3463 }
pcercuei 0:03b5121a232e 3464 /* accelerator for special cases */
pcercuei 0:03b5121a232e 3465 return(xmlParseNameComplex(ctxt));
pcercuei 0:03b5121a232e 3466 }
pcercuei 0:03b5121a232e 3467
pcercuei 0:03b5121a232e 3468 static const xmlChar *
pcercuei 0:03b5121a232e 3469 xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 3470 int len = 0, l;
pcercuei 0:03b5121a232e 3471 int c;
pcercuei 0:03b5121a232e 3472 int count = 0;
pcercuei 0:03b5121a232e 3473 const xmlChar *end; /* needed because CUR_CHAR() can move cur on \r\n */
pcercuei 0:03b5121a232e 3474
pcercuei 0:03b5121a232e 3475 #ifdef DEBUG
pcercuei 0:03b5121a232e 3476 nbParseNCNameComplex++;
pcercuei 0:03b5121a232e 3477 #endif
pcercuei 0:03b5121a232e 3478
pcercuei 0:03b5121a232e 3479 /*
pcercuei 0:03b5121a232e 3480 * Handler for more complex cases
pcercuei 0:03b5121a232e 3481 */
pcercuei 0:03b5121a232e 3482 GROW;
pcercuei 0:03b5121a232e 3483 end = ctxt->input->cur;
pcercuei 0:03b5121a232e 3484 c = CUR_CHAR(l);
pcercuei 0:03b5121a232e 3485 if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
pcercuei 0:03b5121a232e 3486 (!xmlIsNameStartChar(ctxt, c) || (c == ':'))) {
pcercuei 0:03b5121a232e 3487 return(NULL);
pcercuei 0:03b5121a232e 3488 }
pcercuei 0:03b5121a232e 3489
pcercuei 0:03b5121a232e 3490 while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
pcercuei 0:03b5121a232e 3491 (xmlIsNameChar(ctxt, c) && (c != ':'))) {
pcercuei 0:03b5121a232e 3492 if (count++ > XML_PARSER_CHUNK_SIZE) {
pcercuei 0:03b5121a232e 3493 if ((len > XML_MAX_NAME_LENGTH) &&
pcercuei 0:03b5121a232e 3494 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
pcercuei 0:03b5121a232e 3495 xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
pcercuei 0:03b5121a232e 3496 return(NULL);
pcercuei 0:03b5121a232e 3497 }
pcercuei 0:03b5121a232e 3498 count = 0;
pcercuei 0:03b5121a232e 3499 GROW;
pcercuei 0:03b5121a232e 3500 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 3501 return(NULL);
pcercuei 0:03b5121a232e 3502 }
pcercuei 0:03b5121a232e 3503 len += l;
pcercuei 0:03b5121a232e 3504 NEXTL(l);
pcercuei 0:03b5121a232e 3505 end = ctxt->input->cur;
pcercuei 0:03b5121a232e 3506 c = CUR_CHAR(l);
pcercuei 0:03b5121a232e 3507 if (c == 0) {
pcercuei 0:03b5121a232e 3508 count = 0;
pcercuei 0:03b5121a232e 3509 /*
pcercuei 0:03b5121a232e 3510 * when shrinking to extend the buffer we really need to preserve
pcercuei 0:03b5121a232e 3511 * the part of the name we already parsed. Hence rolling back
pcercuei 0:03b5121a232e 3512 * by current lenght.
pcercuei 0:03b5121a232e 3513 */
pcercuei 0:03b5121a232e 3514 ctxt->input->cur -= l;
pcercuei 0:03b5121a232e 3515 GROW;
pcercuei 0:03b5121a232e 3516 ctxt->input->cur += l;
pcercuei 0:03b5121a232e 3517 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 3518 return(NULL);
pcercuei 0:03b5121a232e 3519 end = ctxt->input->cur;
pcercuei 0:03b5121a232e 3520 c = CUR_CHAR(l);
pcercuei 0:03b5121a232e 3521 }
pcercuei 0:03b5121a232e 3522 }
pcercuei 0:03b5121a232e 3523 if ((len > XML_MAX_NAME_LENGTH) &&
pcercuei 0:03b5121a232e 3524 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
pcercuei 0:03b5121a232e 3525 xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
pcercuei 0:03b5121a232e 3526 return(NULL);
pcercuei 0:03b5121a232e 3527 }
pcercuei 0:03b5121a232e 3528 return(xmlDictLookup(ctxt->dict, end - len, len));
pcercuei 0:03b5121a232e 3529 }
pcercuei 0:03b5121a232e 3530
pcercuei 0:03b5121a232e 3531 /**
pcercuei 0:03b5121a232e 3532 * xmlParseNCName:
pcercuei 0:03b5121a232e 3533 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 3534 * @len: length of the string parsed
pcercuei 0:03b5121a232e 3535 *
pcercuei 0:03b5121a232e 3536 * parse an XML name.
pcercuei 0:03b5121a232e 3537 *
pcercuei 0:03b5121a232e 3538 * [4NS] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |
pcercuei 0:03b5121a232e 3539 * CombiningChar | Extender
pcercuei 0:03b5121a232e 3540 *
pcercuei 0:03b5121a232e 3541 * [5NS] NCName ::= (Letter | '_') (NCNameChar)*
pcercuei 0:03b5121a232e 3542 *
pcercuei 0:03b5121a232e 3543 * Returns the Name parsed or NULL
pcercuei 0:03b5121a232e 3544 */
pcercuei 0:03b5121a232e 3545
pcercuei 0:03b5121a232e 3546 static const xmlChar *
pcercuei 0:03b5121a232e 3547 xmlParseNCName(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 3548 const xmlChar *in, *e;
pcercuei 0:03b5121a232e 3549 const xmlChar *ret;
pcercuei 0:03b5121a232e 3550 int count = 0;
pcercuei 0:03b5121a232e 3551
pcercuei 0:03b5121a232e 3552 #ifdef DEBUG
pcercuei 0:03b5121a232e 3553 nbParseNCName++;
pcercuei 0:03b5121a232e 3554 #endif
pcercuei 0:03b5121a232e 3555
pcercuei 0:03b5121a232e 3556 /*
pcercuei 0:03b5121a232e 3557 * Accelerator for simple ASCII names
pcercuei 0:03b5121a232e 3558 */
pcercuei 0:03b5121a232e 3559 in = ctxt->input->cur;
pcercuei 0:03b5121a232e 3560 e = ctxt->input->end;
pcercuei 0:03b5121a232e 3561 if ((((*in >= 0x61) && (*in <= 0x7A)) ||
pcercuei 0:03b5121a232e 3562 ((*in >= 0x41) && (*in <= 0x5A)) ||
pcercuei 0:03b5121a232e 3563 (*in == '_')) && (in < e)) {
pcercuei 0:03b5121a232e 3564 in++;
pcercuei 0:03b5121a232e 3565 while ((((*in >= 0x61) && (*in <= 0x7A)) ||
pcercuei 0:03b5121a232e 3566 ((*in >= 0x41) && (*in <= 0x5A)) ||
pcercuei 0:03b5121a232e 3567 ((*in >= 0x30) && (*in <= 0x39)) ||
pcercuei 0:03b5121a232e 3568 (*in == '_') || (*in == '-') ||
pcercuei 0:03b5121a232e 3569 (*in == '.')) && (in < e))
pcercuei 0:03b5121a232e 3570 in++;
pcercuei 0:03b5121a232e 3571 if (in >= e)
pcercuei 0:03b5121a232e 3572 goto complex;
pcercuei 0:03b5121a232e 3573 if ((*in > 0) && (*in < 0x80)) {
pcercuei 0:03b5121a232e 3574 count = in - ctxt->input->cur;
pcercuei 0:03b5121a232e 3575 if ((count > XML_MAX_NAME_LENGTH) &&
pcercuei 0:03b5121a232e 3576 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
pcercuei 0:03b5121a232e 3577 xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
pcercuei 0:03b5121a232e 3578 return(NULL);
pcercuei 0:03b5121a232e 3579 }
pcercuei 0:03b5121a232e 3580 ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
pcercuei 0:03b5121a232e 3581 ctxt->input->cur = in;
pcercuei 0:03b5121a232e 3582 ctxt->nbChars += count;
pcercuei 0:03b5121a232e 3583 ctxt->input->col += count;
pcercuei 0:03b5121a232e 3584 if (ret == NULL) {
pcercuei 0:03b5121a232e 3585 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 3586 }
pcercuei 0:03b5121a232e 3587 return(ret);
pcercuei 0:03b5121a232e 3588 }
pcercuei 0:03b5121a232e 3589 }
pcercuei 0:03b5121a232e 3590 complex:
pcercuei 0:03b5121a232e 3591 return(xmlParseNCNameComplex(ctxt));
pcercuei 0:03b5121a232e 3592 }
pcercuei 0:03b5121a232e 3593
pcercuei 0:03b5121a232e 3594 /**
pcercuei 0:03b5121a232e 3595 * xmlParseNameAndCompare:
pcercuei 0:03b5121a232e 3596 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 3597 *
pcercuei 0:03b5121a232e 3598 * parse an XML name and compares for match
pcercuei 0:03b5121a232e 3599 * (specialized for endtag parsing)
pcercuei 0:03b5121a232e 3600 *
pcercuei 0:03b5121a232e 3601 * Returns NULL for an illegal name, (xmlChar*) 1 for success
pcercuei 0:03b5121a232e 3602 * and the name for mismatch
pcercuei 0:03b5121a232e 3603 */
pcercuei 0:03b5121a232e 3604
pcercuei 0:03b5121a232e 3605 static const xmlChar *
pcercuei 0:03b5121a232e 3606 xmlParseNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *other) {
pcercuei 0:03b5121a232e 3607 register const xmlChar *cmp = other;
pcercuei 0:03b5121a232e 3608 register const xmlChar *in;
pcercuei 0:03b5121a232e 3609 const xmlChar *ret;
pcercuei 0:03b5121a232e 3610
pcercuei 0:03b5121a232e 3611 GROW;
pcercuei 0:03b5121a232e 3612 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 3613 return(NULL);
pcercuei 0:03b5121a232e 3614
pcercuei 0:03b5121a232e 3615 in = ctxt->input->cur;
pcercuei 0:03b5121a232e 3616 while (*in != 0 && *in == *cmp) {
pcercuei 0:03b5121a232e 3617 ++in;
pcercuei 0:03b5121a232e 3618 ++cmp;
pcercuei 0:03b5121a232e 3619 ctxt->input->col++;
pcercuei 0:03b5121a232e 3620 }
pcercuei 0:03b5121a232e 3621 if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) {
pcercuei 0:03b5121a232e 3622 /* success */
pcercuei 0:03b5121a232e 3623 ctxt->input->cur = in;
pcercuei 0:03b5121a232e 3624 return (const xmlChar*) 1;
pcercuei 0:03b5121a232e 3625 }
pcercuei 0:03b5121a232e 3626 /* failure (or end of input buffer), check with full function */
pcercuei 0:03b5121a232e 3627 ret = xmlParseName (ctxt);
pcercuei 0:03b5121a232e 3628 /* strings coming from the dictionnary direct compare possible */
pcercuei 0:03b5121a232e 3629 if (ret == other) {
pcercuei 0:03b5121a232e 3630 return (const xmlChar*) 1;
pcercuei 0:03b5121a232e 3631 }
pcercuei 0:03b5121a232e 3632 return ret;
pcercuei 0:03b5121a232e 3633 }
pcercuei 0:03b5121a232e 3634
pcercuei 0:03b5121a232e 3635 /**
pcercuei 0:03b5121a232e 3636 * xmlParseStringName:
pcercuei 0:03b5121a232e 3637 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 3638 * @str: a pointer to the string pointer (IN/OUT)
pcercuei 0:03b5121a232e 3639 *
pcercuei 0:03b5121a232e 3640 * parse an XML name.
pcercuei 0:03b5121a232e 3641 *
pcercuei 0:03b5121a232e 3642 * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
pcercuei 0:03b5121a232e 3643 * CombiningChar | Extender
pcercuei 0:03b5121a232e 3644 *
pcercuei 0:03b5121a232e 3645 * [5] Name ::= (Letter | '_' | ':') (NameChar)*
pcercuei 0:03b5121a232e 3646 *
pcercuei 0:03b5121a232e 3647 * [6] Names ::= Name (#x20 Name)*
pcercuei 0:03b5121a232e 3648 *
pcercuei 0:03b5121a232e 3649 * Returns the Name parsed or NULL. The @str pointer
pcercuei 0:03b5121a232e 3650 * is updated to the current location in the string.
pcercuei 0:03b5121a232e 3651 */
pcercuei 0:03b5121a232e 3652
pcercuei 0:03b5121a232e 3653 static xmlChar *
pcercuei 0:03b5121a232e 3654 xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
pcercuei 0:03b5121a232e 3655 xmlChar buf[XML_MAX_NAMELEN + 5];
pcercuei 0:03b5121a232e 3656 const xmlChar *cur = *str;
pcercuei 0:03b5121a232e 3657 int len = 0, l;
pcercuei 0:03b5121a232e 3658 int c;
pcercuei 0:03b5121a232e 3659
pcercuei 0:03b5121a232e 3660 #ifdef DEBUG
pcercuei 0:03b5121a232e 3661 nbParseStringName++;
pcercuei 0:03b5121a232e 3662 #endif
pcercuei 0:03b5121a232e 3663
pcercuei 0:03b5121a232e 3664 c = CUR_SCHAR(cur, l);
pcercuei 0:03b5121a232e 3665 if (!xmlIsNameStartChar(ctxt, c)) {
pcercuei 0:03b5121a232e 3666 return(NULL);
pcercuei 0:03b5121a232e 3667 }
pcercuei 0:03b5121a232e 3668
pcercuei 0:03b5121a232e 3669 COPY_BUF(l,buf,len,c);
pcercuei 0:03b5121a232e 3670 cur += l;
pcercuei 0:03b5121a232e 3671 c = CUR_SCHAR(cur, l);
pcercuei 0:03b5121a232e 3672 while (xmlIsNameChar(ctxt, c)) {
pcercuei 0:03b5121a232e 3673 COPY_BUF(l,buf,len,c);
pcercuei 0:03b5121a232e 3674 cur += l;
pcercuei 0:03b5121a232e 3675 c = CUR_SCHAR(cur, l);
pcercuei 0:03b5121a232e 3676 if (len >= XML_MAX_NAMELEN) { /* test bigentname.xml */
pcercuei 0:03b5121a232e 3677 /*
pcercuei 0:03b5121a232e 3678 * Okay someone managed to make a huge name, so he's ready to pay
pcercuei 0:03b5121a232e 3679 * for the processing speed.
pcercuei 0:03b5121a232e 3680 */
pcercuei 0:03b5121a232e 3681 xmlChar *buffer;
pcercuei 0:03b5121a232e 3682 int max = len * 2;
pcercuei 0:03b5121a232e 3683
pcercuei 0:03b5121a232e 3684 buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
pcercuei 0:03b5121a232e 3685 if (buffer == NULL) {
pcercuei 0:03b5121a232e 3686 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 3687 return(NULL);
pcercuei 0:03b5121a232e 3688 }
pcercuei 0:03b5121a232e 3689 memcpy(buffer, buf, len);
pcercuei 0:03b5121a232e 3690 while (xmlIsNameChar(ctxt, c)) {
pcercuei 0:03b5121a232e 3691 if (len + 10 > max) {
pcercuei 0:03b5121a232e 3692 xmlChar *tmp;
pcercuei 0:03b5121a232e 3693
pcercuei 0:03b5121a232e 3694 if ((len > XML_MAX_NAME_LENGTH) &&
pcercuei 0:03b5121a232e 3695 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
pcercuei 0:03b5121a232e 3696 xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
pcercuei 0:03b5121a232e 3697 xmlFree(buffer);
pcercuei 0:03b5121a232e 3698 return(NULL);
pcercuei 0:03b5121a232e 3699 }
pcercuei 0:03b5121a232e 3700 max *= 2;
pcercuei 0:03b5121a232e 3701 tmp = (xmlChar *) xmlRealloc(buffer,
pcercuei 0:03b5121a232e 3702 max * sizeof(xmlChar));
pcercuei 0:03b5121a232e 3703 if (tmp == NULL) {
pcercuei 0:03b5121a232e 3704 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 3705 xmlFree(buffer);
pcercuei 0:03b5121a232e 3706 return(NULL);
pcercuei 0:03b5121a232e 3707 }
pcercuei 0:03b5121a232e 3708 buffer = tmp;
pcercuei 0:03b5121a232e 3709 }
pcercuei 0:03b5121a232e 3710 COPY_BUF(l,buffer,len,c);
pcercuei 0:03b5121a232e 3711 cur += l;
pcercuei 0:03b5121a232e 3712 c = CUR_SCHAR(cur, l);
pcercuei 0:03b5121a232e 3713 }
pcercuei 0:03b5121a232e 3714 buffer[len] = 0;
pcercuei 0:03b5121a232e 3715 *str = cur;
pcercuei 0:03b5121a232e 3716 return(buffer);
pcercuei 0:03b5121a232e 3717 }
pcercuei 0:03b5121a232e 3718 }
pcercuei 0:03b5121a232e 3719 if ((len > XML_MAX_NAME_LENGTH) &&
pcercuei 0:03b5121a232e 3720 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
pcercuei 0:03b5121a232e 3721 xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
pcercuei 0:03b5121a232e 3722 return(NULL);
pcercuei 0:03b5121a232e 3723 }
pcercuei 0:03b5121a232e 3724 *str = cur;
pcercuei 0:03b5121a232e 3725 return(xmlStrndup(buf, len));
pcercuei 0:03b5121a232e 3726 }
pcercuei 0:03b5121a232e 3727
pcercuei 0:03b5121a232e 3728 /**
pcercuei 0:03b5121a232e 3729 * xmlParseNmtoken:
pcercuei 0:03b5121a232e 3730 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 3731 *
pcercuei 0:03b5121a232e 3732 * parse an XML Nmtoken.
pcercuei 0:03b5121a232e 3733 *
pcercuei 0:03b5121a232e 3734 * [7] Nmtoken ::= (NameChar)+
pcercuei 0:03b5121a232e 3735 *
pcercuei 0:03b5121a232e 3736 * [8] Nmtokens ::= Nmtoken (#x20 Nmtoken)*
pcercuei 0:03b5121a232e 3737 *
pcercuei 0:03b5121a232e 3738 * Returns the Nmtoken parsed or NULL
pcercuei 0:03b5121a232e 3739 */
pcercuei 0:03b5121a232e 3740
pcercuei 0:03b5121a232e 3741 xmlChar *
pcercuei 0:03b5121a232e 3742 xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 3743 xmlChar buf[XML_MAX_NAMELEN + 5];
pcercuei 0:03b5121a232e 3744 int len = 0, l;
pcercuei 0:03b5121a232e 3745 int c;
pcercuei 0:03b5121a232e 3746 int count = 0;
pcercuei 0:03b5121a232e 3747
pcercuei 0:03b5121a232e 3748 #ifdef DEBUG
pcercuei 0:03b5121a232e 3749 nbParseNmToken++;
pcercuei 0:03b5121a232e 3750 #endif
pcercuei 0:03b5121a232e 3751
pcercuei 0:03b5121a232e 3752 GROW;
pcercuei 0:03b5121a232e 3753 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 3754 return(NULL);
pcercuei 0:03b5121a232e 3755 c = CUR_CHAR(l);
pcercuei 0:03b5121a232e 3756
pcercuei 0:03b5121a232e 3757 while (xmlIsNameChar(ctxt, c)) {
pcercuei 0:03b5121a232e 3758 if (count++ > XML_PARSER_CHUNK_SIZE) {
pcercuei 0:03b5121a232e 3759 count = 0;
pcercuei 0:03b5121a232e 3760 GROW;
pcercuei 0:03b5121a232e 3761 }
pcercuei 0:03b5121a232e 3762 COPY_BUF(l,buf,len,c);
pcercuei 0:03b5121a232e 3763 NEXTL(l);
pcercuei 0:03b5121a232e 3764 c = CUR_CHAR(l);
pcercuei 0:03b5121a232e 3765 if (c == 0) {
pcercuei 0:03b5121a232e 3766 count = 0;
pcercuei 0:03b5121a232e 3767 GROW;
pcercuei 0:03b5121a232e 3768 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 3769 return(NULL);
pcercuei 0:03b5121a232e 3770 c = CUR_CHAR(l);
pcercuei 0:03b5121a232e 3771 }
pcercuei 0:03b5121a232e 3772 if (len >= XML_MAX_NAMELEN) {
pcercuei 0:03b5121a232e 3773 /*
pcercuei 0:03b5121a232e 3774 * Okay someone managed to make a huge token, so he's ready to pay
pcercuei 0:03b5121a232e 3775 * for the processing speed.
pcercuei 0:03b5121a232e 3776 */
pcercuei 0:03b5121a232e 3777 xmlChar *buffer;
pcercuei 0:03b5121a232e 3778 int max = len * 2;
pcercuei 0:03b5121a232e 3779
pcercuei 0:03b5121a232e 3780 buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
pcercuei 0:03b5121a232e 3781 if (buffer == NULL) {
pcercuei 0:03b5121a232e 3782 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 3783 return(NULL);
pcercuei 0:03b5121a232e 3784 }
pcercuei 0:03b5121a232e 3785 memcpy(buffer, buf, len);
pcercuei 0:03b5121a232e 3786 while (xmlIsNameChar(ctxt, c)) {
pcercuei 0:03b5121a232e 3787 if (count++ > XML_PARSER_CHUNK_SIZE) {
pcercuei 0:03b5121a232e 3788 count = 0;
pcercuei 0:03b5121a232e 3789 GROW;
pcercuei 0:03b5121a232e 3790 if (ctxt->instate == XML_PARSER_EOF) {
pcercuei 0:03b5121a232e 3791 xmlFree(buffer);
pcercuei 0:03b5121a232e 3792 return(NULL);
pcercuei 0:03b5121a232e 3793 }
pcercuei 0:03b5121a232e 3794 }
pcercuei 0:03b5121a232e 3795 if (len + 10 > max) {
pcercuei 0:03b5121a232e 3796 xmlChar *tmp;
pcercuei 0:03b5121a232e 3797
pcercuei 0:03b5121a232e 3798 if ((max > XML_MAX_NAME_LENGTH) &&
pcercuei 0:03b5121a232e 3799 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
pcercuei 0:03b5121a232e 3800 xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NmToken");
pcercuei 0:03b5121a232e 3801 xmlFree(buffer);
pcercuei 0:03b5121a232e 3802 return(NULL);
pcercuei 0:03b5121a232e 3803 }
pcercuei 0:03b5121a232e 3804 max *= 2;
pcercuei 0:03b5121a232e 3805 tmp = (xmlChar *) xmlRealloc(buffer,
pcercuei 0:03b5121a232e 3806 max * sizeof(xmlChar));
pcercuei 0:03b5121a232e 3807 if (tmp == NULL) {
pcercuei 0:03b5121a232e 3808 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 3809 xmlFree(buffer);
pcercuei 0:03b5121a232e 3810 return(NULL);
pcercuei 0:03b5121a232e 3811 }
pcercuei 0:03b5121a232e 3812 buffer = tmp;
pcercuei 0:03b5121a232e 3813 }
pcercuei 0:03b5121a232e 3814 COPY_BUF(l,buffer,len,c);
pcercuei 0:03b5121a232e 3815 NEXTL(l);
pcercuei 0:03b5121a232e 3816 c = CUR_CHAR(l);
pcercuei 0:03b5121a232e 3817 }
pcercuei 0:03b5121a232e 3818 buffer[len] = 0;
pcercuei 0:03b5121a232e 3819 return(buffer);
pcercuei 0:03b5121a232e 3820 }
pcercuei 0:03b5121a232e 3821 }
pcercuei 0:03b5121a232e 3822 if (len == 0)
pcercuei 0:03b5121a232e 3823 return(NULL);
pcercuei 0:03b5121a232e 3824 if ((len > XML_MAX_NAME_LENGTH) &&
pcercuei 0:03b5121a232e 3825 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
pcercuei 0:03b5121a232e 3826 xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NmToken");
pcercuei 0:03b5121a232e 3827 return(NULL);
pcercuei 0:03b5121a232e 3828 }
pcercuei 0:03b5121a232e 3829 return(xmlStrndup(buf, len));
pcercuei 0:03b5121a232e 3830 }
pcercuei 0:03b5121a232e 3831
pcercuei 0:03b5121a232e 3832 /**
pcercuei 0:03b5121a232e 3833 * xmlParseEntityValue:
pcercuei 0:03b5121a232e 3834 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 3835 * @orig: if non-NULL store a copy of the original entity value
pcercuei 0:03b5121a232e 3836 *
pcercuei 0:03b5121a232e 3837 * parse a value for ENTITY declarations
pcercuei 0:03b5121a232e 3838 *
pcercuei 0:03b5121a232e 3839 * [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"' |
pcercuei 0:03b5121a232e 3840 * "'" ([^%&'] | PEReference | Reference)* "'"
pcercuei 0:03b5121a232e 3841 *
pcercuei 0:03b5121a232e 3842 * Returns the EntityValue parsed with reference substituted or NULL
pcercuei 0:03b5121a232e 3843 */
pcercuei 0:03b5121a232e 3844
pcercuei 0:03b5121a232e 3845 xmlChar *
pcercuei 0:03b5121a232e 3846 xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
pcercuei 0:03b5121a232e 3847 xmlChar *buf = NULL;
pcercuei 0:03b5121a232e 3848 int len = 0;
pcercuei 0:03b5121a232e 3849 int size = XML_PARSER_BUFFER_SIZE;
pcercuei 0:03b5121a232e 3850 int c, l;
pcercuei 0:03b5121a232e 3851 xmlChar stop;
pcercuei 0:03b5121a232e 3852 xmlChar *ret = NULL;
pcercuei 0:03b5121a232e 3853 const xmlChar *cur = NULL;
pcercuei 0:03b5121a232e 3854 xmlParserInputPtr input;
pcercuei 0:03b5121a232e 3855
pcercuei 0:03b5121a232e 3856 if (RAW == '"') stop = '"';
pcercuei 0:03b5121a232e 3857 else if (RAW == '\'') stop = '\'';
pcercuei 0:03b5121a232e 3858 else {
pcercuei 0:03b5121a232e 3859 xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_STARTED, NULL);
pcercuei 0:03b5121a232e 3860 return(NULL);
pcercuei 0:03b5121a232e 3861 }
pcercuei 0:03b5121a232e 3862 buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
pcercuei 0:03b5121a232e 3863 if (buf == NULL) {
pcercuei 0:03b5121a232e 3864 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 3865 return(NULL);
pcercuei 0:03b5121a232e 3866 }
pcercuei 0:03b5121a232e 3867
pcercuei 0:03b5121a232e 3868 /*
pcercuei 0:03b5121a232e 3869 * The content of the entity definition is copied in a buffer.
pcercuei 0:03b5121a232e 3870 */
pcercuei 0:03b5121a232e 3871
pcercuei 0:03b5121a232e 3872 ctxt->instate = XML_PARSER_ENTITY_VALUE;
pcercuei 0:03b5121a232e 3873 input = ctxt->input;
pcercuei 0:03b5121a232e 3874 GROW;
pcercuei 0:03b5121a232e 3875 if (ctxt->instate == XML_PARSER_EOF) {
pcercuei 0:03b5121a232e 3876 xmlFree(buf);
pcercuei 0:03b5121a232e 3877 return(NULL);
pcercuei 0:03b5121a232e 3878 }
pcercuei 0:03b5121a232e 3879 NEXT;
pcercuei 0:03b5121a232e 3880 c = CUR_CHAR(l);
pcercuei 0:03b5121a232e 3881 /*
pcercuei 0:03b5121a232e 3882 * NOTE: 4.4.5 Included in Literal
pcercuei 0:03b5121a232e 3883 * When a parameter entity reference appears in a literal entity
pcercuei 0:03b5121a232e 3884 * value, ... a single or double quote character in the replacement
pcercuei 0:03b5121a232e 3885 * text is always treated as a normal data character and will not
pcercuei 0:03b5121a232e 3886 * terminate the literal.
pcercuei 0:03b5121a232e 3887 * In practice it means we stop the loop only when back at parsing
pcercuei 0:03b5121a232e 3888 * the initial entity and the quote is found
pcercuei 0:03b5121a232e 3889 */
pcercuei 0:03b5121a232e 3890 while (((IS_CHAR(c)) && ((c != stop) || /* checked */
pcercuei 0:03b5121a232e 3891 (ctxt->input != input))) && (ctxt->instate != XML_PARSER_EOF)) {
pcercuei 0:03b5121a232e 3892 if (len + 5 >= size) {
pcercuei 0:03b5121a232e 3893 xmlChar *tmp;
pcercuei 0:03b5121a232e 3894
pcercuei 0:03b5121a232e 3895 size *= 2;
pcercuei 0:03b5121a232e 3896 tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
pcercuei 0:03b5121a232e 3897 if (tmp == NULL) {
pcercuei 0:03b5121a232e 3898 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 3899 xmlFree(buf);
pcercuei 0:03b5121a232e 3900 return(NULL);
pcercuei 0:03b5121a232e 3901 }
pcercuei 0:03b5121a232e 3902 buf = tmp;
pcercuei 0:03b5121a232e 3903 }
pcercuei 0:03b5121a232e 3904 COPY_BUF(l,buf,len,c);
pcercuei 0:03b5121a232e 3905 NEXTL(l);
pcercuei 0:03b5121a232e 3906 /*
pcercuei 0:03b5121a232e 3907 * Pop-up of finished entities.
pcercuei 0:03b5121a232e 3908 */
pcercuei 0:03b5121a232e 3909 while ((RAW == 0) && (ctxt->inputNr > 1)) /* non input consuming */
pcercuei 0:03b5121a232e 3910 xmlPopInput(ctxt);
pcercuei 0:03b5121a232e 3911
pcercuei 0:03b5121a232e 3912 GROW;
pcercuei 0:03b5121a232e 3913 c = CUR_CHAR(l);
pcercuei 0:03b5121a232e 3914 if (c == 0) {
pcercuei 0:03b5121a232e 3915 GROW;
pcercuei 0:03b5121a232e 3916 c = CUR_CHAR(l);
pcercuei 0:03b5121a232e 3917 }
pcercuei 0:03b5121a232e 3918 }
pcercuei 0:03b5121a232e 3919 buf[len] = 0;
pcercuei 0:03b5121a232e 3920 if (ctxt->instate == XML_PARSER_EOF) {
pcercuei 0:03b5121a232e 3921 xmlFree(buf);
pcercuei 0:03b5121a232e 3922 return(NULL);
pcercuei 0:03b5121a232e 3923 }
pcercuei 0:03b5121a232e 3924
pcercuei 0:03b5121a232e 3925 /*
pcercuei 0:03b5121a232e 3926 * Raise problem w.r.t. '&' and '%' being used in non-entities
pcercuei 0:03b5121a232e 3927 * reference constructs. Note Charref will be handled in
pcercuei 0:03b5121a232e 3928 * xmlStringDecodeEntities()
pcercuei 0:03b5121a232e 3929 */
pcercuei 0:03b5121a232e 3930 cur = buf;
pcercuei 0:03b5121a232e 3931 while (*cur != 0) { /* non input consuming */
pcercuei 0:03b5121a232e 3932 if ((*cur == '%') || ((*cur == '&') && (cur[1] != '#'))) {
pcercuei 0:03b5121a232e 3933 xmlChar *name;
pcercuei 0:03b5121a232e 3934 xmlChar tmp = *cur;
pcercuei 0:03b5121a232e 3935
pcercuei 0:03b5121a232e 3936 cur++;
pcercuei 0:03b5121a232e 3937 name = xmlParseStringName(ctxt, &cur);
pcercuei 0:03b5121a232e 3938 if ((name == NULL) || (*cur != ';')) {
pcercuei 0:03b5121a232e 3939 xmlFatalErrMsgInt(ctxt, XML_ERR_ENTITY_CHAR_ERROR,
pcercuei 0:03b5121a232e 3940 "EntityValue: '%c' forbidden except for entities references\n",
pcercuei 0:03b5121a232e 3941 tmp);
pcercuei 0:03b5121a232e 3942 }
pcercuei 0:03b5121a232e 3943 if ((tmp == '%') && (ctxt->inSubset == 1) &&
pcercuei 0:03b5121a232e 3944 (ctxt->inputNr == 1)) {
pcercuei 0:03b5121a232e 3945 xmlFatalErr(ctxt, XML_ERR_ENTITY_PE_INTERNAL, NULL);
pcercuei 0:03b5121a232e 3946 }
pcercuei 0:03b5121a232e 3947 if (name != NULL)
pcercuei 0:03b5121a232e 3948 xmlFree(name);
pcercuei 0:03b5121a232e 3949 if (*cur == 0)
pcercuei 0:03b5121a232e 3950 break;
pcercuei 0:03b5121a232e 3951 }
pcercuei 0:03b5121a232e 3952 cur++;
pcercuei 0:03b5121a232e 3953 }
pcercuei 0:03b5121a232e 3954
pcercuei 0:03b5121a232e 3955 /*
pcercuei 0:03b5121a232e 3956 * Then PEReference entities are substituted.
pcercuei 0:03b5121a232e 3957 */
pcercuei 0:03b5121a232e 3958 if (c != stop) {
pcercuei 0:03b5121a232e 3959 xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_FINISHED, NULL);
pcercuei 0:03b5121a232e 3960 xmlFree(buf);
pcercuei 0:03b5121a232e 3961 } else {
pcercuei 0:03b5121a232e 3962 NEXT;
pcercuei 0:03b5121a232e 3963 /*
pcercuei 0:03b5121a232e 3964 * NOTE: 4.4.7 Bypassed
pcercuei 0:03b5121a232e 3965 * When a general entity reference appears in the EntityValue in
pcercuei 0:03b5121a232e 3966 * an entity declaration, it is bypassed and left as is.
pcercuei 0:03b5121a232e 3967 * so XML_SUBSTITUTE_REF is not set here.
pcercuei 0:03b5121a232e 3968 */
pcercuei 0:03b5121a232e 3969 ret = xmlStringDecodeEntities(ctxt, buf, XML_SUBSTITUTE_PEREF,
pcercuei 0:03b5121a232e 3970 0, 0, 0);
pcercuei 0:03b5121a232e 3971 if (orig != NULL)
pcercuei 0:03b5121a232e 3972 *orig = buf;
pcercuei 0:03b5121a232e 3973 else
pcercuei 0:03b5121a232e 3974 xmlFree(buf);
pcercuei 0:03b5121a232e 3975 }
pcercuei 0:03b5121a232e 3976
pcercuei 0:03b5121a232e 3977 return(ret);
pcercuei 0:03b5121a232e 3978 }
pcercuei 0:03b5121a232e 3979
pcercuei 0:03b5121a232e 3980 /**
pcercuei 0:03b5121a232e 3981 * xmlParseAttValueComplex:
pcercuei 0:03b5121a232e 3982 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 3983 * @len: the resulting attribute len
pcercuei 0:03b5121a232e 3984 * @normalize: wether to apply the inner normalization
pcercuei 0:03b5121a232e 3985 *
pcercuei 0:03b5121a232e 3986 * parse a value for an attribute, this is the fallback function
pcercuei 0:03b5121a232e 3987 * of xmlParseAttValue() when the attribute parsing requires handling
pcercuei 0:03b5121a232e 3988 * of non-ASCII characters, or normalization compaction.
pcercuei 0:03b5121a232e 3989 *
pcercuei 0:03b5121a232e 3990 * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
pcercuei 0:03b5121a232e 3991 */
pcercuei 0:03b5121a232e 3992 static xmlChar *
pcercuei 0:03b5121a232e 3993 xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
pcercuei 0:03b5121a232e 3994 xmlChar limit = 0;
pcercuei 0:03b5121a232e 3995 xmlChar *buf = NULL;
pcercuei 0:03b5121a232e 3996 xmlChar *rep = NULL;
pcercuei 0:03b5121a232e 3997 size_t len = 0;
pcercuei 0:03b5121a232e 3998 size_t buf_size = 0;
pcercuei 0:03b5121a232e 3999 int c, l, in_space = 0;
pcercuei 0:03b5121a232e 4000 xmlChar *current = NULL;
pcercuei 0:03b5121a232e 4001 xmlEntityPtr ent;
pcercuei 0:03b5121a232e 4002
pcercuei 0:03b5121a232e 4003 if (NXT(0) == '"') {
pcercuei 0:03b5121a232e 4004 ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
pcercuei 0:03b5121a232e 4005 limit = '"';
pcercuei 0:03b5121a232e 4006 NEXT;
pcercuei 0:03b5121a232e 4007 } else if (NXT(0) == '\'') {
pcercuei 0:03b5121a232e 4008 limit = '\'';
pcercuei 0:03b5121a232e 4009 ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
pcercuei 0:03b5121a232e 4010 NEXT;
pcercuei 0:03b5121a232e 4011 } else {
pcercuei 0:03b5121a232e 4012 xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
pcercuei 0:03b5121a232e 4013 return(NULL);
pcercuei 0:03b5121a232e 4014 }
pcercuei 0:03b5121a232e 4015
pcercuei 0:03b5121a232e 4016 /*
pcercuei 0:03b5121a232e 4017 * allocate a translation buffer.
pcercuei 0:03b5121a232e 4018 */
pcercuei 0:03b5121a232e 4019 buf_size = XML_PARSER_BUFFER_SIZE;
pcercuei 0:03b5121a232e 4020 buf = (xmlChar *) xmlMallocAtomic(buf_size);
pcercuei 0:03b5121a232e 4021 if (buf == NULL) goto mem_error;
pcercuei 0:03b5121a232e 4022
pcercuei 0:03b5121a232e 4023 /*
pcercuei 0:03b5121a232e 4024 * OK loop until we reach one of the ending char or a size limit.
pcercuei 0:03b5121a232e 4025 */
pcercuei 0:03b5121a232e 4026 c = CUR_CHAR(l);
pcercuei 0:03b5121a232e 4027 while (((NXT(0) != limit) && /* checked */
pcercuei 0:03b5121a232e 4028 (IS_CHAR(c)) && (c != '<')) &&
pcercuei 0:03b5121a232e 4029 (ctxt->instate != XML_PARSER_EOF)) {
pcercuei 0:03b5121a232e 4030 /*
pcercuei 0:03b5121a232e 4031 * Impose a reasonable limit on attribute size, unless XML_PARSE_HUGE
pcercuei 0:03b5121a232e 4032 * special option is given
pcercuei 0:03b5121a232e 4033 */
pcercuei 0:03b5121a232e 4034 if ((len > XML_MAX_TEXT_LENGTH) &&
pcercuei 0:03b5121a232e 4035 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
pcercuei 0:03b5121a232e 4036 xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
pcercuei 0:03b5121a232e 4037 "AttValue length too long\n");
pcercuei 0:03b5121a232e 4038 goto mem_error;
pcercuei 0:03b5121a232e 4039 }
pcercuei 0:03b5121a232e 4040 if (c == 0) break;
pcercuei 0:03b5121a232e 4041 if (c == '&') {
pcercuei 0:03b5121a232e 4042 in_space = 0;
pcercuei 0:03b5121a232e 4043 if (NXT(1) == '#') {
pcercuei 0:03b5121a232e 4044 int val = xmlParseCharRef(ctxt);
pcercuei 0:03b5121a232e 4045
pcercuei 0:03b5121a232e 4046 if (val == '&') {
pcercuei 0:03b5121a232e 4047 if (ctxt->replaceEntities) {
pcercuei 0:03b5121a232e 4048 if (len + 10 > buf_size) {
pcercuei 0:03b5121a232e 4049 growBuffer(buf, 10);
pcercuei 0:03b5121a232e 4050 }
pcercuei 0:03b5121a232e 4051 buf[len++] = '&';
pcercuei 0:03b5121a232e 4052 } else {
pcercuei 0:03b5121a232e 4053 /*
pcercuei 0:03b5121a232e 4054 * The reparsing will be done in xmlStringGetNodeList()
pcercuei 0:03b5121a232e 4055 * called by the attribute() function in SAX.c
pcercuei 0:03b5121a232e 4056 */
pcercuei 0:03b5121a232e 4057 if (len + 10 > buf_size) {
pcercuei 0:03b5121a232e 4058 growBuffer(buf, 10);
pcercuei 0:03b5121a232e 4059 }
pcercuei 0:03b5121a232e 4060 buf[len++] = '&';
pcercuei 0:03b5121a232e 4061 buf[len++] = '#';
pcercuei 0:03b5121a232e 4062 buf[len++] = '3';
pcercuei 0:03b5121a232e 4063 buf[len++] = '8';
pcercuei 0:03b5121a232e 4064 buf[len++] = ';';
pcercuei 0:03b5121a232e 4065 }
pcercuei 0:03b5121a232e 4066 } else if (val != 0) {
pcercuei 0:03b5121a232e 4067 if (len + 10 > buf_size) {
pcercuei 0:03b5121a232e 4068 growBuffer(buf, 10);
pcercuei 0:03b5121a232e 4069 }
pcercuei 0:03b5121a232e 4070 len += xmlCopyChar(0, &buf[len], val);
pcercuei 0:03b5121a232e 4071 }
pcercuei 0:03b5121a232e 4072 } else {
pcercuei 0:03b5121a232e 4073 ent = xmlParseEntityRef(ctxt);
pcercuei 0:03b5121a232e 4074 ctxt->nbentities++;
pcercuei 0:03b5121a232e 4075 if (ent != NULL)
pcercuei 0:03b5121a232e 4076 ctxt->nbentities += ent->owner;
pcercuei 0:03b5121a232e 4077 if ((ent != NULL) &&
pcercuei 0:03b5121a232e 4078 (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
pcercuei 0:03b5121a232e 4079 if (len + 10 > buf_size) {
pcercuei 0:03b5121a232e 4080 growBuffer(buf, 10);
pcercuei 0:03b5121a232e 4081 }
pcercuei 0:03b5121a232e 4082 if ((ctxt->replaceEntities == 0) &&
pcercuei 0:03b5121a232e 4083 (ent->content[0] == '&')) {
pcercuei 0:03b5121a232e 4084 buf[len++] = '&';
pcercuei 0:03b5121a232e 4085 buf[len++] = '#';
pcercuei 0:03b5121a232e 4086 buf[len++] = '3';
pcercuei 0:03b5121a232e 4087 buf[len++] = '8';
pcercuei 0:03b5121a232e 4088 buf[len++] = ';';
pcercuei 0:03b5121a232e 4089 } else {
pcercuei 0:03b5121a232e 4090 buf[len++] = ent->content[0];
pcercuei 0:03b5121a232e 4091 }
pcercuei 0:03b5121a232e 4092 } else if ((ent != NULL) &&
pcercuei 0:03b5121a232e 4093 (ctxt->replaceEntities != 0)) {
pcercuei 0:03b5121a232e 4094 if (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) {
pcercuei 0:03b5121a232e 4095 rep = xmlStringDecodeEntities(ctxt, ent->content,
pcercuei 0:03b5121a232e 4096 XML_SUBSTITUTE_REF,
pcercuei 0:03b5121a232e 4097 0, 0, 0);
pcercuei 0:03b5121a232e 4098 if (rep != NULL) {
pcercuei 0:03b5121a232e 4099 current = rep;
pcercuei 0:03b5121a232e 4100 while (*current != 0) { /* non input consuming */
pcercuei 0:03b5121a232e 4101 if ((*current == 0xD) || (*current == 0xA) ||
pcercuei 0:03b5121a232e 4102 (*current == 0x9)) {
pcercuei 0:03b5121a232e 4103 buf[len++] = 0x20;
pcercuei 0:03b5121a232e 4104 current++;
pcercuei 0:03b5121a232e 4105 } else
pcercuei 0:03b5121a232e 4106 buf[len++] = *current++;
pcercuei 0:03b5121a232e 4107 if (len + 10 > buf_size) {
pcercuei 0:03b5121a232e 4108 growBuffer(buf, 10);
pcercuei 0:03b5121a232e 4109 }
pcercuei 0:03b5121a232e 4110 }
pcercuei 0:03b5121a232e 4111 xmlFree(rep);
pcercuei 0:03b5121a232e 4112 rep = NULL;
pcercuei 0:03b5121a232e 4113 }
pcercuei 0:03b5121a232e 4114 } else {
pcercuei 0:03b5121a232e 4115 if (len + 10 > buf_size) {
pcercuei 0:03b5121a232e 4116 growBuffer(buf, 10);
pcercuei 0:03b5121a232e 4117 }
pcercuei 0:03b5121a232e 4118 if (ent->content != NULL)
pcercuei 0:03b5121a232e 4119 buf[len++] = ent->content[0];
pcercuei 0:03b5121a232e 4120 }
pcercuei 0:03b5121a232e 4121 } else if (ent != NULL) {
pcercuei 0:03b5121a232e 4122 int i = xmlStrlen(ent->name);
pcercuei 0:03b5121a232e 4123 const xmlChar *cur = ent->name;
pcercuei 0:03b5121a232e 4124
pcercuei 0:03b5121a232e 4125 /*
pcercuei 0:03b5121a232e 4126 * This may look absurd but is needed to detect
pcercuei 0:03b5121a232e 4127 * entities problems
pcercuei 0:03b5121a232e 4128 */
pcercuei 0:03b5121a232e 4129 if ((ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
pcercuei 0:03b5121a232e 4130 (ent->content != NULL) && (ent->checked == 0)) {
pcercuei 0:03b5121a232e 4131 unsigned long oldnbent = ctxt->nbentities;
pcercuei 0:03b5121a232e 4132
pcercuei 0:03b5121a232e 4133 rep = xmlStringDecodeEntities(ctxt, ent->content,
pcercuei 0:03b5121a232e 4134 XML_SUBSTITUTE_REF, 0, 0, 0);
pcercuei 0:03b5121a232e 4135
pcercuei 0:03b5121a232e 4136 ent->checked = (ctxt->nbentities - oldnbent + 1) * 2;
pcercuei 0:03b5121a232e 4137 if (rep != NULL) {
pcercuei 0:03b5121a232e 4138 if (xmlStrchr(rep, '<'))
pcercuei 0:03b5121a232e 4139 ent->checked |= 1;
pcercuei 0:03b5121a232e 4140 xmlFree(rep);
pcercuei 0:03b5121a232e 4141 rep = NULL;
pcercuei 0:03b5121a232e 4142 }
pcercuei 0:03b5121a232e 4143 }
pcercuei 0:03b5121a232e 4144
pcercuei 0:03b5121a232e 4145 /*
pcercuei 0:03b5121a232e 4146 * Just output the reference
pcercuei 0:03b5121a232e 4147 */
pcercuei 0:03b5121a232e 4148 buf[len++] = '&';
pcercuei 0:03b5121a232e 4149 while (len + i + 10 > buf_size) {
pcercuei 0:03b5121a232e 4150 growBuffer(buf, i + 10);
pcercuei 0:03b5121a232e 4151 }
pcercuei 0:03b5121a232e 4152 for (;i > 0;i--)
pcercuei 0:03b5121a232e 4153 buf[len++] = *cur++;
pcercuei 0:03b5121a232e 4154 buf[len++] = ';';
pcercuei 0:03b5121a232e 4155 }
pcercuei 0:03b5121a232e 4156 }
pcercuei 0:03b5121a232e 4157 } else {
pcercuei 0:03b5121a232e 4158 if ((c == 0x20) || (c == 0xD) || (c == 0xA) || (c == 0x9)) {
pcercuei 0:03b5121a232e 4159 if ((len != 0) || (!normalize)) {
pcercuei 0:03b5121a232e 4160 if ((!normalize) || (!in_space)) {
pcercuei 0:03b5121a232e 4161 COPY_BUF(l,buf,len,0x20);
pcercuei 0:03b5121a232e 4162 while (len + 10 > buf_size) {
pcercuei 0:03b5121a232e 4163 growBuffer(buf, 10);
pcercuei 0:03b5121a232e 4164 }
pcercuei 0:03b5121a232e 4165 }
pcercuei 0:03b5121a232e 4166 in_space = 1;
pcercuei 0:03b5121a232e 4167 }
pcercuei 0:03b5121a232e 4168 } else {
pcercuei 0:03b5121a232e 4169 in_space = 0;
pcercuei 0:03b5121a232e 4170 COPY_BUF(l,buf,len,c);
pcercuei 0:03b5121a232e 4171 if (len + 10 > buf_size) {
pcercuei 0:03b5121a232e 4172 growBuffer(buf, 10);
pcercuei 0:03b5121a232e 4173 }
pcercuei 0:03b5121a232e 4174 }
pcercuei 0:03b5121a232e 4175 NEXTL(l);
pcercuei 0:03b5121a232e 4176 }
pcercuei 0:03b5121a232e 4177 GROW;
pcercuei 0:03b5121a232e 4178 c = CUR_CHAR(l);
pcercuei 0:03b5121a232e 4179 }
pcercuei 0:03b5121a232e 4180 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 4181 goto error;
pcercuei 0:03b5121a232e 4182
pcercuei 0:03b5121a232e 4183 if ((in_space) && (normalize)) {
pcercuei 0:03b5121a232e 4184 while ((len > 0) && (buf[len - 1] == 0x20)) len--;
pcercuei 0:03b5121a232e 4185 }
pcercuei 0:03b5121a232e 4186 buf[len] = 0;
pcercuei 0:03b5121a232e 4187 if (RAW == '<') {
pcercuei 0:03b5121a232e 4188 xmlFatalErr(ctxt, XML_ERR_LT_IN_ATTRIBUTE, NULL);
pcercuei 0:03b5121a232e 4189 } else if (RAW != limit) {
pcercuei 0:03b5121a232e 4190 if ((c != 0) && (!IS_CHAR(c))) {
pcercuei 0:03b5121a232e 4191 xmlFatalErrMsg(ctxt, XML_ERR_INVALID_CHAR,
pcercuei 0:03b5121a232e 4192 "invalid character in attribute value\n");
pcercuei 0:03b5121a232e 4193 } else {
pcercuei 0:03b5121a232e 4194 xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
pcercuei 0:03b5121a232e 4195 "AttValue: ' expected\n");
pcercuei 0:03b5121a232e 4196 }
pcercuei 0:03b5121a232e 4197 } else
pcercuei 0:03b5121a232e 4198 NEXT;
pcercuei 0:03b5121a232e 4199
pcercuei 0:03b5121a232e 4200 /*
pcercuei 0:03b5121a232e 4201 * There we potentially risk an overflow, don't allow attribute value of
pcercuei 0:03b5121a232e 4202 * length more than INT_MAX it is a very reasonnable assumption !
pcercuei 0:03b5121a232e 4203 */
pcercuei 0:03b5121a232e 4204 if (len >= INT_MAX) {
pcercuei 0:03b5121a232e 4205 xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
pcercuei 0:03b5121a232e 4206 "AttValue length too long\n");
pcercuei 0:03b5121a232e 4207 goto mem_error;
pcercuei 0:03b5121a232e 4208 }
pcercuei 0:03b5121a232e 4209
pcercuei 0:03b5121a232e 4210 if (attlen != NULL) *attlen = (int) len;
pcercuei 0:03b5121a232e 4211 return(buf);
pcercuei 0:03b5121a232e 4212
pcercuei 0:03b5121a232e 4213 mem_error:
pcercuei 0:03b5121a232e 4214 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 4215 error:
pcercuei 0:03b5121a232e 4216 if (buf != NULL)
pcercuei 0:03b5121a232e 4217 xmlFree(buf);
pcercuei 0:03b5121a232e 4218 if (rep != NULL)
pcercuei 0:03b5121a232e 4219 xmlFree(rep);
pcercuei 0:03b5121a232e 4220 return(NULL);
pcercuei 0:03b5121a232e 4221 }
pcercuei 0:03b5121a232e 4222
pcercuei 0:03b5121a232e 4223 /**
pcercuei 0:03b5121a232e 4224 * xmlParseAttValue:
pcercuei 0:03b5121a232e 4225 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 4226 *
pcercuei 0:03b5121a232e 4227 * parse a value for an attribute
pcercuei 0:03b5121a232e 4228 * Note: the parser won't do substitution of entities here, this
pcercuei 0:03b5121a232e 4229 * will be handled later in xmlStringGetNodeList
pcercuei 0:03b5121a232e 4230 *
pcercuei 0:03b5121a232e 4231 * [10] AttValue ::= '"' ([^<&"] | Reference)* '"' |
pcercuei 0:03b5121a232e 4232 * "'" ([^<&'] | Reference)* "'"
pcercuei 0:03b5121a232e 4233 *
pcercuei 0:03b5121a232e 4234 * 3.3.3 Attribute-Value Normalization:
pcercuei 0:03b5121a232e 4235 * Before the value of an attribute is passed to the application or
pcercuei 0:03b5121a232e 4236 * checked for validity, the XML processor must normalize it as follows:
pcercuei 0:03b5121a232e 4237 * - a character reference is processed by appending the referenced
pcercuei 0:03b5121a232e 4238 * character to the attribute value
pcercuei 0:03b5121a232e 4239 * - an entity reference is processed by recursively processing the
pcercuei 0:03b5121a232e 4240 * replacement text of the entity
pcercuei 0:03b5121a232e 4241 * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
pcercuei 0:03b5121a232e 4242 * appending #x20 to the normalized value, except that only a single
pcercuei 0:03b5121a232e 4243 * #x20 is appended for a "#xD#xA" sequence that is part of an external
pcercuei 0:03b5121a232e 4244 * parsed entity or the literal entity value of an internal parsed entity
pcercuei 0:03b5121a232e 4245 * - other characters are processed by appending them to the normalized value
pcercuei 0:03b5121a232e 4246 * If the declared value is not CDATA, then the XML processor must further
pcercuei 0:03b5121a232e 4247 * process the normalized attribute value by discarding any leading and
pcercuei 0:03b5121a232e 4248 * trailing space (#x20) characters, and by replacing sequences of space
pcercuei 0:03b5121a232e 4249 * (#x20) characters by a single space (#x20) character.
pcercuei 0:03b5121a232e 4250 * All attributes for which no declaration has been read should be treated
pcercuei 0:03b5121a232e 4251 * by a non-validating parser as if declared CDATA.
pcercuei 0:03b5121a232e 4252 *
pcercuei 0:03b5121a232e 4253 * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
pcercuei 0:03b5121a232e 4254 */
pcercuei 0:03b5121a232e 4255
pcercuei 0:03b5121a232e 4256
pcercuei 0:03b5121a232e 4257 xmlChar *
pcercuei 0:03b5121a232e 4258 xmlParseAttValue(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 4259 if ((ctxt == NULL) || (ctxt->input == NULL)) return(NULL);
pcercuei 0:03b5121a232e 4260 return(xmlParseAttValueInternal(ctxt, NULL, NULL, 0));
pcercuei 0:03b5121a232e 4261 }
pcercuei 0:03b5121a232e 4262
pcercuei 0:03b5121a232e 4263 /**
pcercuei 0:03b5121a232e 4264 * xmlParseSystemLiteral:
pcercuei 0:03b5121a232e 4265 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 4266 *
pcercuei 0:03b5121a232e 4267 * parse an XML Literal
pcercuei 0:03b5121a232e 4268 *
pcercuei 0:03b5121a232e 4269 * [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
pcercuei 0:03b5121a232e 4270 *
pcercuei 0:03b5121a232e 4271 * Returns the SystemLiteral parsed or NULL
pcercuei 0:03b5121a232e 4272 */
pcercuei 0:03b5121a232e 4273
pcercuei 0:03b5121a232e 4274 xmlChar *
pcercuei 0:03b5121a232e 4275 xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 4276 xmlChar *buf = NULL;
pcercuei 0:03b5121a232e 4277 int len = 0;
pcercuei 0:03b5121a232e 4278 int size = XML_PARSER_BUFFER_SIZE;
pcercuei 0:03b5121a232e 4279 int cur, l;
pcercuei 0:03b5121a232e 4280 xmlChar stop;
pcercuei 0:03b5121a232e 4281 int state = ctxt->instate;
pcercuei 0:03b5121a232e 4282 int count = 0;
pcercuei 0:03b5121a232e 4283
pcercuei 0:03b5121a232e 4284 SHRINK;
pcercuei 0:03b5121a232e 4285 if (RAW == '"') {
pcercuei 0:03b5121a232e 4286 NEXT;
pcercuei 0:03b5121a232e 4287 stop = '"';
pcercuei 0:03b5121a232e 4288 } else if (RAW == '\'') {
pcercuei 0:03b5121a232e 4289 NEXT;
pcercuei 0:03b5121a232e 4290 stop = '\'';
pcercuei 0:03b5121a232e 4291 } else {
pcercuei 0:03b5121a232e 4292 xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, NULL);
pcercuei 0:03b5121a232e 4293 return(NULL);
pcercuei 0:03b5121a232e 4294 }
pcercuei 0:03b5121a232e 4295
pcercuei 0:03b5121a232e 4296 buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
pcercuei 0:03b5121a232e 4297 if (buf == NULL) {
pcercuei 0:03b5121a232e 4298 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 4299 return(NULL);
pcercuei 0:03b5121a232e 4300 }
pcercuei 0:03b5121a232e 4301 ctxt->instate = XML_PARSER_SYSTEM_LITERAL;
pcercuei 0:03b5121a232e 4302 cur = CUR_CHAR(l);
pcercuei 0:03b5121a232e 4303 while ((IS_CHAR(cur)) && (cur != stop)) { /* checked */
pcercuei 0:03b5121a232e 4304 if (len + 5 >= size) {
pcercuei 0:03b5121a232e 4305 xmlChar *tmp;
pcercuei 0:03b5121a232e 4306
pcercuei 0:03b5121a232e 4307 if ((size > XML_MAX_NAME_LENGTH) &&
pcercuei 0:03b5121a232e 4308 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
pcercuei 0:03b5121a232e 4309 xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "SystemLiteral");
pcercuei 0:03b5121a232e 4310 xmlFree(buf);
pcercuei 0:03b5121a232e 4311 ctxt->instate = (xmlParserInputState) state;
pcercuei 0:03b5121a232e 4312 return(NULL);
pcercuei 0:03b5121a232e 4313 }
pcercuei 0:03b5121a232e 4314 size *= 2;
pcercuei 0:03b5121a232e 4315 tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
pcercuei 0:03b5121a232e 4316 if (tmp == NULL) {
pcercuei 0:03b5121a232e 4317 xmlFree(buf);
pcercuei 0:03b5121a232e 4318 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 4319 ctxt->instate = (xmlParserInputState) state;
pcercuei 0:03b5121a232e 4320 return(NULL);
pcercuei 0:03b5121a232e 4321 }
pcercuei 0:03b5121a232e 4322 buf = tmp;
pcercuei 0:03b5121a232e 4323 }
pcercuei 0:03b5121a232e 4324 count++;
pcercuei 0:03b5121a232e 4325 if (count > 50) {
pcercuei 0:03b5121a232e 4326 GROW;
pcercuei 0:03b5121a232e 4327 count = 0;
pcercuei 0:03b5121a232e 4328 if (ctxt->instate == XML_PARSER_EOF) {
pcercuei 0:03b5121a232e 4329 xmlFree(buf);
pcercuei 0:03b5121a232e 4330 return(NULL);
pcercuei 0:03b5121a232e 4331 }
pcercuei 0:03b5121a232e 4332 }
pcercuei 0:03b5121a232e 4333 COPY_BUF(l,buf,len,cur);
pcercuei 0:03b5121a232e 4334 NEXTL(l);
pcercuei 0:03b5121a232e 4335 cur = CUR_CHAR(l);
pcercuei 0:03b5121a232e 4336 if (cur == 0) {
pcercuei 0:03b5121a232e 4337 GROW;
pcercuei 0:03b5121a232e 4338 SHRINK;
pcercuei 0:03b5121a232e 4339 cur = CUR_CHAR(l);
pcercuei 0:03b5121a232e 4340 }
pcercuei 0:03b5121a232e 4341 }
pcercuei 0:03b5121a232e 4342 buf[len] = 0;
pcercuei 0:03b5121a232e 4343 ctxt->instate = (xmlParserInputState) state;
pcercuei 0:03b5121a232e 4344 if (!IS_CHAR(cur)) {
pcercuei 0:03b5121a232e 4345 xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
pcercuei 0:03b5121a232e 4346 } else {
pcercuei 0:03b5121a232e 4347 NEXT;
pcercuei 0:03b5121a232e 4348 }
pcercuei 0:03b5121a232e 4349 return(buf);
pcercuei 0:03b5121a232e 4350 }
pcercuei 0:03b5121a232e 4351
pcercuei 0:03b5121a232e 4352 /**
pcercuei 0:03b5121a232e 4353 * xmlParsePubidLiteral:
pcercuei 0:03b5121a232e 4354 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 4355 *
pcercuei 0:03b5121a232e 4356 * parse an XML public literal
pcercuei 0:03b5121a232e 4357 *
pcercuei 0:03b5121a232e 4358 * [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
pcercuei 0:03b5121a232e 4359 *
pcercuei 0:03b5121a232e 4360 * Returns the PubidLiteral parsed or NULL.
pcercuei 0:03b5121a232e 4361 */
pcercuei 0:03b5121a232e 4362
pcercuei 0:03b5121a232e 4363 xmlChar *
pcercuei 0:03b5121a232e 4364 xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 4365 xmlChar *buf = NULL;
pcercuei 0:03b5121a232e 4366 int len = 0;
pcercuei 0:03b5121a232e 4367 int size = XML_PARSER_BUFFER_SIZE;
pcercuei 0:03b5121a232e 4368 xmlChar cur;
pcercuei 0:03b5121a232e 4369 xmlChar stop;
pcercuei 0:03b5121a232e 4370 int count = 0;
pcercuei 0:03b5121a232e 4371 xmlParserInputState oldstate = ctxt->instate;
pcercuei 0:03b5121a232e 4372
pcercuei 0:03b5121a232e 4373 SHRINK;
pcercuei 0:03b5121a232e 4374 if (RAW == '"') {
pcercuei 0:03b5121a232e 4375 NEXT;
pcercuei 0:03b5121a232e 4376 stop = '"';
pcercuei 0:03b5121a232e 4377 } else if (RAW == '\'') {
pcercuei 0:03b5121a232e 4378 NEXT;
pcercuei 0:03b5121a232e 4379 stop = '\'';
pcercuei 0:03b5121a232e 4380 } else {
pcercuei 0:03b5121a232e 4381 xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, NULL);
pcercuei 0:03b5121a232e 4382 return(NULL);
pcercuei 0:03b5121a232e 4383 }
pcercuei 0:03b5121a232e 4384 buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
pcercuei 0:03b5121a232e 4385 if (buf == NULL) {
pcercuei 0:03b5121a232e 4386 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 4387 return(NULL);
pcercuei 0:03b5121a232e 4388 }
pcercuei 0:03b5121a232e 4389 ctxt->instate = XML_PARSER_PUBLIC_LITERAL;
pcercuei 0:03b5121a232e 4390 cur = CUR;
pcercuei 0:03b5121a232e 4391 while ((IS_PUBIDCHAR_CH(cur)) && (cur != stop)) { /* checked */
pcercuei 0:03b5121a232e 4392 if (len + 1 >= size) {
pcercuei 0:03b5121a232e 4393 xmlChar *tmp;
pcercuei 0:03b5121a232e 4394
pcercuei 0:03b5121a232e 4395 if ((size > XML_MAX_NAME_LENGTH) &&
pcercuei 0:03b5121a232e 4396 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
pcercuei 0:03b5121a232e 4397 xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Public ID");
pcercuei 0:03b5121a232e 4398 xmlFree(buf);
pcercuei 0:03b5121a232e 4399 return(NULL);
pcercuei 0:03b5121a232e 4400 }
pcercuei 0:03b5121a232e 4401 size *= 2;
pcercuei 0:03b5121a232e 4402 tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
pcercuei 0:03b5121a232e 4403 if (tmp == NULL) {
pcercuei 0:03b5121a232e 4404 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 4405 xmlFree(buf);
pcercuei 0:03b5121a232e 4406 return(NULL);
pcercuei 0:03b5121a232e 4407 }
pcercuei 0:03b5121a232e 4408 buf = tmp;
pcercuei 0:03b5121a232e 4409 }
pcercuei 0:03b5121a232e 4410 buf[len++] = cur;
pcercuei 0:03b5121a232e 4411 count++;
pcercuei 0:03b5121a232e 4412 if (count > 50) {
pcercuei 0:03b5121a232e 4413 GROW;
pcercuei 0:03b5121a232e 4414 count = 0;
pcercuei 0:03b5121a232e 4415 if (ctxt->instate == XML_PARSER_EOF) {
pcercuei 0:03b5121a232e 4416 xmlFree(buf);
pcercuei 0:03b5121a232e 4417 return(NULL);
pcercuei 0:03b5121a232e 4418 }
pcercuei 0:03b5121a232e 4419 }
pcercuei 0:03b5121a232e 4420 NEXT;
pcercuei 0:03b5121a232e 4421 cur = CUR;
pcercuei 0:03b5121a232e 4422 if (cur == 0) {
pcercuei 0:03b5121a232e 4423 GROW;
pcercuei 0:03b5121a232e 4424 SHRINK;
pcercuei 0:03b5121a232e 4425 cur = CUR;
pcercuei 0:03b5121a232e 4426 }
pcercuei 0:03b5121a232e 4427 }
pcercuei 0:03b5121a232e 4428 buf[len] = 0;
pcercuei 0:03b5121a232e 4429 if (cur != stop) {
pcercuei 0:03b5121a232e 4430 xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
pcercuei 0:03b5121a232e 4431 } else {
pcercuei 0:03b5121a232e 4432 NEXT;
pcercuei 0:03b5121a232e 4433 }
pcercuei 0:03b5121a232e 4434 ctxt->instate = oldstate;
pcercuei 0:03b5121a232e 4435 return(buf);
pcercuei 0:03b5121a232e 4436 }
pcercuei 0:03b5121a232e 4437
pcercuei 0:03b5121a232e 4438 static void xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata);
pcercuei 0:03b5121a232e 4439
pcercuei 0:03b5121a232e 4440 /*
pcercuei 0:03b5121a232e 4441 * used for the test in the inner loop of the char data testing
pcercuei 0:03b5121a232e 4442 */
pcercuei 0:03b5121a232e 4443 static const unsigned char test_char_data[256] = {
pcercuei 0:03b5121a232e 4444 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
pcercuei 0:03b5121a232e 4445 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9, CR/LF separated */
pcercuei 0:03b5121a232e 4446 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
pcercuei 0:03b5121a232e 4447 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
pcercuei 0:03b5121a232e 4448 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x00, 0x27, /* & */
pcercuei 0:03b5121a232e 4449 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
pcercuei 0:03b5121a232e 4450 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
pcercuei 0:03b5121a232e 4451 0x38, 0x39, 0x3A, 0x3B, 0x00, 0x3D, 0x3E, 0x3F, /* < */
pcercuei 0:03b5121a232e 4452 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
pcercuei 0:03b5121a232e 4453 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
pcercuei 0:03b5121a232e 4454 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
pcercuei 0:03b5121a232e 4455 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x00, 0x5E, 0x5F, /* ] */
pcercuei 0:03b5121a232e 4456 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
pcercuei 0:03b5121a232e 4457 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
pcercuei 0:03b5121a232e 4458 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
pcercuei 0:03b5121a232e 4459 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
pcercuei 0:03b5121a232e 4460 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* non-ascii */
pcercuei 0:03b5121a232e 4461 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
pcercuei 0:03b5121a232e 4462 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
pcercuei 0:03b5121a232e 4463 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
pcercuei 0:03b5121a232e 4464 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
pcercuei 0:03b5121a232e 4465 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
pcercuei 0:03b5121a232e 4466 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
pcercuei 0:03b5121a232e 4467 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
pcercuei 0:03b5121a232e 4468 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
pcercuei 0:03b5121a232e 4469 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
pcercuei 0:03b5121a232e 4470 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
pcercuei 0:03b5121a232e 4471 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
pcercuei 0:03b5121a232e 4472 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
pcercuei 0:03b5121a232e 4473 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
pcercuei 0:03b5121a232e 4474 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
pcercuei 0:03b5121a232e 4475 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
pcercuei 0:03b5121a232e 4476 };
pcercuei 0:03b5121a232e 4477
pcercuei 0:03b5121a232e 4478 /**
pcercuei 0:03b5121a232e 4479 * xmlParseCharData:
pcercuei 0:03b5121a232e 4480 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 4481 * @cdata: int indicating whether we are within a CDATA section
pcercuei 0:03b5121a232e 4482 *
pcercuei 0:03b5121a232e 4483 * parse a CharData section.
pcercuei 0:03b5121a232e 4484 * if we are within a CDATA section ']]>' marks an end of section.
pcercuei 0:03b5121a232e 4485 *
pcercuei 0:03b5121a232e 4486 * The right angle bracket (>) may be represented using the string "&gt;",
pcercuei 0:03b5121a232e 4487 * and must, for compatibility, be escaped using "&gt;" or a character
pcercuei 0:03b5121a232e 4488 * reference when it appears in the string "]]>" in content, when that
pcercuei 0:03b5121a232e 4489 * string is not marking the end of a CDATA section.
pcercuei 0:03b5121a232e 4490 *
pcercuei 0:03b5121a232e 4491 * [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
pcercuei 0:03b5121a232e 4492 */
pcercuei 0:03b5121a232e 4493
pcercuei 0:03b5121a232e 4494 void
pcercuei 0:03b5121a232e 4495 xmlParseCharData(xmlParserCtxtPtr ctxt, int cdata) {
pcercuei 0:03b5121a232e 4496 const xmlChar *in;
pcercuei 0:03b5121a232e 4497 int nbchar = 0;
pcercuei 0:03b5121a232e 4498 int line = ctxt->input->line;
pcercuei 0:03b5121a232e 4499 int col = ctxt->input->col;
pcercuei 0:03b5121a232e 4500 int ccol;
pcercuei 0:03b5121a232e 4501
pcercuei 0:03b5121a232e 4502 SHRINK;
pcercuei 0:03b5121a232e 4503 GROW;
pcercuei 0:03b5121a232e 4504 /*
pcercuei 0:03b5121a232e 4505 * Accelerated common case where input don't need to be
pcercuei 0:03b5121a232e 4506 * modified before passing it to the handler.
pcercuei 0:03b5121a232e 4507 */
pcercuei 0:03b5121a232e 4508 if (!cdata) {
pcercuei 0:03b5121a232e 4509 in = ctxt->input->cur;
pcercuei 0:03b5121a232e 4510 do {
pcercuei 0:03b5121a232e 4511 get_more_space:
pcercuei 0:03b5121a232e 4512 while (*in == 0x20) { in++; ctxt->input->col++; }
pcercuei 0:03b5121a232e 4513 if (*in == 0xA) {
pcercuei 0:03b5121a232e 4514 do {
pcercuei 0:03b5121a232e 4515 ctxt->input->line++; ctxt->input->col = 1;
pcercuei 0:03b5121a232e 4516 in++;
pcercuei 0:03b5121a232e 4517 } while (*in == 0xA);
pcercuei 0:03b5121a232e 4518 goto get_more_space;
pcercuei 0:03b5121a232e 4519 }
pcercuei 0:03b5121a232e 4520 if (*in == '<') {
pcercuei 0:03b5121a232e 4521 nbchar = in - ctxt->input->cur;
pcercuei 0:03b5121a232e 4522 if (nbchar > 0) {
pcercuei 0:03b5121a232e 4523 const xmlChar *tmp = ctxt->input->cur;
pcercuei 0:03b5121a232e 4524 ctxt->input->cur = in;
pcercuei 0:03b5121a232e 4525
pcercuei 0:03b5121a232e 4526 if ((ctxt->sax != NULL) &&
pcercuei 0:03b5121a232e 4527 (ctxt->sax->ignorableWhitespace !=
pcercuei 0:03b5121a232e 4528 ctxt->sax->characters)) {
pcercuei 0:03b5121a232e 4529 if (areBlanks(ctxt, tmp, nbchar, 1)) {
pcercuei 0:03b5121a232e 4530 if (ctxt->sax->ignorableWhitespace != NULL)
pcercuei 0:03b5121a232e 4531 ctxt->sax->ignorableWhitespace(ctxt->userData,
pcercuei 0:03b5121a232e 4532 tmp, nbchar);
pcercuei 0:03b5121a232e 4533 } else {
pcercuei 0:03b5121a232e 4534 if (ctxt->sax->characters != NULL)
pcercuei 0:03b5121a232e 4535 ctxt->sax->characters(ctxt->userData,
pcercuei 0:03b5121a232e 4536 tmp, nbchar);
pcercuei 0:03b5121a232e 4537 if (*ctxt->space == -1)
pcercuei 0:03b5121a232e 4538 *ctxt->space = -2;
pcercuei 0:03b5121a232e 4539 }
pcercuei 0:03b5121a232e 4540 } else if ((ctxt->sax != NULL) &&
pcercuei 0:03b5121a232e 4541 (ctxt->sax->characters != NULL)) {
pcercuei 0:03b5121a232e 4542 ctxt->sax->characters(ctxt->userData,
pcercuei 0:03b5121a232e 4543 tmp, nbchar);
pcercuei 0:03b5121a232e 4544 }
pcercuei 0:03b5121a232e 4545 }
pcercuei 0:03b5121a232e 4546 return;
pcercuei 0:03b5121a232e 4547 }
pcercuei 0:03b5121a232e 4548
pcercuei 0:03b5121a232e 4549 get_more:
pcercuei 0:03b5121a232e 4550 ccol = ctxt->input->col;
pcercuei 0:03b5121a232e 4551 while (test_char_data[*in]) {
pcercuei 0:03b5121a232e 4552 in++;
pcercuei 0:03b5121a232e 4553 ccol++;
pcercuei 0:03b5121a232e 4554 }
pcercuei 0:03b5121a232e 4555 ctxt->input->col = ccol;
pcercuei 0:03b5121a232e 4556 if (*in == 0xA) {
pcercuei 0:03b5121a232e 4557 do {
pcercuei 0:03b5121a232e 4558 ctxt->input->line++; ctxt->input->col = 1;
pcercuei 0:03b5121a232e 4559 in++;
pcercuei 0:03b5121a232e 4560 } while (*in == 0xA);
pcercuei 0:03b5121a232e 4561 goto get_more;
pcercuei 0:03b5121a232e 4562 }
pcercuei 0:03b5121a232e 4563 if (*in == ']') {
pcercuei 0:03b5121a232e 4564 if ((in[1] == ']') && (in[2] == '>')) {
pcercuei 0:03b5121a232e 4565 xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
pcercuei 0:03b5121a232e 4566 ctxt->input->cur = in;
pcercuei 0:03b5121a232e 4567 return;
pcercuei 0:03b5121a232e 4568 }
pcercuei 0:03b5121a232e 4569 in++;
pcercuei 0:03b5121a232e 4570 ctxt->input->col++;
pcercuei 0:03b5121a232e 4571 goto get_more;
pcercuei 0:03b5121a232e 4572 }
pcercuei 0:03b5121a232e 4573 nbchar = in - ctxt->input->cur;
pcercuei 0:03b5121a232e 4574 if (nbchar > 0) {
pcercuei 0:03b5121a232e 4575 if ((ctxt->sax != NULL) &&
pcercuei 0:03b5121a232e 4576 (ctxt->sax->ignorableWhitespace !=
pcercuei 0:03b5121a232e 4577 ctxt->sax->characters) &&
pcercuei 0:03b5121a232e 4578 (IS_BLANK_CH(*ctxt->input->cur))) {
pcercuei 0:03b5121a232e 4579 const xmlChar *tmp = ctxt->input->cur;
pcercuei 0:03b5121a232e 4580 ctxt->input->cur = in;
pcercuei 0:03b5121a232e 4581
pcercuei 0:03b5121a232e 4582 if (areBlanks(ctxt, tmp, nbchar, 0)) {
pcercuei 0:03b5121a232e 4583 if (ctxt->sax->ignorableWhitespace != NULL)
pcercuei 0:03b5121a232e 4584 ctxt->sax->ignorableWhitespace(ctxt->userData,
pcercuei 0:03b5121a232e 4585 tmp, nbchar);
pcercuei 0:03b5121a232e 4586 } else {
pcercuei 0:03b5121a232e 4587 if (ctxt->sax->characters != NULL)
pcercuei 0:03b5121a232e 4588 ctxt->sax->characters(ctxt->userData,
pcercuei 0:03b5121a232e 4589 tmp, nbchar);
pcercuei 0:03b5121a232e 4590 if (*ctxt->space == -1)
pcercuei 0:03b5121a232e 4591 *ctxt->space = -2;
pcercuei 0:03b5121a232e 4592 }
pcercuei 0:03b5121a232e 4593 line = ctxt->input->line;
pcercuei 0:03b5121a232e 4594 col = ctxt->input->col;
pcercuei 0:03b5121a232e 4595 } else if (ctxt->sax != NULL) {
pcercuei 0:03b5121a232e 4596 if (ctxt->sax->characters != NULL)
pcercuei 0:03b5121a232e 4597 ctxt->sax->characters(ctxt->userData,
pcercuei 0:03b5121a232e 4598 ctxt->input->cur, nbchar);
pcercuei 0:03b5121a232e 4599 line = ctxt->input->line;
pcercuei 0:03b5121a232e 4600 col = ctxt->input->col;
pcercuei 0:03b5121a232e 4601 }
pcercuei 0:03b5121a232e 4602 /* something really bad happened in the SAX callback */
pcercuei 0:03b5121a232e 4603 if (ctxt->instate != XML_PARSER_CONTENT)
pcercuei 0:03b5121a232e 4604 return;
pcercuei 0:03b5121a232e 4605 }
pcercuei 0:03b5121a232e 4606 ctxt->input->cur = in;
pcercuei 0:03b5121a232e 4607 if (*in == 0xD) {
pcercuei 0:03b5121a232e 4608 in++;
pcercuei 0:03b5121a232e 4609 if (*in == 0xA) {
pcercuei 0:03b5121a232e 4610 ctxt->input->cur = in;
pcercuei 0:03b5121a232e 4611 in++;
pcercuei 0:03b5121a232e 4612 ctxt->input->line++; ctxt->input->col = 1;
pcercuei 0:03b5121a232e 4613 continue; /* while */
pcercuei 0:03b5121a232e 4614 }
pcercuei 0:03b5121a232e 4615 in--;
pcercuei 0:03b5121a232e 4616 }
pcercuei 0:03b5121a232e 4617 if (*in == '<') {
pcercuei 0:03b5121a232e 4618 return;
pcercuei 0:03b5121a232e 4619 }
pcercuei 0:03b5121a232e 4620 if (*in == '&') {
pcercuei 0:03b5121a232e 4621 return;
pcercuei 0:03b5121a232e 4622 }
pcercuei 0:03b5121a232e 4623 SHRINK;
pcercuei 0:03b5121a232e 4624 GROW;
pcercuei 0:03b5121a232e 4625 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 4626 return;
pcercuei 0:03b5121a232e 4627 in = ctxt->input->cur;
pcercuei 0:03b5121a232e 4628 } while (((*in >= 0x20) && (*in <= 0x7F)) || (*in == 0x09));
pcercuei 0:03b5121a232e 4629 nbchar = 0;
pcercuei 0:03b5121a232e 4630 }
pcercuei 0:03b5121a232e 4631 ctxt->input->line = line;
pcercuei 0:03b5121a232e 4632 ctxt->input->col = col;
pcercuei 0:03b5121a232e 4633 xmlParseCharDataComplex(ctxt, cdata);
pcercuei 0:03b5121a232e 4634 }
pcercuei 0:03b5121a232e 4635
pcercuei 0:03b5121a232e 4636 /**
pcercuei 0:03b5121a232e 4637 * xmlParseCharDataComplex:
pcercuei 0:03b5121a232e 4638 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 4639 * @cdata: int indicating whether we are within a CDATA section
pcercuei 0:03b5121a232e 4640 *
pcercuei 0:03b5121a232e 4641 * parse a CharData section.this is the fallback function
pcercuei 0:03b5121a232e 4642 * of xmlParseCharData() when the parsing requires handling
pcercuei 0:03b5121a232e 4643 * of non-ASCII characters.
pcercuei 0:03b5121a232e 4644 */
pcercuei 0:03b5121a232e 4645 static void
pcercuei 0:03b5121a232e 4646 xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata) {
pcercuei 0:03b5121a232e 4647 xmlChar buf[XML_PARSER_BIG_BUFFER_SIZE + 5];
pcercuei 0:03b5121a232e 4648 int nbchar = 0;
pcercuei 0:03b5121a232e 4649 int cur, l;
pcercuei 0:03b5121a232e 4650 int count = 0;
pcercuei 0:03b5121a232e 4651
pcercuei 0:03b5121a232e 4652 SHRINK;
pcercuei 0:03b5121a232e 4653 GROW;
pcercuei 0:03b5121a232e 4654 cur = CUR_CHAR(l);
pcercuei 0:03b5121a232e 4655 while ((cur != '<') && /* checked */
pcercuei 0:03b5121a232e 4656 (cur != '&') &&
pcercuei 0:03b5121a232e 4657 (IS_CHAR(cur))) /* test also done in xmlCurrentChar() */ {
pcercuei 0:03b5121a232e 4658 if ((cur == ']') && (NXT(1) == ']') &&
pcercuei 0:03b5121a232e 4659 (NXT(2) == '>')) {
pcercuei 0:03b5121a232e 4660 if (cdata) break;
pcercuei 0:03b5121a232e 4661 else {
pcercuei 0:03b5121a232e 4662 xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
pcercuei 0:03b5121a232e 4663 }
pcercuei 0:03b5121a232e 4664 }
pcercuei 0:03b5121a232e 4665 COPY_BUF(l,buf,nbchar,cur);
pcercuei 0:03b5121a232e 4666 if (nbchar >= XML_PARSER_BIG_BUFFER_SIZE) {
pcercuei 0:03b5121a232e 4667 buf[nbchar] = 0;
pcercuei 0:03b5121a232e 4668
pcercuei 0:03b5121a232e 4669 /*
pcercuei 0:03b5121a232e 4670 * OK the segment is to be consumed as chars.
pcercuei 0:03b5121a232e 4671 */
pcercuei 0:03b5121a232e 4672 if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
pcercuei 0:03b5121a232e 4673 if (areBlanks(ctxt, buf, nbchar, 0)) {
pcercuei 0:03b5121a232e 4674 if (ctxt->sax->ignorableWhitespace != NULL)
pcercuei 0:03b5121a232e 4675 ctxt->sax->ignorableWhitespace(ctxt->userData,
pcercuei 0:03b5121a232e 4676 buf, nbchar);
pcercuei 0:03b5121a232e 4677 } else {
pcercuei 0:03b5121a232e 4678 if (ctxt->sax->characters != NULL)
pcercuei 0:03b5121a232e 4679 ctxt->sax->characters(ctxt->userData, buf, nbchar);
pcercuei 0:03b5121a232e 4680 if ((ctxt->sax->characters !=
pcercuei 0:03b5121a232e 4681 ctxt->sax->ignorableWhitespace) &&
pcercuei 0:03b5121a232e 4682 (*ctxt->space == -1))
pcercuei 0:03b5121a232e 4683 *ctxt->space = -2;
pcercuei 0:03b5121a232e 4684 }
pcercuei 0:03b5121a232e 4685 }
pcercuei 0:03b5121a232e 4686 nbchar = 0;
pcercuei 0:03b5121a232e 4687 /* something really bad happened in the SAX callback */
pcercuei 0:03b5121a232e 4688 if (ctxt->instate != XML_PARSER_CONTENT)
pcercuei 0:03b5121a232e 4689 return;
pcercuei 0:03b5121a232e 4690 }
pcercuei 0:03b5121a232e 4691 count++;
pcercuei 0:03b5121a232e 4692 if (count > 50) {
pcercuei 0:03b5121a232e 4693 GROW;
pcercuei 0:03b5121a232e 4694 count = 0;
pcercuei 0:03b5121a232e 4695 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 4696 return;
pcercuei 0:03b5121a232e 4697 }
pcercuei 0:03b5121a232e 4698 NEXTL(l);
pcercuei 0:03b5121a232e 4699 cur = CUR_CHAR(l);
pcercuei 0:03b5121a232e 4700 }
pcercuei 0:03b5121a232e 4701 if (nbchar != 0) {
pcercuei 0:03b5121a232e 4702 buf[nbchar] = 0;
pcercuei 0:03b5121a232e 4703 /*
pcercuei 0:03b5121a232e 4704 * OK the segment is to be consumed as chars.
pcercuei 0:03b5121a232e 4705 */
pcercuei 0:03b5121a232e 4706 if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
pcercuei 0:03b5121a232e 4707 if (areBlanks(ctxt, buf, nbchar, 0)) {
pcercuei 0:03b5121a232e 4708 if (ctxt->sax->ignorableWhitespace != NULL)
pcercuei 0:03b5121a232e 4709 ctxt->sax->ignorableWhitespace(ctxt->userData, buf, nbchar);
pcercuei 0:03b5121a232e 4710 } else {
pcercuei 0:03b5121a232e 4711 if (ctxt->sax->characters != NULL)
pcercuei 0:03b5121a232e 4712 ctxt->sax->characters(ctxt->userData, buf, nbchar);
pcercuei 0:03b5121a232e 4713 if ((ctxt->sax->characters != ctxt->sax->ignorableWhitespace) &&
pcercuei 0:03b5121a232e 4714 (*ctxt->space == -1))
pcercuei 0:03b5121a232e 4715 *ctxt->space = -2;
pcercuei 0:03b5121a232e 4716 }
pcercuei 0:03b5121a232e 4717 }
pcercuei 0:03b5121a232e 4718 }
pcercuei 0:03b5121a232e 4719 if ((cur != 0) && (!IS_CHAR(cur))) {
pcercuei 0:03b5121a232e 4720 /* Generate the error and skip the offending character */
pcercuei 0:03b5121a232e 4721 xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
pcercuei 0:03b5121a232e 4722 "PCDATA invalid Char value %d\n",
pcercuei 0:03b5121a232e 4723 cur);
pcercuei 0:03b5121a232e 4724 NEXTL(l);
pcercuei 0:03b5121a232e 4725 }
pcercuei 0:03b5121a232e 4726 }
pcercuei 0:03b5121a232e 4727
pcercuei 0:03b5121a232e 4728 /**
pcercuei 0:03b5121a232e 4729 * xmlParseExternalID:
pcercuei 0:03b5121a232e 4730 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 4731 * @publicID: a xmlChar** receiving PubidLiteral
pcercuei 0:03b5121a232e 4732 * @strict: indicate whether we should restrict parsing to only
pcercuei 0:03b5121a232e 4733 * production [75], see NOTE below
pcercuei 0:03b5121a232e 4734 *
pcercuei 0:03b5121a232e 4735 * Parse an External ID or a Public ID
pcercuei 0:03b5121a232e 4736 *
pcercuei 0:03b5121a232e 4737 * NOTE: Productions [75] and [83] interact badly since [75] can generate
pcercuei 0:03b5121a232e 4738 * 'PUBLIC' S PubidLiteral S SystemLiteral
pcercuei 0:03b5121a232e 4739 *
pcercuei 0:03b5121a232e 4740 * [75] ExternalID ::= 'SYSTEM' S SystemLiteral
pcercuei 0:03b5121a232e 4741 * | 'PUBLIC' S PubidLiteral S SystemLiteral
pcercuei 0:03b5121a232e 4742 *
pcercuei 0:03b5121a232e 4743 * [83] PublicID ::= 'PUBLIC' S PubidLiteral
pcercuei 0:03b5121a232e 4744 *
pcercuei 0:03b5121a232e 4745 * Returns the function returns SystemLiteral and in the second
pcercuei 0:03b5121a232e 4746 * case publicID receives PubidLiteral, is strict is off
pcercuei 0:03b5121a232e 4747 * it is possible to return NULL and have publicID set.
pcercuei 0:03b5121a232e 4748 */
pcercuei 0:03b5121a232e 4749
pcercuei 0:03b5121a232e 4750 xmlChar *
pcercuei 0:03b5121a232e 4751 xmlParseExternalID(xmlParserCtxtPtr ctxt, xmlChar **publicID, int strict) {
pcercuei 0:03b5121a232e 4752 xmlChar *URI = NULL;
pcercuei 0:03b5121a232e 4753
pcercuei 0:03b5121a232e 4754 SHRINK;
pcercuei 0:03b5121a232e 4755
pcercuei 0:03b5121a232e 4756 *publicID = NULL;
pcercuei 0:03b5121a232e 4757 if (CMP6(CUR_PTR, 'S', 'Y', 'S', 'T', 'E', 'M')) {
pcercuei 0:03b5121a232e 4758 SKIP(6);
pcercuei 0:03b5121a232e 4759 if (!IS_BLANK_CH(CUR)) {
pcercuei 0:03b5121a232e 4760 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
pcercuei 0:03b5121a232e 4761 "Space required after 'SYSTEM'\n");
pcercuei 0:03b5121a232e 4762 }
pcercuei 0:03b5121a232e 4763 SKIP_BLANKS;
pcercuei 0:03b5121a232e 4764 URI = xmlParseSystemLiteral(ctxt);
pcercuei 0:03b5121a232e 4765 if (URI == NULL) {
pcercuei 0:03b5121a232e 4766 xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL);
pcercuei 0:03b5121a232e 4767 }
pcercuei 0:03b5121a232e 4768 } else if (CMP6(CUR_PTR, 'P', 'U', 'B', 'L', 'I', 'C')) {
pcercuei 0:03b5121a232e 4769 SKIP(6);
pcercuei 0:03b5121a232e 4770 if (!IS_BLANK_CH(CUR)) {
pcercuei 0:03b5121a232e 4771 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
pcercuei 0:03b5121a232e 4772 "Space required after 'PUBLIC'\n");
pcercuei 0:03b5121a232e 4773 }
pcercuei 0:03b5121a232e 4774 SKIP_BLANKS;
pcercuei 0:03b5121a232e 4775 *publicID = xmlParsePubidLiteral(ctxt);
pcercuei 0:03b5121a232e 4776 if (*publicID == NULL) {
pcercuei 0:03b5121a232e 4777 xmlFatalErr(ctxt, XML_ERR_PUBID_REQUIRED, NULL);
pcercuei 0:03b5121a232e 4778 }
pcercuei 0:03b5121a232e 4779 if (strict) {
pcercuei 0:03b5121a232e 4780 /*
pcercuei 0:03b5121a232e 4781 * We don't handle [83] so "S SystemLiteral" is required.
pcercuei 0:03b5121a232e 4782 */
pcercuei 0:03b5121a232e 4783 if (!IS_BLANK_CH(CUR)) {
pcercuei 0:03b5121a232e 4784 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
pcercuei 0:03b5121a232e 4785 "Space required after the Public Identifier\n");
pcercuei 0:03b5121a232e 4786 }
pcercuei 0:03b5121a232e 4787 } else {
pcercuei 0:03b5121a232e 4788 /*
pcercuei 0:03b5121a232e 4789 * We handle [83] so we return immediately, if
pcercuei 0:03b5121a232e 4790 * "S SystemLiteral" is not detected. From a purely parsing
pcercuei 0:03b5121a232e 4791 * point of view that's a nice mess.
pcercuei 0:03b5121a232e 4792 */
pcercuei 0:03b5121a232e 4793 const xmlChar *ptr;
pcercuei 0:03b5121a232e 4794 GROW;
pcercuei 0:03b5121a232e 4795
pcercuei 0:03b5121a232e 4796 ptr = CUR_PTR;
pcercuei 0:03b5121a232e 4797 if (!IS_BLANK_CH(*ptr)) return(NULL);
pcercuei 0:03b5121a232e 4798
pcercuei 0:03b5121a232e 4799 while (IS_BLANK_CH(*ptr)) ptr++; /* TODO: dangerous, fix ! */
pcercuei 0:03b5121a232e 4800 if ((*ptr != '\'') && (*ptr != '"')) return(NULL);
pcercuei 0:03b5121a232e 4801 }
pcercuei 0:03b5121a232e 4802 SKIP_BLANKS;
pcercuei 0:03b5121a232e 4803 URI = xmlParseSystemLiteral(ctxt);
pcercuei 0:03b5121a232e 4804 if (URI == NULL) {
pcercuei 0:03b5121a232e 4805 xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL);
pcercuei 0:03b5121a232e 4806 }
pcercuei 0:03b5121a232e 4807 }
pcercuei 0:03b5121a232e 4808 return(URI);
pcercuei 0:03b5121a232e 4809 }
pcercuei 0:03b5121a232e 4810
pcercuei 0:03b5121a232e 4811 /**
pcercuei 0:03b5121a232e 4812 * xmlParseCommentComplex:
pcercuei 0:03b5121a232e 4813 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 4814 * @buf: the already parsed part of the buffer
pcercuei 0:03b5121a232e 4815 * @len: number of bytes filles in the buffer
pcercuei 0:03b5121a232e 4816 * @size: allocated size of the buffer
pcercuei 0:03b5121a232e 4817 *
pcercuei 0:03b5121a232e 4818 * Skip an XML (SGML) comment <!-- .... -->
pcercuei 0:03b5121a232e 4819 * The spec says that "For compatibility, the string "--" (double-hyphen)
pcercuei 0:03b5121a232e 4820 * must not occur within comments. "
pcercuei 0:03b5121a232e 4821 * This is the slow routine in case the accelerator for ascii didn't work
pcercuei 0:03b5121a232e 4822 *
pcercuei 0:03b5121a232e 4823 * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
pcercuei 0:03b5121a232e 4824 */
pcercuei 0:03b5121a232e 4825 static void
pcercuei 0:03b5121a232e 4826 xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf,
pcercuei 0:03b5121a232e 4827 size_t len, size_t size) {
pcercuei 0:03b5121a232e 4828 int q, ql;
pcercuei 0:03b5121a232e 4829 int r, rl;
pcercuei 0:03b5121a232e 4830 int cur, l;
pcercuei 0:03b5121a232e 4831 size_t count = 0;
pcercuei 0:03b5121a232e 4832 int inputid;
pcercuei 0:03b5121a232e 4833
pcercuei 0:03b5121a232e 4834 inputid = ctxt->input->id;
pcercuei 0:03b5121a232e 4835
pcercuei 0:03b5121a232e 4836 if (buf == NULL) {
pcercuei 0:03b5121a232e 4837 len = 0;
pcercuei 0:03b5121a232e 4838 size = XML_PARSER_BUFFER_SIZE;
pcercuei 0:03b5121a232e 4839 buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
pcercuei 0:03b5121a232e 4840 if (buf == NULL) {
pcercuei 0:03b5121a232e 4841 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 4842 return;
pcercuei 0:03b5121a232e 4843 }
pcercuei 0:03b5121a232e 4844 }
pcercuei 0:03b5121a232e 4845 GROW; /* Assure there's enough input data */
pcercuei 0:03b5121a232e 4846 q = CUR_CHAR(ql);
pcercuei 0:03b5121a232e 4847 if (q == 0)
pcercuei 0:03b5121a232e 4848 goto not_terminated;
pcercuei 0:03b5121a232e 4849 if (!IS_CHAR(q)) {
pcercuei 0:03b5121a232e 4850 xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
pcercuei 0:03b5121a232e 4851 "xmlParseComment: invalid xmlChar value %d\n",
pcercuei 0:03b5121a232e 4852 q);
pcercuei 0:03b5121a232e 4853 xmlFree (buf);
pcercuei 0:03b5121a232e 4854 return;
pcercuei 0:03b5121a232e 4855 }
pcercuei 0:03b5121a232e 4856 NEXTL(ql);
pcercuei 0:03b5121a232e 4857 r = CUR_CHAR(rl);
pcercuei 0:03b5121a232e 4858 if (r == 0)
pcercuei 0:03b5121a232e 4859 goto not_terminated;
pcercuei 0:03b5121a232e 4860 if (!IS_CHAR(r)) {
pcercuei 0:03b5121a232e 4861 xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
pcercuei 0:03b5121a232e 4862 "xmlParseComment: invalid xmlChar value %d\n",
pcercuei 0:03b5121a232e 4863 q);
pcercuei 0:03b5121a232e 4864 xmlFree (buf);
pcercuei 0:03b5121a232e 4865 return;
pcercuei 0:03b5121a232e 4866 }
pcercuei 0:03b5121a232e 4867 NEXTL(rl);
pcercuei 0:03b5121a232e 4868 cur = CUR_CHAR(l);
pcercuei 0:03b5121a232e 4869 if (cur == 0)
pcercuei 0:03b5121a232e 4870 goto not_terminated;
pcercuei 0:03b5121a232e 4871 while (IS_CHAR(cur) && /* checked */
pcercuei 0:03b5121a232e 4872 ((cur != '>') ||
pcercuei 0:03b5121a232e 4873 (r != '-') || (q != '-'))) {
pcercuei 0:03b5121a232e 4874 if ((r == '-') && (q == '-')) {
pcercuei 0:03b5121a232e 4875 xmlFatalErr(ctxt, XML_ERR_HYPHEN_IN_COMMENT, NULL);
pcercuei 0:03b5121a232e 4876 }
pcercuei 0:03b5121a232e 4877 if ((len > XML_MAX_TEXT_LENGTH) &&
pcercuei 0:03b5121a232e 4878 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
pcercuei 0:03b5121a232e 4879 xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
pcercuei 0:03b5121a232e 4880 "Comment too big found", NULL);
pcercuei 0:03b5121a232e 4881 xmlFree (buf);
pcercuei 0:03b5121a232e 4882 return;
pcercuei 0:03b5121a232e 4883 }
pcercuei 0:03b5121a232e 4884 if (len + 5 >= size) {
pcercuei 0:03b5121a232e 4885 xmlChar *new_buf;
pcercuei 0:03b5121a232e 4886 size_t new_size;
pcercuei 0:03b5121a232e 4887
pcercuei 0:03b5121a232e 4888 new_size = size * 2;
pcercuei 0:03b5121a232e 4889 new_buf = (xmlChar *) xmlRealloc(buf, new_size);
pcercuei 0:03b5121a232e 4890 if (new_buf == NULL) {
pcercuei 0:03b5121a232e 4891 xmlFree (buf);
pcercuei 0:03b5121a232e 4892 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 4893 return;
pcercuei 0:03b5121a232e 4894 }
pcercuei 0:03b5121a232e 4895 buf = new_buf;
pcercuei 0:03b5121a232e 4896 size = new_size;
pcercuei 0:03b5121a232e 4897 }
pcercuei 0:03b5121a232e 4898 COPY_BUF(ql,buf,len,q);
pcercuei 0:03b5121a232e 4899 q = r;
pcercuei 0:03b5121a232e 4900 ql = rl;
pcercuei 0:03b5121a232e 4901 r = cur;
pcercuei 0:03b5121a232e 4902 rl = l;
pcercuei 0:03b5121a232e 4903
pcercuei 0:03b5121a232e 4904 count++;
pcercuei 0:03b5121a232e 4905 if (count > 50) {
pcercuei 0:03b5121a232e 4906 GROW;
pcercuei 0:03b5121a232e 4907 count = 0;
pcercuei 0:03b5121a232e 4908 if (ctxt->instate == XML_PARSER_EOF) {
pcercuei 0:03b5121a232e 4909 xmlFree(buf);
pcercuei 0:03b5121a232e 4910 return;
pcercuei 0:03b5121a232e 4911 }
pcercuei 0:03b5121a232e 4912 }
pcercuei 0:03b5121a232e 4913 NEXTL(l);
pcercuei 0:03b5121a232e 4914 cur = CUR_CHAR(l);
pcercuei 0:03b5121a232e 4915 if (cur == 0) {
pcercuei 0:03b5121a232e 4916 SHRINK;
pcercuei 0:03b5121a232e 4917 GROW;
pcercuei 0:03b5121a232e 4918 cur = CUR_CHAR(l);
pcercuei 0:03b5121a232e 4919 }
pcercuei 0:03b5121a232e 4920 }
pcercuei 0:03b5121a232e 4921 buf[len] = 0;
pcercuei 0:03b5121a232e 4922 if (cur == 0) {
pcercuei 0:03b5121a232e 4923 xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
pcercuei 0:03b5121a232e 4924 "Comment not terminated \n<!--%.50s\n", buf);
pcercuei 0:03b5121a232e 4925 } else if (!IS_CHAR(cur)) {
pcercuei 0:03b5121a232e 4926 xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
pcercuei 0:03b5121a232e 4927 "xmlParseComment: invalid xmlChar value %d\n",
pcercuei 0:03b5121a232e 4928 cur);
pcercuei 0:03b5121a232e 4929 } else {
pcercuei 0:03b5121a232e 4930 if (inputid != ctxt->input->id) {
pcercuei 0:03b5121a232e 4931 xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
pcercuei 0:03b5121a232e 4932 "Comment doesn't start and stop in the same entity\n");
pcercuei 0:03b5121a232e 4933 }
pcercuei 0:03b5121a232e 4934 NEXT;
pcercuei 0:03b5121a232e 4935 if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
pcercuei 0:03b5121a232e 4936 (!ctxt->disableSAX))
pcercuei 0:03b5121a232e 4937 ctxt->sax->comment(ctxt->userData, buf);
pcercuei 0:03b5121a232e 4938 }
pcercuei 0:03b5121a232e 4939 xmlFree(buf);
pcercuei 0:03b5121a232e 4940 return;
pcercuei 0:03b5121a232e 4941 not_terminated:
pcercuei 0:03b5121a232e 4942 xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
pcercuei 0:03b5121a232e 4943 "Comment not terminated\n", NULL);
pcercuei 0:03b5121a232e 4944 xmlFree(buf);
pcercuei 0:03b5121a232e 4945 return;
pcercuei 0:03b5121a232e 4946 }
pcercuei 0:03b5121a232e 4947
pcercuei 0:03b5121a232e 4948 /**
pcercuei 0:03b5121a232e 4949 * xmlParseComment:
pcercuei 0:03b5121a232e 4950 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 4951 *
pcercuei 0:03b5121a232e 4952 * Skip an XML (SGML) comment <!-- .... -->
pcercuei 0:03b5121a232e 4953 * The spec says that "For compatibility, the string "--" (double-hyphen)
pcercuei 0:03b5121a232e 4954 * must not occur within comments. "
pcercuei 0:03b5121a232e 4955 *
pcercuei 0:03b5121a232e 4956 * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
pcercuei 0:03b5121a232e 4957 */
pcercuei 0:03b5121a232e 4958 void
pcercuei 0:03b5121a232e 4959 xmlParseComment(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 4960 xmlChar *buf = NULL;
pcercuei 0:03b5121a232e 4961 size_t size = XML_PARSER_BUFFER_SIZE;
pcercuei 0:03b5121a232e 4962 size_t len = 0;
pcercuei 0:03b5121a232e 4963 xmlParserInputState state;
pcercuei 0:03b5121a232e 4964 const xmlChar *in;
pcercuei 0:03b5121a232e 4965 size_t nbchar = 0;
pcercuei 0:03b5121a232e 4966 int ccol;
pcercuei 0:03b5121a232e 4967 int inputid;
pcercuei 0:03b5121a232e 4968
pcercuei 0:03b5121a232e 4969 /*
pcercuei 0:03b5121a232e 4970 * Check that there is a comment right here.
pcercuei 0:03b5121a232e 4971 */
pcercuei 0:03b5121a232e 4972 if ((RAW != '<') || (NXT(1) != '!') ||
pcercuei 0:03b5121a232e 4973 (NXT(2) != '-') || (NXT(3) != '-')) return;
pcercuei 0:03b5121a232e 4974 state = ctxt->instate;
pcercuei 0:03b5121a232e 4975 ctxt->instate = XML_PARSER_COMMENT;
pcercuei 0:03b5121a232e 4976 inputid = ctxt->input->id;
pcercuei 0:03b5121a232e 4977 SKIP(4);
pcercuei 0:03b5121a232e 4978 SHRINK;
pcercuei 0:03b5121a232e 4979 GROW;
pcercuei 0:03b5121a232e 4980
pcercuei 0:03b5121a232e 4981 /*
pcercuei 0:03b5121a232e 4982 * Accelerated common case where input don't need to be
pcercuei 0:03b5121a232e 4983 * modified before passing it to the handler.
pcercuei 0:03b5121a232e 4984 */
pcercuei 0:03b5121a232e 4985 in = ctxt->input->cur;
pcercuei 0:03b5121a232e 4986 do {
pcercuei 0:03b5121a232e 4987 if (*in == 0xA) {
pcercuei 0:03b5121a232e 4988 do {
pcercuei 0:03b5121a232e 4989 ctxt->input->line++; ctxt->input->col = 1;
pcercuei 0:03b5121a232e 4990 in++;
pcercuei 0:03b5121a232e 4991 } while (*in == 0xA);
pcercuei 0:03b5121a232e 4992 }
pcercuei 0:03b5121a232e 4993 get_more:
pcercuei 0:03b5121a232e 4994 ccol = ctxt->input->col;
pcercuei 0:03b5121a232e 4995 while (((*in > '-') && (*in <= 0x7F)) ||
pcercuei 0:03b5121a232e 4996 ((*in >= 0x20) && (*in < '-')) ||
pcercuei 0:03b5121a232e 4997 (*in == 0x09)) {
pcercuei 0:03b5121a232e 4998 in++;
pcercuei 0:03b5121a232e 4999 ccol++;
pcercuei 0:03b5121a232e 5000 }
pcercuei 0:03b5121a232e 5001 ctxt->input->col = ccol;
pcercuei 0:03b5121a232e 5002 if (*in == 0xA) {
pcercuei 0:03b5121a232e 5003 do {
pcercuei 0:03b5121a232e 5004 ctxt->input->line++; ctxt->input->col = 1;
pcercuei 0:03b5121a232e 5005 in++;
pcercuei 0:03b5121a232e 5006 } while (*in == 0xA);
pcercuei 0:03b5121a232e 5007 goto get_more;
pcercuei 0:03b5121a232e 5008 }
pcercuei 0:03b5121a232e 5009 nbchar = in - ctxt->input->cur;
pcercuei 0:03b5121a232e 5010 /*
pcercuei 0:03b5121a232e 5011 * save current set of data
pcercuei 0:03b5121a232e 5012 */
pcercuei 0:03b5121a232e 5013 if (nbchar > 0) {
pcercuei 0:03b5121a232e 5014 if ((ctxt->sax != NULL) &&
pcercuei 0:03b5121a232e 5015 (ctxt->sax->comment != NULL)) {
pcercuei 0:03b5121a232e 5016 if (buf == NULL) {
pcercuei 0:03b5121a232e 5017 if ((*in == '-') && (in[1] == '-'))
pcercuei 0:03b5121a232e 5018 size = nbchar + 1;
pcercuei 0:03b5121a232e 5019 else
pcercuei 0:03b5121a232e 5020 size = XML_PARSER_BUFFER_SIZE + nbchar;
pcercuei 0:03b5121a232e 5021 buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
pcercuei 0:03b5121a232e 5022 if (buf == NULL) {
pcercuei 0:03b5121a232e 5023 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 5024 ctxt->instate = state;
pcercuei 0:03b5121a232e 5025 return;
pcercuei 0:03b5121a232e 5026 }
pcercuei 0:03b5121a232e 5027 len = 0;
pcercuei 0:03b5121a232e 5028 } else if (len + nbchar + 1 >= size) {
pcercuei 0:03b5121a232e 5029 xmlChar *new_buf;
pcercuei 0:03b5121a232e 5030 size += len + nbchar + XML_PARSER_BUFFER_SIZE;
pcercuei 0:03b5121a232e 5031 new_buf = (xmlChar *) xmlRealloc(buf,
pcercuei 0:03b5121a232e 5032 size * sizeof(xmlChar));
pcercuei 0:03b5121a232e 5033 if (new_buf == NULL) {
pcercuei 0:03b5121a232e 5034 xmlFree (buf);
pcercuei 0:03b5121a232e 5035 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 5036 ctxt->instate = state;
pcercuei 0:03b5121a232e 5037 return;
pcercuei 0:03b5121a232e 5038 }
pcercuei 0:03b5121a232e 5039 buf = new_buf;
pcercuei 0:03b5121a232e 5040 }
pcercuei 0:03b5121a232e 5041 memcpy(&buf[len], ctxt->input->cur, nbchar);
pcercuei 0:03b5121a232e 5042 len += nbchar;
pcercuei 0:03b5121a232e 5043 buf[len] = 0;
pcercuei 0:03b5121a232e 5044 }
pcercuei 0:03b5121a232e 5045 }
pcercuei 0:03b5121a232e 5046 if ((len > XML_MAX_TEXT_LENGTH) &&
pcercuei 0:03b5121a232e 5047 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
pcercuei 0:03b5121a232e 5048 xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
pcercuei 0:03b5121a232e 5049 "Comment too big found", NULL);
pcercuei 0:03b5121a232e 5050 xmlFree (buf);
pcercuei 0:03b5121a232e 5051 return;
pcercuei 0:03b5121a232e 5052 }
pcercuei 0:03b5121a232e 5053 ctxt->input->cur = in;
pcercuei 0:03b5121a232e 5054 if (*in == 0xA) {
pcercuei 0:03b5121a232e 5055 in++;
pcercuei 0:03b5121a232e 5056 ctxt->input->line++; ctxt->input->col = 1;
pcercuei 0:03b5121a232e 5057 }
pcercuei 0:03b5121a232e 5058 if (*in == 0xD) {
pcercuei 0:03b5121a232e 5059 in++;
pcercuei 0:03b5121a232e 5060 if (*in == 0xA) {
pcercuei 0:03b5121a232e 5061 ctxt->input->cur = in;
pcercuei 0:03b5121a232e 5062 in++;
pcercuei 0:03b5121a232e 5063 ctxt->input->line++; ctxt->input->col = 1;
pcercuei 0:03b5121a232e 5064 continue; /* while */
pcercuei 0:03b5121a232e 5065 }
pcercuei 0:03b5121a232e 5066 in--;
pcercuei 0:03b5121a232e 5067 }
pcercuei 0:03b5121a232e 5068 SHRINK;
pcercuei 0:03b5121a232e 5069 GROW;
pcercuei 0:03b5121a232e 5070 if (ctxt->instate == XML_PARSER_EOF) {
pcercuei 0:03b5121a232e 5071 xmlFree(buf);
pcercuei 0:03b5121a232e 5072 return;
pcercuei 0:03b5121a232e 5073 }
pcercuei 0:03b5121a232e 5074 in = ctxt->input->cur;
pcercuei 0:03b5121a232e 5075 if (*in == '-') {
pcercuei 0:03b5121a232e 5076 if (in[1] == '-') {
pcercuei 0:03b5121a232e 5077 if (in[2] == '>') {
pcercuei 0:03b5121a232e 5078 if (ctxt->input->id != inputid) {
pcercuei 0:03b5121a232e 5079 xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
pcercuei 0:03b5121a232e 5080 "comment doesn't start and stop in the same entity\n");
pcercuei 0:03b5121a232e 5081 }
pcercuei 0:03b5121a232e 5082 SKIP(3);
pcercuei 0:03b5121a232e 5083 if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
pcercuei 0:03b5121a232e 5084 (!ctxt->disableSAX)) {
pcercuei 0:03b5121a232e 5085 if (buf != NULL)
pcercuei 0:03b5121a232e 5086 ctxt->sax->comment(ctxt->userData, buf);
pcercuei 0:03b5121a232e 5087 else
pcercuei 0:03b5121a232e 5088 ctxt->sax->comment(ctxt->userData, BAD_CAST "");
pcercuei 0:03b5121a232e 5089 }
pcercuei 0:03b5121a232e 5090 if (buf != NULL)
pcercuei 0:03b5121a232e 5091 xmlFree(buf);
pcercuei 0:03b5121a232e 5092 if (ctxt->instate != XML_PARSER_EOF)
pcercuei 0:03b5121a232e 5093 ctxt->instate = state;
pcercuei 0:03b5121a232e 5094 return;
pcercuei 0:03b5121a232e 5095 }
pcercuei 0:03b5121a232e 5096 if (buf != NULL) {
pcercuei 0:03b5121a232e 5097 xmlFatalErrMsgStr(ctxt, XML_ERR_HYPHEN_IN_COMMENT,
pcercuei 0:03b5121a232e 5098 "Double hyphen within comment: "
pcercuei 0:03b5121a232e 5099 "<!--%.50s\n",
pcercuei 0:03b5121a232e 5100 buf);
pcercuei 0:03b5121a232e 5101 } else
pcercuei 0:03b5121a232e 5102 xmlFatalErrMsgStr(ctxt, XML_ERR_HYPHEN_IN_COMMENT,
pcercuei 0:03b5121a232e 5103 "Double hyphen within comment\n", NULL);
pcercuei 0:03b5121a232e 5104 in++;
pcercuei 0:03b5121a232e 5105 ctxt->input->col++;
pcercuei 0:03b5121a232e 5106 }
pcercuei 0:03b5121a232e 5107 in++;
pcercuei 0:03b5121a232e 5108 ctxt->input->col++;
pcercuei 0:03b5121a232e 5109 goto get_more;
pcercuei 0:03b5121a232e 5110 }
pcercuei 0:03b5121a232e 5111 } while (((*in >= 0x20) && (*in <= 0x7F)) || (*in == 0x09));
pcercuei 0:03b5121a232e 5112 xmlParseCommentComplex(ctxt, buf, len, size);
pcercuei 0:03b5121a232e 5113 ctxt->instate = state;
pcercuei 0:03b5121a232e 5114 return;
pcercuei 0:03b5121a232e 5115 }
pcercuei 0:03b5121a232e 5116
pcercuei 0:03b5121a232e 5117
pcercuei 0:03b5121a232e 5118 /**
pcercuei 0:03b5121a232e 5119 * xmlParsePITarget:
pcercuei 0:03b5121a232e 5120 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 5121 *
pcercuei 0:03b5121a232e 5122 * parse the name of a PI
pcercuei 0:03b5121a232e 5123 *
pcercuei 0:03b5121a232e 5124 * [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
pcercuei 0:03b5121a232e 5125 *
pcercuei 0:03b5121a232e 5126 * Returns the PITarget name or NULL
pcercuei 0:03b5121a232e 5127 */
pcercuei 0:03b5121a232e 5128
pcercuei 0:03b5121a232e 5129 const xmlChar *
pcercuei 0:03b5121a232e 5130 xmlParsePITarget(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 5131 const xmlChar *name;
pcercuei 0:03b5121a232e 5132
pcercuei 0:03b5121a232e 5133 name = xmlParseName(ctxt);
pcercuei 0:03b5121a232e 5134 if ((name != NULL) &&
pcercuei 0:03b5121a232e 5135 ((name[0] == 'x') || (name[0] == 'X')) &&
pcercuei 0:03b5121a232e 5136 ((name[1] == 'm') || (name[1] == 'M')) &&
pcercuei 0:03b5121a232e 5137 ((name[2] == 'l') || (name[2] == 'L'))) {
pcercuei 0:03b5121a232e 5138 int i;
pcercuei 0:03b5121a232e 5139 if ((name[0] == 'x') && (name[1] == 'm') &&
pcercuei 0:03b5121a232e 5140 (name[2] == 'l') && (name[3] == 0)) {
pcercuei 0:03b5121a232e 5141 xmlFatalErrMsg(ctxt, XML_ERR_RESERVED_XML_NAME,
pcercuei 0:03b5121a232e 5142 "XML declaration allowed only at the start of the document\n");
pcercuei 0:03b5121a232e 5143 return(name);
pcercuei 0:03b5121a232e 5144 } else if (name[3] == 0) {
pcercuei 0:03b5121a232e 5145 xmlFatalErr(ctxt, XML_ERR_RESERVED_XML_NAME, NULL);
pcercuei 0:03b5121a232e 5146 return(name);
pcercuei 0:03b5121a232e 5147 }
pcercuei 0:03b5121a232e 5148 for (i = 0;;i++) {
pcercuei 0:03b5121a232e 5149 if (xmlW3CPIs[i] == NULL) break;
pcercuei 0:03b5121a232e 5150 if (xmlStrEqual(name, (const xmlChar *)xmlW3CPIs[i]))
pcercuei 0:03b5121a232e 5151 return(name);
pcercuei 0:03b5121a232e 5152 }
pcercuei 0:03b5121a232e 5153 xmlWarningMsg(ctxt, XML_ERR_RESERVED_XML_NAME,
pcercuei 0:03b5121a232e 5154 "xmlParsePITarget: invalid name prefix 'xml'\n",
pcercuei 0:03b5121a232e 5155 NULL, NULL);
pcercuei 0:03b5121a232e 5156 }
pcercuei 0:03b5121a232e 5157 if ((name != NULL) && (xmlStrchr(name, ':') != NULL)) {
pcercuei 0:03b5121a232e 5158 xmlNsErr(ctxt, XML_NS_ERR_COLON,
pcercuei 0:03b5121a232e 5159 "colons are forbidden from PI names '%s'\n", name, NULL, NULL);
pcercuei 0:03b5121a232e 5160 }
pcercuei 0:03b5121a232e 5161 return(name);
pcercuei 0:03b5121a232e 5162 }
pcercuei 0:03b5121a232e 5163
pcercuei 0:03b5121a232e 5164 #ifdef LIBXML_CATALOG_ENABLED
pcercuei 0:03b5121a232e 5165 /**
pcercuei 0:03b5121a232e 5166 * xmlParseCatalogPI:
pcercuei 0:03b5121a232e 5167 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 5168 * @catalog: the PI value string
pcercuei 0:03b5121a232e 5169 *
pcercuei 0:03b5121a232e 5170 * parse an XML Catalog Processing Instruction.
pcercuei 0:03b5121a232e 5171 *
pcercuei 0:03b5121a232e 5172 * <?oasis-xml-catalog catalog="http://example.com/catalog.xml"?>
pcercuei 0:03b5121a232e 5173 *
pcercuei 0:03b5121a232e 5174 * Occurs only if allowed by the user and if happening in the Misc
pcercuei 0:03b5121a232e 5175 * part of the document before any doctype informations
pcercuei 0:03b5121a232e 5176 * This will add the given catalog to the parsing context in order
pcercuei 0:03b5121a232e 5177 * to be used if there is a resolution need further down in the document
pcercuei 0:03b5121a232e 5178 */
pcercuei 0:03b5121a232e 5179
pcercuei 0:03b5121a232e 5180 static void
pcercuei 0:03b5121a232e 5181 xmlParseCatalogPI(xmlParserCtxtPtr ctxt, const xmlChar *catalog) {
pcercuei 0:03b5121a232e 5182 xmlChar *URL = NULL;
pcercuei 0:03b5121a232e 5183 const xmlChar *tmp, *base;
pcercuei 0:03b5121a232e 5184 xmlChar marker;
pcercuei 0:03b5121a232e 5185
pcercuei 0:03b5121a232e 5186 tmp = catalog;
pcercuei 0:03b5121a232e 5187 while (IS_BLANK_CH(*tmp)) tmp++;
pcercuei 0:03b5121a232e 5188 if (xmlStrncmp(tmp, BAD_CAST"catalog", 7))
pcercuei 0:03b5121a232e 5189 goto error;
pcercuei 0:03b5121a232e 5190 tmp += 7;
pcercuei 0:03b5121a232e 5191 while (IS_BLANK_CH(*tmp)) tmp++;
pcercuei 0:03b5121a232e 5192 if (*tmp != '=') {
pcercuei 0:03b5121a232e 5193 return;
pcercuei 0:03b5121a232e 5194 }
pcercuei 0:03b5121a232e 5195 tmp++;
pcercuei 0:03b5121a232e 5196 while (IS_BLANK_CH(*tmp)) tmp++;
pcercuei 0:03b5121a232e 5197 marker = *tmp;
pcercuei 0:03b5121a232e 5198 if ((marker != '\'') && (marker != '"'))
pcercuei 0:03b5121a232e 5199 goto error;
pcercuei 0:03b5121a232e 5200 tmp++;
pcercuei 0:03b5121a232e 5201 base = tmp;
pcercuei 0:03b5121a232e 5202 while ((*tmp != 0) && (*tmp != marker)) tmp++;
pcercuei 0:03b5121a232e 5203 if (*tmp == 0)
pcercuei 0:03b5121a232e 5204 goto error;
pcercuei 0:03b5121a232e 5205 URL = xmlStrndup(base, tmp - base);
pcercuei 0:03b5121a232e 5206 tmp++;
pcercuei 0:03b5121a232e 5207 while (IS_BLANK_CH(*tmp)) tmp++;
pcercuei 0:03b5121a232e 5208 if (*tmp != 0)
pcercuei 0:03b5121a232e 5209 goto error;
pcercuei 0:03b5121a232e 5210
pcercuei 0:03b5121a232e 5211 if (URL != NULL) {
pcercuei 0:03b5121a232e 5212 ctxt->catalogs = xmlCatalogAddLocal(ctxt->catalogs, URL);
pcercuei 0:03b5121a232e 5213 xmlFree(URL);
pcercuei 0:03b5121a232e 5214 }
pcercuei 0:03b5121a232e 5215 return;
pcercuei 0:03b5121a232e 5216
pcercuei 0:03b5121a232e 5217 error:
pcercuei 0:03b5121a232e 5218 xmlWarningMsg(ctxt, XML_WAR_CATALOG_PI,
pcercuei 0:03b5121a232e 5219 "Catalog PI syntax error: %s\n",
pcercuei 0:03b5121a232e 5220 catalog, NULL);
pcercuei 0:03b5121a232e 5221 if (URL != NULL)
pcercuei 0:03b5121a232e 5222 xmlFree(URL);
pcercuei 0:03b5121a232e 5223 }
pcercuei 0:03b5121a232e 5224 #endif
pcercuei 0:03b5121a232e 5225
pcercuei 0:03b5121a232e 5226 /**
pcercuei 0:03b5121a232e 5227 * xmlParsePI:
pcercuei 0:03b5121a232e 5228 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 5229 *
pcercuei 0:03b5121a232e 5230 * parse an XML Processing Instruction.
pcercuei 0:03b5121a232e 5231 *
pcercuei 0:03b5121a232e 5232 * [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
pcercuei 0:03b5121a232e 5233 *
pcercuei 0:03b5121a232e 5234 * The processing is transfered to SAX once parsed.
pcercuei 0:03b5121a232e 5235 */
pcercuei 0:03b5121a232e 5236
pcercuei 0:03b5121a232e 5237 void
pcercuei 0:03b5121a232e 5238 xmlParsePI(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 5239 xmlChar *buf = NULL;
pcercuei 0:03b5121a232e 5240 size_t len = 0;
pcercuei 0:03b5121a232e 5241 size_t size = XML_PARSER_BUFFER_SIZE;
pcercuei 0:03b5121a232e 5242 int cur, l;
pcercuei 0:03b5121a232e 5243 const xmlChar *target;
pcercuei 0:03b5121a232e 5244 xmlParserInputState state;
pcercuei 0:03b5121a232e 5245 int count = 0;
pcercuei 0:03b5121a232e 5246
pcercuei 0:03b5121a232e 5247 if ((RAW == '<') && (NXT(1) == '?')) {
pcercuei 0:03b5121a232e 5248 xmlParserInputPtr input = ctxt->input;
pcercuei 0:03b5121a232e 5249 state = ctxt->instate;
pcercuei 0:03b5121a232e 5250 ctxt->instate = XML_PARSER_PI;
pcercuei 0:03b5121a232e 5251 /*
pcercuei 0:03b5121a232e 5252 * this is a Processing Instruction.
pcercuei 0:03b5121a232e 5253 */
pcercuei 0:03b5121a232e 5254 SKIP(2);
pcercuei 0:03b5121a232e 5255 SHRINK;
pcercuei 0:03b5121a232e 5256
pcercuei 0:03b5121a232e 5257 /*
pcercuei 0:03b5121a232e 5258 * Parse the target name and check for special support like
pcercuei 0:03b5121a232e 5259 * namespace.
pcercuei 0:03b5121a232e 5260 */
pcercuei 0:03b5121a232e 5261 target = xmlParsePITarget(ctxt);
pcercuei 0:03b5121a232e 5262 if (target != NULL) {
pcercuei 0:03b5121a232e 5263 if ((RAW == '?') && (NXT(1) == '>')) {
pcercuei 0:03b5121a232e 5264 if (input != ctxt->input) {
pcercuei 0:03b5121a232e 5265 xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
pcercuei 0:03b5121a232e 5266 "PI declaration doesn't start and stop in the same entity\n");
pcercuei 0:03b5121a232e 5267 }
pcercuei 0:03b5121a232e 5268 SKIP(2);
pcercuei 0:03b5121a232e 5269
pcercuei 0:03b5121a232e 5270 /*
pcercuei 0:03b5121a232e 5271 * SAX: PI detected.
pcercuei 0:03b5121a232e 5272 */
pcercuei 0:03b5121a232e 5273 if ((ctxt->sax) && (!ctxt->disableSAX) &&
pcercuei 0:03b5121a232e 5274 (ctxt->sax->processingInstruction != NULL))
pcercuei 0:03b5121a232e 5275 ctxt->sax->processingInstruction(ctxt->userData,
pcercuei 0:03b5121a232e 5276 target, NULL);
pcercuei 0:03b5121a232e 5277 if (ctxt->instate != XML_PARSER_EOF)
pcercuei 0:03b5121a232e 5278 ctxt->instate = state;
pcercuei 0:03b5121a232e 5279 return;
pcercuei 0:03b5121a232e 5280 }
pcercuei 0:03b5121a232e 5281 buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
pcercuei 0:03b5121a232e 5282 if (buf == NULL) {
pcercuei 0:03b5121a232e 5283 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 5284 ctxt->instate = state;
pcercuei 0:03b5121a232e 5285 return;
pcercuei 0:03b5121a232e 5286 }
pcercuei 0:03b5121a232e 5287 cur = CUR;
pcercuei 0:03b5121a232e 5288 if (!IS_BLANK(cur)) {
pcercuei 0:03b5121a232e 5289 xmlFatalErrMsgStr(ctxt, XML_ERR_SPACE_REQUIRED,
pcercuei 0:03b5121a232e 5290 "ParsePI: PI %s space expected\n", target);
pcercuei 0:03b5121a232e 5291 }
pcercuei 0:03b5121a232e 5292 SKIP_BLANKS;
pcercuei 0:03b5121a232e 5293 cur = CUR_CHAR(l);
pcercuei 0:03b5121a232e 5294 while (IS_CHAR(cur) && /* checked */
pcercuei 0:03b5121a232e 5295 ((cur != '?') || (NXT(1) != '>'))) {
pcercuei 0:03b5121a232e 5296 if (len + 5 >= size) {
pcercuei 0:03b5121a232e 5297 xmlChar *tmp;
pcercuei 0:03b5121a232e 5298 size_t new_size = size * 2;
pcercuei 0:03b5121a232e 5299 tmp = (xmlChar *) xmlRealloc(buf, new_size);
pcercuei 0:03b5121a232e 5300 if (tmp == NULL) {
pcercuei 0:03b5121a232e 5301 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 5302 xmlFree(buf);
pcercuei 0:03b5121a232e 5303 ctxt->instate = state;
pcercuei 0:03b5121a232e 5304 return;
pcercuei 0:03b5121a232e 5305 }
pcercuei 0:03b5121a232e 5306 buf = tmp;
pcercuei 0:03b5121a232e 5307 size = new_size;
pcercuei 0:03b5121a232e 5308 }
pcercuei 0:03b5121a232e 5309 count++;
pcercuei 0:03b5121a232e 5310 if (count > 50) {
pcercuei 0:03b5121a232e 5311 GROW;
pcercuei 0:03b5121a232e 5312 if (ctxt->instate == XML_PARSER_EOF) {
pcercuei 0:03b5121a232e 5313 xmlFree(buf);
pcercuei 0:03b5121a232e 5314 return;
pcercuei 0:03b5121a232e 5315 }
pcercuei 0:03b5121a232e 5316 count = 0;
pcercuei 0:03b5121a232e 5317 if ((len > XML_MAX_TEXT_LENGTH) &&
pcercuei 0:03b5121a232e 5318 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
pcercuei 0:03b5121a232e 5319 xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
pcercuei 0:03b5121a232e 5320 "PI %s too big found", target);
pcercuei 0:03b5121a232e 5321 xmlFree(buf);
pcercuei 0:03b5121a232e 5322 ctxt->instate = state;
pcercuei 0:03b5121a232e 5323 return;
pcercuei 0:03b5121a232e 5324 }
pcercuei 0:03b5121a232e 5325 }
pcercuei 0:03b5121a232e 5326 COPY_BUF(l,buf,len,cur);
pcercuei 0:03b5121a232e 5327 NEXTL(l);
pcercuei 0:03b5121a232e 5328 cur = CUR_CHAR(l);
pcercuei 0:03b5121a232e 5329 if (cur == 0) {
pcercuei 0:03b5121a232e 5330 SHRINK;
pcercuei 0:03b5121a232e 5331 GROW;
pcercuei 0:03b5121a232e 5332 cur = CUR_CHAR(l);
pcercuei 0:03b5121a232e 5333 }
pcercuei 0:03b5121a232e 5334 }
pcercuei 0:03b5121a232e 5335 if ((len > XML_MAX_TEXT_LENGTH) &&
pcercuei 0:03b5121a232e 5336 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
pcercuei 0:03b5121a232e 5337 xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
pcercuei 0:03b5121a232e 5338 "PI %s too big found", target);
pcercuei 0:03b5121a232e 5339 xmlFree(buf);
pcercuei 0:03b5121a232e 5340 ctxt->instate = state;
pcercuei 0:03b5121a232e 5341 return;
pcercuei 0:03b5121a232e 5342 }
pcercuei 0:03b5121a232e 5343 buf[len] = 0;
pcercuei 0:03b5121a232e 5344 if (cur != '?') {
pcercuei 0:03b5121a232e 5345 xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
pcercuei 0:03b5121a232e 5346 "ParsePI: PI %s never end ...\n", target);
pcercuei 0:03b5121a232e 5347 } else {
pcercuei 0:03b5121a232e 5348 if (input != ctxt->input) {
pcercuei 0:03b5121a232e 5349 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
pcercuei 0:03b5121a232e 5350 "PI declaration doesn't start and stop in the same entity\n");
pcercuei 0:03b5121a232e 5351 }
pcercuei 0:03b5121a232e 5352 SKIP(2);
pcercuei 0:03b5121a232e 5353
pcercuei 0:03b5121a232e 5354 #ifdef LIBXML_CATALOG_ENABLED
pcercuei 0:03b5121a232e 5355 if (((state == XML_PARSER_MISC) ||
pcercuei 0:03b5121a232e 5356 (state == XML_PARSER_START)) &&
pcercuei 0:03b5121a232e 5357 (xmlStrEqual(target, XML_CATALOG_PI))) {
pcercuei 0:03b5121a232e 5358 xmlCatalogAllow allow = xmlCatalogGetDefaults();
pcercuei 0:03b5121a232e 5359 if ((allow == XML_CATA_ALLOW_DOCUMENT) ||
pcercuei 0:03b5121a232e 5360 (allow == XML_CATA_ALLOW_ALL))
pcercuei 0:03b5121a232e 5361 xmlParseCatalogPI(ctxt, buf);
pcercuei 0:03b5121a232e 5362 }
pcercuei 0:03b5121a232e 5363 #endif
pcercuei 0:03b5121a232e 5364
pcercuei 0:03b5121a232e 5365
pcercuei 0:03b5121a232e 5366 /*
pcercuei 0:03b5121a232e 5367 * SAX: PI detected.
pcercuei 0:03b5121a232e 5368 */
pcercuei 0:03b5121a232e 5369 if ((ctxt->sax) && (!ctxt->disableSAX) &&
pcercuei 0:03b5121a232e 5370 (ctxt->sax->processingInstruction != NULL))
pcercuei 0:03b5121a232e 5371 ctxt->sax->processingInstruction(ctxt->userData,
pcercuei 0:03b5121a232e 5372 target, buf);
pcercuei 0:03b5121a232e 5373 }
pcercuei 0:03b5121a232e 5374 xmlFree(buf);
pcercuei 0:03b5121a232e 5375 } else {
pcercuei 0:03b5121a232e 5376 xmlFatalErr(ctxt, XML_ERR_PI_NOT_STARTED, NULL);
pcercuei 0:03b5121a232e 5377 }
pcercuei 0:03b5121a232e 5378 if (ctxt->instate != XML_PARSER_EOF)
pcercuei 0:03b5121a232e 5379 ctxt->instate = state;
pcercuei 0:03b5121a232e 5380 }
pcercuei 0:03b5121a232e 5381 }
pcercuei 0:03b5121a232e 5382
pcercuei 0:03b5121a232e 5383 /**
pcercuei 0:03b5121a232e 5384 * xmlParseNotationDecl:
pcercuei 0:03b5121a232e 5385 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 5386 *
pcercuei 0:03b5121a232e 5387 * parse a notation declaration
pcercuei 0:03b5121a232e 5388 *
pcercuei 0:03b5121a232e 5389 * [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID | PublicID) S? '>'
pcercuei 0:03b5121a232e 5390 *
pcercuei 0:03b5121a232e 5391 * Hence there is actually 3 choices:
pcercuei 0:03b5121a232e 5392 * 'PUBLIC' S PubidLiteral
pcercuei 0:03b5121a232e 5393 * 'PUBLIC' S PubidLiteral S SystemLiteral
pcercuei 0:03b5121a232e 5394 * and 'SYSTEM' S SystemLiteral
pcercuei 0:03b5121a232e 5395 *
pcercuei 0:03b5121a232e 5396 * See the NOTE on xmlParseExternalID().
pcercuei 0:03b5121a232e 5397 */
pcercuei 0:03b5121a232e 5398
pcercuei 0:03b5121a232e 5399 void
pcercuei 0:03b5121a232e 5400 xmlParseNotationDecl(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 5401 const xmlChar *name;
pcercuei 0:03b5121a232e 5402 xmlChar *Pubid;
pcercuei 0:03b5121a232e 5403 xmlChar *Systemid;
pcercuei 0:03b5121a232e 5404
pcercuei 0:03b5121a232e 5405 if (CMP10(CUR_PTR, '<', '!', 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
pcercuei 0:03b5121a232e 5406 xmlParserInputPtr input = ctxt->input;
pcercuei 0:03b5121a232e 5407 SHRINK;
pcercuei 0:03b5121a232e 5408 SKIP(10);
pcercuei 0:03b5121a232e 5409 if (!IS_BLANK_CH(CUR)) {
pcercuei 0:03b5121a232e 5410 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
pcercuei 0:03b5121a232e 5411 "Space required after '<!NOTATION'\n");
pcercuei 0:03b5121a232e 5412 return;
pcercuei 0:03b5121a232e 5413 }
pcercuei 0:03b5121a232e 5414 SKIP_BLANKS;
pcercuei 0:03b5121a232e 5415
pcercuei 0:03b5121a232e 5416 name = xmlParseName(ctxt);
pcercuei 0:03b5121a232e 5417 if (name == NULL) {
pcercuei 0:03b5121a232e 5418 xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
pcercuei 0:03b5121a232e 5419 return;
pcercuei 0:03b5121a232e 5420 }
pcercuei 0:03b5121a232e 5421 if (!IS_BLANK_CH(CUR)) {
pcercuei 0:03b5121a232e 5422 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
pcercuei 0:03b5121a232e 5423 "Space required after the NOTATION name'\n");
pcercuei 0:03b5121a232e 5424 return;
pcercuei 0:03b5121a232e 5425 }
pcercuei 0:03b5121a232e 5426 if (xmlStrchr(name, ':') != NULL) {
pcercuei 0:03b5121a232e 5427 xmlNsErr(ctxt, XML_NS_ERR_COLON,
pcercuei 0:03b5121a232e 5428 "colons are forbidden from notation names '%s'\n",
pcercuei 0:03b5121a232e 5429 name, NULL, NULL);
pcercuei 0:03b5121a232e 5430 }
pcercuei 0:03b5121a232e 5431 SKIP_BLANKS;
pcercuei 0:03b5121a232e 5432
pcercuei 0:03b5121a232e 5433 /*
pcercuei 0:03b5121a232e 5434 * Parse the IDs.
pcercuei 0:03b5121a232e 5435 */
pcercuei 0:03b5121a232e 5436 Systemid = xmlParseExternalID(ctxt, &Pubid, 0);
pcercuei 0:03b5121a232e 5437 SKIP_BLANKS;
pcercuei 0:03b5121a232e 5438
pcercuei 0:03b5121a232e 5439 if (RAW == '>') {
pcercuei 0:03b5121a232e 5440 if (input != ctxt->input) {
pcercuei 0:03b5121a232e 5441 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
pcercuei 0:03b5121a232e 5442 "Notation declaration doesn't start and stop in the same entity\n");
pcercuei 0:03b5121a232e 5443 }
pcercuei 0:03b5121a232e 5444 NEXT;
pcercuei 0:03b5121a232e 5445 if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
pcercuei 0:03b5121a232e 5446 (ctxt->sax->notationDecl != NULL))
pcercuei 0:03b5121a232e 5447 ctxt->sax->notationDecl(ctxt->userData, name, Pubid, Systemid);
pcercuei 0:03b5121a232e 5448 } else {
pcercuei 0:03b5121a232e 5449 xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
pcercuei 0:03b5121a232e 5450 }
pcercuei 0:03b5121a232e 5451 if (Systemid != NULL) xmlFree(Systemid);
pcercuei 0:03b5121a232e 5452 if (Pubid != NULL) xmlFree(Pubid);
pcercuei 0:03b5121a232e 5453 }
pcercuei 0:03b5121a232e 5454 }
pcercuei 0:03b5121a232e 5455
pcercuei 0:03b5121a232e 5456 /**
pcercuei 0:03b5121a232e 5457 * xmlParseEntityDecl:
pcercuei 0:03b5121a232e 5458 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 5459 *
pcercuei 0:03b5121a232e 5460 * parse <!ENTITY declarations
pcercuei 0:03b5121a232e 5461 *
pcercuei 0:03b5121a232e 5462 * [70] EntityDecl ::= GEDecl | PEDecl
pcercuei 0:03b5121a232e 5463 *
pcercuei 0:03b5121a232e 5464 * [71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
pcercuei 0:03b5121a232e 5465 *
pcercuei 0:03b5121a232e 5466 * [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
pcercuei 0:03b5121a232e 5467 *
pcercuei 0:03b5121a232e 5468 * [73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)
pcercuei 0:03b5121a232e 5469 *
pcercuei 0:03b5121a232e 5470 * [74] PEDef ::= EntityValue | ExternalID
pcercuei 0:03b5121a232e 5471 *
pcercuei 0:03b5121a232e 5472 * [76] NDataDecl ::= S 'NDATA' S Name
pcercuei 0:03b5121a232e 5473 *
pcercuei 0:03b5121a232e 5474 * [ VC: Notation Declared ]
pcercuei 0:03b5121a232e 5475 * The Name must match the declared name of a notation.
pcercuei 0:03b5121a232e 5476 */
pcercuei 0:03b5121a232e 5477
pcercuei 0:03b5121a232e 5478 void
pcercuei 0:03b5121a232e 5479 xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 5480 const xmlChar *name = NULL;
pcercuei 0:03b5121a232e 5481 xmlChar *value = NULL;
pcercuei 0:03b5121a232e 5482 xmlChar *URI = NULL, *literal = NULL;
pcercuei 0:03b5121a232e 5483 const xmlChar *ndata = NULL;
pcercuei 0:03b5121a232e 5484 int isParameter = 0;
pcercuei 0:03b5121a232e 5485 xmlChar *orig = NULL;
pcercuei 0:03b5121a232e 5486 int skipped;
pcercuei 0:03b5121a232e 5487
pcercuei 0:03b5121a232e 5488 /* GROW; done in the caller */
pcercuei 0:03b5121a232e 5489 if (CMP8(CUR_PTR, '<', '!', 'E', 'N', 'T', 'I', 'T', 'Y')) {
pcercuei 0:03b5121a232e 5490 xmlParserInputPtr input = ctxt->input;
pcercuei 0:03b5121a232e 5491 SHRINK;
pcercuei 0:03b5121a232e 5492 SKIP(8);
pcercuei 0:03b5121a232e 5493 skipped = SKIP_BLANKS;
pcercuei 0:03b5121a232e 5494 if (skipped == 0) {
pcercuei 0:03b5121a232e 5495 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
pcercuei 0:03b5121a232e 5496 "Space required after '<!ENTITY'\n");
pcercuei 0:03b5121a232e 5497 }
pcercuei 0:03b5121a232e 5498
pcercuei 0:03b5121a232e 5499 if (RAW == '%') {
pcercuei 0:03b5121a232e 5500 NEXT;
pcercuei 0:03b5121a232e 5501 skipped = SKIP_BLANKS;
pcercuei 0:03b5121a232e 5502 if (skipped == 0) {
pcercuei 0:03b5121a232e 5503 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
pcercuei 0:03b5121a232e 5504 "Space required after '%'\n");
pcercuei 0:03b5121a232e 5505 }
pcercuei 0:03b5121a232e 5506 isParameter = 1;
pcercuei 0:03b5121a232e 5507 }
pcercuei 0:03b5121a232e 5508
pcercuei 0:03b5121a232e 5509 name = xmlParseName(ctxt);
pcercuei 0:03b5121a232e 5510 if (name == NULL) {
pcercuei 0:03b5121a232e 5511 xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
pcercuei 0:03b5121a232e 5512 "xmlParseEntityDecl: no name\n");
pcercuei 0:03b5121a232e 5513 return;
pcercuei 0:03b5121a232e 5514 }
pcercuei 0:03b5121a232e 5515 if (xmlStrchr(name, ':') != NULL) {
pcercuei 0:03b5121a232e 5516 xmlNsErr(ctxt, XML_NS_ERR_COLON,
pcercuei 0:03b5121a232e 5517 "colons are forbidden from entities names '%s'\n",
pcercuei 0:03b5121a232e 5518 name, NULL, NULL);
pcercuei 0:03b5121a232e 5519 }
pcercuei 0:03b5121a232e 5520 skipped = SKIP_BLANKS;
pcercuei 0:03b5121a232e 5521 if (skipped == 0) {
pcercuei 0:03b5121a232e 5522 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
pcercuei 0:03b5121a232e 5523 "Space required after the entity name\n");
pcercuei 0:03b5121a232e 5524 }
pcercuei 0:03b5121a232e 5525
pcercuei 0:03b5121a232e 5526 ctxt->instate = XML_PARSER_ENTITY_DECL;
pcercuei 0:03b5121a232e 5527 /*
pcercuei 0:03b5121a232e 5528 * handle the various case of definitions...
pcercuei 0:03b5121a232e 5529 */
pcercuei 0:03b5121a232e 5530 if (isParameter) {
pcercuei 0:03b5121a232e 5531 if ((RAW == '"') || (RAW == '\'')) {
pcercuei 0:03b5121a232e 5532 value = xmlParseEntityValue(ctxt, &orig);
pcercuei 0:03b5121a232e 5533 if (value) {
pcercuei 0:03b5121a232e 5534 if ((ctxt->sax != NULL) &&
pcercuei 0:03b5121a232e 5535 (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
pcercuei 0:03b5121a232e 5536 ctxt->sax->entityDecl(ctxt->userData, name,
pcercuei 0:03b5121a232e 5537 XML_INTERNAL_PARAMETER_ENTITY,
pcercuei 0:03b5121a232e 5538 NULL, NULL, value);
pcercuei 0:03b5121a232e 5539 }
pcercuei 0:03b5121a232e 5540 } else {
pcercuei 0:03b5121a232e 5541 URI = xmlParseExternalID(ctxt, &literal, 1);
pcercuei 0:03b5121a232e 5542 if ((URI == NULL) && (literal == NULL)) {
pcercuei 0:03b5121a232e 5543 xmlFatalErr(ctxt, XML_ERR_VALUE_REQUIRED, NULL);
pcercuei 0:03b5121a232e 5544 }
pcercuei 0:03b5121a232e 5545 if (URI) {
pcercuei 0:03b5121a232e 5546 xmlURIPtr uri;
pcercuei 0:03b5121a232e 5547
pcercuei 0:03b5121a232e 5548 uri = xmlParseURI((const char *) URI);
pcercuei 0:03b5121a232e 5549 if (uri == NULL) {
pcercuei 0:03b5121a232e 5550 xmlErrMsgStr(ctxt, XML_ERR_INVALID_URI,
pcercuei 0:03b5121a232e 5551 "Invalid URI: %s\n", URI);
pcercuei 0:03b5121a232e 5552 /*
pcercuei 0:03b5121a232e 5553 * This really ought to be a well formedness error
pcercuei 0:03b5121a232e 5554 * but the XML Core WG decided otherwise c.f. issue
pcercuei 0:03b5121a232e 5555 * E26 of the XML erratas.
pcercuei 0:03b5121a232e 5556 */
pcercuei 0:03b5121a232e 5557 } else {
pcercuei 0:03b5121a232e 5558 if (uri->fragment != NULL) {
pcercuei 0:03b5121a232e 5559 /*
pcercuei 0:03b5121a232e 5560 * Okay this is foolish to block those but not
pcercuei 0:03b5121a232e 5561 * invalid URIs.
pcercuei 0:03b5121a232e 5562 */
pcercuei 0:03b5121a232e 5563 xmlFatalErr(ctxt, XML_ERR_URI_FRAGMENT, NULL);
pcercuei 0:03b5121a232e 5564 } else {
pcercuei 0:03b5121a232e 5565 if ((ctxt->sax != NULL) &&
pcercuei 0:03b5121a232e 5566 (!ctxt->disableSAX) &&
pcercuei 0:03b5121a232e 5567 (ctxt->sax->entityDecl != NULL))
pcercuei 0:03b5121a232e 5568 ctxt->sax->entityDecl(ctxt->userData, name,
pcercuei 0:03b5121a232e 5569 XML_EXTERNAL_PARAMETER_ENTITY,
pcercuei 0:03b5121a232e 5570 literal, URI, NULL);
pcercuei 0:03b5121a232e 5571 }
pcercuei 0:03b5121a232e 5572 xmlFreeURI(uri);
pcercuei 0:03b5121a232e 5573 }
pcercuei 0:03b5121a232e 5574 }
pcercuei 0:03b5121a232e 5575 }
pcercuei 0:03b5121a232e 5576 } else {
pcercuei 0:03b5121a232e 5577 if ((RAW == '"') || (RAW == '\'')) {
pcercuei 0:03b5121a232e 5578 value = xmlParseEntityValue(ctxt, &orig);
pcercuei 0:03b5121a232e 5579 if ((ctxt->sax != NULL) &&
pcercuei 0:03b5121a232e 5580 (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
pcercuei 0:03b5121a232e 5581 ctxt->sax->entityDecl(ctxt->userData, name,
pcercuei 0:03b5121a232e 5582 XML_INTERNAL_GENERAL_ENTITY,
pcercuei 0:03b5121a232e 5583 NULL, NULL, value);
pcercuei 0:03b5121a232e 5584 /*
pcercuei 0:03b5121a232e 5585 * For expat compatibility in SAX mode.
pcercuei 0:03b5121a232e 5586 */
pcercuei 0:03b5121a232e 5587 if ((ctxt->myDoc == NULL) ||
pcercuei 0:03b5121a232e 5588 (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) {
pcercuei 0:03b5121a232e 5589 if (ctxt->myDoc == NULL) {
pcercuei 0:03b5121a232e 5590 ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
pcercuei 0:03b5121a232e 5591 if (ctxt->myDoc == NULL) {
pcercuei 0:03b5121a232e 5592 xmlErrMemory(ctxt, "New Doc failed");
pcercuei 0:03b5121a232e 5593 return;
pcercuei 0:03b5121a232e 5594 }
pcercuei 0:03b5121a232e 5595 ctxt->myDoc->properties = XML_DOC_INTERNAL;
pcercuei 0:03b5121a232e 5596 }
pcercuei 0:03b5121a232e 5597 if (ctxt->myDoc->intSubset == NULL)
pcercuei 0:03b5121a232e 5598 ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
pcercuei 0:03b5121a232e 5599 BAD_CAST "fake", NULL, NULL);
pcercuei 0:03b5121a232e 5600
pcercuei 0:03b5121a232e 5601 xmlSAX2EntityDecl(ctxt, name, XML_INTERNAL_GENERAL_ENTITY,
pcercuei 0:03b5121a232e 5602 NULL, NULL, value);
pcercuei 0:03b5121a232e 5603 }
pcercuei 0:03b5121a232e 5604 } else {
pcercuei 0:03b5121a232e 5605 URI = xmlParseExternalID(ctxt, &literal, 1);
pcercuei 0:03b5121a232e 5606 if ((URI == NULL) && (literal == NULL)) {
pcercuei 0:03b5121a232e 5607 xmlFatalErr(ctxt, XML_ERR_VALUE_REQUIRED, NULL);
pcercuei 0:03b5121a232e 5608 }
pcercuei 0:03b5121a232e 5609 if (URI) {
pcercuei 0:03b5121a232e 5610 xmlURIPtr uri;
pcercuei 0:03b5121a232e 5611
pcercuei 0:03b5121a232e 5612 uri = xmlParseURI((const char *)URI);
pcercuei 0:03b5121a232e 5613 if (uri == NULL) {
pcercuei 0:03b5121a232e 5614 xmlErrMsgStr(ctxt, XML_ERR_INVALID_URI,
pcercuei 0:03b5121a232e 5615 "Invalid URI: %s\n", URI);
pcercuei 0:03b5121a232e 5616 /*
pcercuei 0:03b5121a232e 5617 * This really ought to be a well formedness error
pcercuei 0:03b5121a232e 5618 * but the XML Core WG decided otherwise c.f. issue
pcercuei 0:03b5121a232e 5619 * E26 of the XML erratas.
pcercuei 0:03b5121a232e 5620 */
pcercuei 0:03b5121a232e 5621 } else {
pcercuei 0:03b5121a232e 5622 if (uri->fragment != NULL) {
pcercuei 0:03b5121a232e 5623 /*
pcercuei 0:03b5121a232e 5624 * Okay this is foolish to block those but not
pcercuei 0:03b5121a232e 5625 * invalid URIs.
pcercuei 0:03b5121a232e 5626 */
pcercuei 0:03b5121a232e 5627 xmlFatalErr(ctxt, XML_ERR_URI_FRAGMENT, NULL);
pcercuei 0:03b5121a232e 5628 }
pcercuei 0:03b5121a232e 5629 xmlFreeURI(uri);
pcercuei 0:03b5121a232e 5630 }
pcercuei 0:03b5121a232e 5631 }
pcercuei 0:03b5121a232e 5632 if ((RAW != '>') && (!IS_BLANK_CH(CUR))) {
pcercuei 0:03b5121a232e 5633 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
pcercuei 0:03b5121a232e 5634 "Space required before 'NDATA'\n");
pcercuei 0:03b5121a232e 5635 }
pcercuei 0:03b5121a232e 5636 SKIP_BLANKS;
pcercuei 0:03b5121a232e 5637 if (CMP5(CUR_PTR, 'N', 'D', 'A', 'T', 'A')) {
pcercuei 0:03b5121a232e 5638 SKIP(5);
pcercuei 0:03b5121a232e 5639 if (!IS_BLANK_CH(CUR)) {
pcercuei 0:03b5121a232e 5640 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
pcercuei 0:03b5121a232e 5641 "Space required after 'NDATA'\n");
pcercuei 0:03b5121a232e 5642 }
pcercuei 0:03b5121a232e 5643 SKIP_BLANKS;
pcercuei 0:03b5121a232e 5644 ndata = xmlParseName(ctxt);
pcercuei 0:03b5121a232e 5645 if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
pcercuei 0:03b5121a232e 5646 (ctxt->sax->unparsedEntityDecl != NULL))
pcercuei 0:03b5121a232e 5647 ctxt->sax->unparsedEntityDecl(ctxt->userData, name,
pcercuei 0:03b5121a232e 5648 literal, URI, ndata);
pcercuei 0:03b5121a232e 5649 } else {
pcercuei 0:03b5121a232e 5650 if ((ctxt->sax != NULL) &&
pcercuei 0:03b5121a232e 5651 (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
pcercuei 0:03b5121a232e 5652 ctxt->sax->entityDecl(ctxt->userData, name,
pcercuei 0:03b5121a232e 5653 XML_EXTERNAL_GENERAL_PARSED_ENTITY,
pcercuei 0:03b5121a232e 5654 literal, URI, NULL);
pcercuei 0:03b5121a232e 5655 /*
pcercuei 0:03b5121a232e 5656 * For expat compatibility in SAX mode.
pcercuei 0:03b5121a232e 5657 * assuming the entity repalcement was asked for
pcercuei 0:03b5121a232e 5658 */
pcercuei 0:03b5121a232e 5659 if ((ctxt->replaceEntities != 0) &&
pcercuei 0:03b5121a232e 5660 ((ctxt->myDoc == NULL) ||
pcercuei 0:03b5121a232e 5661 (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE)))) {
pcercuei 0:03b5121a232e 5662 if (ctxt->myDoc == NULL) {
pcercuei 0:03b5121a232e 5663 ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
pcercuei 0:03b5121a232e 5664 if (ctxt->myDoc == NULL) {
pcercuei 0:03b5121a232e 5665 xmlErrMemory(ctxt, "New Doc failed");
pcercuei 0:03b5121a232e 5666 return;
pcercuei 0:03b5121a232e 5667 }
pcercuei 0:03b5121a232e 5668 ctxt->myDoc->properties = XML_DOC_INTERNAL;
pcercuei 0:03b5121a232e 5669 }
pcercuei 0:03b5121a232e 5670
pcercuei 0:03b5121a232e 5671 if (ctxt->myDoc->intSubset == NULL)
pcercuei 0:03b5121a232e 5672 ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
pcercuei 0:03b5121a232e 5673 BAD_CAST "fake", NULL, NULL);
pcercuei 0:03b5121a232e 5674 xmlSAX2EntityDecl(ctxt, name,
pcercuei 0:03b5121a232e 5675 XML_EXTERNAL_GENERAL_PARSED_ENTITY,
pcercuei 0:03b5121a232e 5676 literal, URI, NULL);
pcercuei 0:03b5121a232e 5677 }
pcercuei 0:03b5121a232e 5678 }
pcercuei 0:03b5121a232e 5679 }
pcercuei 0:03b5121a232e 5680 }
pcercuei 0:03b5121a232e 5681 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 5682 return;
pcercuei 0:03b5121a232e 5683 SKIP_BLANKS;
pcercuei 0:03b5121a232e 5684 if (RAW != '>') {
pcercuei 0:03b5121a232e 5685 xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_NOT_FINISHED,
pcercuei 0:03b5121a232e 5686 "xmlParseEntityDecl: entity %s not terminated\n", name);
pcercuei 0:03b5121a232e 5687 xmlHaltParser(ctxt);
pcercuei 0:03b5121a232e 5688 } else {
pcercuei 0:03b5121a232e 5689 if (input != ctxt->input) {
pcercuei 0:03b5121a232e 5690 xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
pcercuei 0:03b5121a232e 5691 "Entity declaration doesn't start and stop in the same entity\n");
pcercuei 0:03b5121a232e 5692 }
pcercuei 0:03b5121a232e 5693 NEXT;
pcercuei 0:03b5121a232e 5694 }
pcercuei 0:03b5121a232e 5695 if (orig != NULL) {
pcercuei 0:03b5121a232e 5696 /*
pcercuei 0:03b5121a232e 5697 * Ugly mechanism to save the raw entity value.
pcercuei 0:03b5121a232e 5698 */
pcercuei 0:03b5121a232e 5699 xmlEntityPtr cur = NULL;
pcercuei 0:03b5121a232e 5700
pcercuei 0:03b5121a232e 5701 if (isParameter) {
pcercuei 0:03b5121a232e 5702 if ((ctxt->sax != NULL) &&
pcercuei 0:03b5121a232e 5703 (ctxt->sax->getParameterEntity != NULL))
pcercuei 0:03b5121a232e 5704 cur = ctxt->sax->getParameterEntity(ctxt->userData, name);
pcercuei 0:03b5121a232e 5705 } else {
pcercuei 0:03b5121a232e 5706 if ((ctxt->sax != NULL) &&
pcercuei 0:03b5121a232e 5707 (ctxt->sax->getEntity != NULL))
pcercuei 0:03b5121a232e 5708 cur = ctxt->sax->getEntity(ctxt->userData, name);
pcercuei 0:03b5121a232e 5709 if ((cur == NULL) && (ctxt->userData==ctxt)) {
pcercuei 0:03b5121a232e 5710 cur = xmlSAX2GetEntity(ctxt, name);
pcercuei 0:03b5121a232e 5711 }
pcercuei 0:03b5121a232e 5712 }
pcercuei 0:03b5121a232e 5713 if (cur != NULL) {
pcercuei 0:03b5121a232e 5714 if (cur->orig != NULL)
pcercuei 0:03b5121a232e 5715 xmlFree(orig);
pcercuei 0:03b5121a232e 5716 else
pcercuei 0:03b5121a232e 5717 cur->orig = orig;
pcercuei 0:03b5121a232e 5718 } else
pcercuei 0:03b5121a232e 5719 xmlFree(orig);
pcercuei 0:03b5121a232e 5720 }
pcercuei 0:03b5121a232e 5721 if (value != NULL) xmlFree(value);
pcercuei 0:03b5121a232e 5722 if (URI != NULL) xmlFree(URI);
pcercuei 0:03b5121a232e 5723 if (literal != NULL) xmlFree(literal);
pcercuei 0:03b5121a232e 5724 }
pcercuei 0:03b5121a232e 5725 }
pcercuei 0:03b5121a232e 5726
pcercuei 0:03b5121a232e 5727 /**
pcercuei 0:03b5121a232e 5728 * xmlParseDefaultDecl:
pcercuei 0:03b5121a232e 5729 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 5730 * @value: Receive a possible fixed default value for the attribute
pcercuei 0:03b5121a232e 5731 *
pcercuei 0:03b5121a232e 5732 * Parse an attribute default declaration
pcercuei 0:03b5121a232e 5733 *
pcercuei 0:03b5121a232e 5734 * [60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)
pcercuei 0:03b5121a232e 5735 *
pcercuei 0:03b5121a232e 5736 * [ VC: Required Attribute ]
pcercuei 0:03b5121a232e 5737 * if the default declaration is the keyword #REQUIRED, then the
pcercuei 0:03b5121a232e 5738 * attribute must be specified for all elements of the type in the
pcercuei 0:03b5121a232e 5739 * attribute-list declaration.
pcercuei 0:03b5121a232e 5740 *
pcercuei 0:03b5121a232e 5741 * [ VC: Attribute Default Legal ]
pcercuei 0:03b5121a232e 5742 * The declared default value must meet the lexical constraints of
pcercuei 0:03b5121a232e 5743 * the declared attribute type c.f. xmlValidateAttributeDecl()
pcercuei 0:03b5121a232e 5744 *
pcercuei 0:03b5121a232e 5745 * [ VC: Fixed Attribute Default ]
pcercuei 0:03b5121a232e 5746 * if an attribute has a default value declared with the #FIXED
pcercuei 0:03b5121a232e 5747 * keyword, instances of that attribute must match the default value.
pcercuei 0:03b5121a232e 5748 *
pcercuei 0:03b5121a232e 5749 * [ WFC: No < in Attribute Values ]
pcercuei 0:03b5121a232e 5750 * handled in xmlParseAttValue()
pcercuei 0:03b5121a232e 5751 *
pcercuei 0:03b5121a232e 5752 * returns: XML_ATTRIBUTE_NONE, XML_ATTRIBUTE_REQUIRED, XML_ATTRIBUTE_IMPLIED
pcercuei 0:03b5121a232e 5753 * or XML_ATTRIBUTE_FIXED.
pcercuei 0:03b5121a232e 5754 */
pcercuei 0:03b5121a232e 5755
pcercuei 0:03b5121a232e 5756 int
pcercuei 0:03b5121a232e 5757 xmlParseDefaultDecl(xmlParserCtxtPtr ctxt, xmlChar **value) {
pcercuei 0:03b5121a232e 5758 int val;
pcercuei 0:03b5121a232e 5759 xmlChar *ret;
pcercuei 0:03b5121a232e 5760
pcercuei 0:03b5121a232e 5761 *value = NULL;
pcercuei 0:03b5121a232e 5762 if (CMP9(CUR_PTR, '#', 'R', 'E', 'Q', 'U', 'I', 'R', 'E', 'D')) {
pcercuei 0:03b5121a232e 5763 SKIP(9);
pcercuei 0:03b5121a232e 5764 return(XML_ATTRIBUTE_REQUIRED);
pcercuei 0:03b5121a232e 5765 }
pcercuei 0:03b5121a232e 5766 if (CMP8(CUR_PTR, '#', 'I', 'M', 'P', 'L', 'I', 'E', 'D')) {
pcercuei 0:03b5121a232e 5767 SKIP(8);
pcercuei 0:03b5121a232e 5768 return(XML_ATTRIBUTE_IMPLIED);
pcercuei 0:03b5121a232e 5769 }
pcercuei 0:03b5121a232e 5770 val = XML_ATTRIBUTE_NONE;
pcercuei 0:03b5121a232e 5771 if (CMP6(CUR_PTR, '#', 'F', 'I', 'X', 'E', 'D')) {
pcercuei 0:03b5121a232e 5772 SKIP(6);
pcercuei 0:03b5121a232e 5773 val = XML_ATTRIBUTE_FIXED;
pcercuei 0:03b5121a232e 5774 if (!IS_BLANK_CH(CUR)) {
pcercuei 0:03b5121a232e 5775 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
pcercuei 0:03b5121a232e 5776 "Space required after '#FIXED'\n");
pcercuei 0:03b5121a232e 5777 }
pcercuei 0:03b5121a232e 5778 SKIP_BLANKS;
pcercuei 0:03b5121a232e 5779 }
pcercuei 0:03b5121a232e 5780 ret = xmlParseAttValue(ctxt);
pcercuei 0:03b5121a232e 5781 ctxt->instate = XML_PARSER_DTD;
pcercuei 0:03b5121a232e 5782 if (ret == NULL) {
pcercuei 0:03b5121a232e 5783 xmlFatalErrMsg(ctxt, (xmlParserErrors)ctxt->errNo,
pcercuei 0:03b5121a232e 5784 "Attribute default value declaration error\n");
pcercuei 0:03b5121a232e 5785 } else
pcercuei 0:03b5121a232e 5786 *value = ret;
pcercuei 0:03b5121a232e 5787 return(val);
pcercuei 0:03b5121a232e 5788 }
pcercuei 0:03b5121a232e 5789
pcercuei 0:03b5121a232e 5790 /**
pcercuei 0:03b5121a232e 5791 * xmlParseNotationType:
pcercuei 0:03b5121a232e 5792 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 5793 *
pcercuei 0:03b5121a232e 5794 * parse an Notation attribute type.
pcercuei 0:03b5121a232e 5795 *
pcercuei 0:03b5121a232e 5796 * Note: the leading 'NOTATION' S part has already being parsed...
pcercuei 0:03b5121a232e 5797 *
pcercuei 0:03b5121a232e 5798 * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
pcercuei 0:03b5121a232e 5799 *
pcercuei 0:03b5121a232e 5800 * [ VC: Notation Attributes ]
pcercuei 0:03b5121a232e 5801 * Values of this type must match one of the notation names included
pcercuei 0:03b5121a232e 5802 * in the declaration; all notation names in the declaration must be declared.
pcercuei 0:03b5121a232e 5803 *
pcercuei 0:03b5121a232e 5804 * Returns: the notation attribute tree built while parsing
pcercuei 0:03b5121a232e 5805 */
pcercuei 0:03b5121a232e 5806
pcercuei 0:03b5121a232e 5807 xmlEnumerationPtr
pcercuei 0:03b5121a232e 5808 xmlParseNotationType(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 5809 const xmlChar *name;
pcercuei 0:03b5121a232e 5810 xmlEnumerationPtr ret = NULL, last = NULL, cur, tmp;
pcercuei 0:03b5121a232e 5811
pcercuei 0:03b5121a232e 5812 if (RAW != '(') {
pcercuei 0:03b5121a232e 5813 xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
pcercuei 0:03b5121a232e 5814 return(NULL);
pcercuei 0:03b5121a232e 5815 }
pcercuei 0:03b5121a232e 5816 SHRINK;
pcercuei 0:03b5121a232e 5817 do {
pcercuei 0:03b5121a232e 5818 NEXT;
pcercuei 0:03b5121a232e 5819 SKIP_BLANKS;
pcercuei 0:03b5121a232e 5820 name = xmlParseName(ctxt);
pcercuei 0:03b5121a232e 5821 if (name == NULL) {
pcercuei 0:03b5121a232e 5822 xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
pcercuei 0:03b5121a232e 5823 "Name expected in NOTATION declaration\n");
pcercuei 0:03b5121a232e 5824 xmlFreeEnumeration(ret);
pcercuei 0:03b5121a232e 5825 return(NULL);
pcercuei 0:03b5121a232e 5826 }
pcercuei 0:03b5121a232e 5827 tmp = ret;
pcercuei 0:03b5121a232e 5828 while (tmp != NULL) {
pcercuei 0:03b5121a232e 5829 if (xmlStrEqual(name, tmp->name)) {
pcercuei 0:03b5121a232e 5830 xmlValidityError(ctxt, XML_DTD_DUP_TOKEN,
pcercuei 0:03b5121a232e 5831 "standalone: attribute notation value token %s duplicated\n",
pcercuei 0:03b5121a232e 5832 name, NULL);
pcercuei 0:03b5121a232e 5833 if (!xmlDictOwns(ctxt->dict, name))
pcercuei 0:03b5121a232e 5834 xmlFree((xmlChar *) name);
pcercuei 0:03b5121a232e 5835 break;
pcercuei 0:03b5121a232e 5836 }
pcercuei 0:03b5121a232e 5837 tmp = tmp->next;
pcercuei 0:03b5121a232e 5838 }
pcercuei 0:03b5121a232e 5839 if (tmp == NULL) {
pcercuei 0:03b5121a232e 5840 cur = xmlCreateEnumeration(name);
pcercuei 0:03b5121a232e 5841 if (cur == NULL) {
pcercuei 0:03b5121a232e 5842 xmlFreeEnumeration(ret);
pcercuei 0:03b5121a232e 5843 return(NULL);
pcercuei 0:03b5121a232e 5844 }
pcercuei 0:03b5121a232e 5845 if (last == NULL) ret = last = cur;
pcercuei 0:03b5121a232e 5846 else {
pcercuei 0:03b5121a232e 5847 last->next = cur;
pcercuei 0:03b5121a232e 5848 last = cur;
pcercuei 0:03b5121a232e 5849 }
pcercuei 0:03b5121a232e 5850 }
pcercuei 0:03b5121a232e 5851 SKIP_BLANKS;
pcercuei 0:03b5121a232e 5852 } while (RAW == '|');
pcercuei 0:03b5121a232e 5853 if (RAW != ')') {
pcercuei 0:03b5121a232e 5854 xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
pcercuei 0:03b5121a232e 5855 xmlFreeEnumeration(ret);
pcercuei 0:03b5121a232e 5856 return(NULL);
pcercuei 0:03b5121a232e 5857 }
pcercuei 0:03b5121a232e 5858 NEXT;
pcercuei 0:03b5121a232e 5859 return(ret);
pcercuei 0:03b5121a232e 5860 }
pcercuei 0:03b5121a232e 5861
pcercuei 0:03b5121a232e 5862 /**
pcercuei 0:03b5121a232e 5863 * xmlParseEnumerationType:
pcercuei 0:03b5121a232e 5864 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 5865 *
pcercuei 0:03b5121a232e 5866 * parse an Enumeration attribute type.
pcercuei 0:03b5121a232e 5867 *
pcercuei 0:03b5121a232e 5868 * [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
pcercuei 0:03b5121a232e 5869 *
pcercuei 0:03b5121a232e 5870 * [ VC: Enumeration ]
pcercuei 0:03b5121a232e 5871 * Values of this type must match one of the Nmtoken tokens in
pcercuei 0:03b5121a232e 5872 * the declaration
pcercuei 0:03b5121a232e 5873 *
pcercuei 0:03b5121a232e 5874 * Returns: the enumeration attribute tree built while parsing
pcercuei 0:03b5121a232e 5875 */
pcercuei 0:03b5121a232e 5876
pcercuei 0:03b5121a232e 5877 xmlEnumerationPtr
pcercuei 0:03b5121a232e 5878 xmlParseEnumerationType(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 5879 xmlChar *name;
pcercuei 0:03b5121a232e 5880 xmlEnumerationPtr ret = NULL, last = NULL, cur, tmp;
pcercuei 0:03b5121a232e 5881
pcercuei 0:03b5121a232e 5882 if (RAW != '(') {
pcercuei 0:03b5121a232e 5883 xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_STARTED, NULL);
pcercuei 0:03b5121a232e 5884 return(NULL);
pcercuei 0:03b5121a232e 5885 }
pcercuei 0:03b5121a232e 5886 SHRINK;
pcercuei 0:03b5121a232e 5887 do {
pcercuei 0:03b5121a232e 5888 NEXT;
pcercuei 0:03b5121a232e 5889 SKIP_BLANKS;
pcercuei 0:03b5121a232e 5890 name = xmlParseNmtoken(ctxt);
pcercuei 0:03b5121a232e 5891 if (name == NULL) {
pcercuei 0:03b5121a232e 5892 xmlFatalErr(ctxt, XML_ERR_NMTOKEN_REQUIRED, NULL);
pcercuei 0:03b5121a232e 5893 return(ret);
pcercuei 0:03b5121a232e 5894 }
pcercuei 0:03b5121a232e 5895 tmp = ret;
pcercuei 0:03b5121a232e 5896 while (tmp != NULL) {
pcercuei 0:03b5121a232e 5897 if (xmlStrEqual(name, tmp->name)) {
pcercuei 0:03b5121a232e 5898 xmlValidityError(ctxt, XML_DTD_DUP_TOKEN,
pcercuei 0:03b5121a232e 5899 "standalone: attribute enumeration value token %s duplicated\n",
pcercuei 0:03b5121a232e 5900 name, NULL);
pcercuei 0:03b5121a232e 5901 if (!xmlDictOwns(ctxt->dict, name))
pcercuei 0:03b5121a232e 5902 xmlFree(name);
pcercuei 0:03b5121a232e 5903 break;
pcercuei 0:03b5121a232e 5904 }
pcercuei 0:03b5121a232e 5905 tmp = tmp->next;
pcercuei 0:03b5121a232e 5906 }
pcercuei 0:03b5121a232e 5907 if (tmp == NULL) {
pcercuei 0:03b5121a232e 5908 cur = xmlCreateEnumeration(name);
pcercuei 0:03b5121a232e 5909 if (!xmlDictOwns(ctxt->dict, name))
pcercuei 0:03b5121a232e 5910 xmlFree(name);
pcercuei 0:03b5121a232e 5911 if (cur == NULL) {
pcercuei 0:03b5121a232e 5912 xmlFreeEnumeration(ret);
pcercuei 0:03b5121a232e 5913 return(NULL);
pcercuei 0:03b5121a232e 5914 }
pcercuei 0:03b5121a232e 5915 if (last == NULL) ret = last = cur;
pcercuei 0:03b5121a232e 5916 else {
pcercuei 0:03b5121a232e 5917 last->next = cur;
pcercuei 0:03b5121a232e 5918 last = cur;
pcercuei 0:03b5121a232e 5919 }
pcercuei 0:03b5121a232e 5920 }
pcercuei 0:03b5121a232e 5921 SKIP_BLANKS;
pcercuei 0:03b5121a232e 5922 } while (RAW == '|');
pcercuei 0:03b5121a232e 5923 if (RAW != ')') {
pcercuei 0:03b5121a232e 5924 xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_FINISHED, NULL);
pcercuei 0:03b5121a232e 5925 return(ret);
pcercuei 0:03b5121a232e 5926 }
pcercuei 0:03b5121a232e 5927 NEXT;
pcercuei 0:03b5121a232e 5928 return(ret);
pcercuei 0:03b5121a232e 5929 }
pcercuei 0:03b5121a232e 5930
pcercuei 0:03b5121a232e 5931 /**
pcercuei 0:03b5121a232e 5932 * xmlParseEnumeratedType:
pcercuei 0:03b5121a232e 5933 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 5934 * @tree: the enumeration tree built while parsing
pcercuei 0:03b5121a232e 5935 *
pcercuei 0:03b5121a232e 5936 * parse an Enumerated attribute type.
pcercuei 0:03b5121a232e 5937 *
pcercuei 0:03b5121a232e 5938 * [57] EnumeratedType ::= NotationType | Enumeration
pcercuei 0:03b5121a232e 5939 *
pcercuei 0:03b5121a232e 5940 * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
pcercuei 0:03b5121a232e 5941 *
pcercuei 0:03b5121a232e 5942 *
pcercuei 0:03b5121a232e 5943 * Returns: XML_ATTRIBUTE_ENUMERATION or XML_ATTRIBUTE_NOTATION
pcercuei 0:03b5121a232e 5944 */
pcercuei 0:03b5121a232e 5945
pcercuei 0:03b5121a232e 5946 int
pcercuei 0:03b5121a232e 5947 xmlParseEnumeratedType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
pcercuei 0:03b5121a232e 5948 if (CMP8(CUR_PTR, 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
pcercuei 0:03b5121a232e 5949 SKIP(8);
pcercuei 0:03b5121a232e 5950 if (!IS_BLANK_CH(CUR)) {
pcercuei 0:03b5121a232e 5951 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
pcercuei 0:03b5121a232e 5952 "Space required after 'NOTATION'\n");
pcercuei 0:03b5121a232e 5953 return(0);
pcercuei 0:03b5121a232e 5954 }
pcercuei 0:03b5121a232e 5955 SKIP_BLANKS;
pcercuei 0:03b5121a232e 5956 *tree = xmlParseNotationType(ctxt);
pcercuei 0:03b5121a232e 5957 if (*tree == NULL) return(0);
pcercuei 0:03b5121a232e 5958 return(XML_ATTRIBUTE_NOTATION);
pcercuei 0:03b5121a232e 5959 }
pcercuei 0:03b5121a232e 5960 *tree = xmlParseEnumerationType(ctxt);
pcercuei 0:03b5121a232e 5961 if (*tree == NULL) return(0);
pcercuei 0:03b5121a232e 5962 return(XML_ATTRIBUTE_ENUMERATION);
pcercuei 0:03b5121a232e 5963 }
pcercuei 0:03b5121a232e 5964
pcercuei 0:03b5121a232e 5965 /**
pcercuei 0:03b5121a232e 5966 * xmlParseAttributeType:
pcercuei 0:03b5121a232e 5967 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 5968 * @tree: the enumeration tree built while parsing
pcercuei 0:03b5121a232e 5969 *
pcercuei 0:03b5121a232e 5970 * parse the Attribute list def for an element
pcercuei 0:03b5121a232e 5971 *
pcercuei 0:03b5121a232e 5972 * [54] AttType ::= StringType | TokenizedType | EnumeratedType
pcercuei 0:03b5121a232e 5973 *
pcercuei 0:03b5121a232e 5974 * [55] StringType ::= 'CDATA'
pcercuei 0:03b5121a232e 5975 *
pcercuei 0:03b5121a232e 5976 * [56] TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' |
pcercuei 0:03b5121a232e 5977 * 'ENTITIES' | 'NMTOKEN' | 'NMTOKENS'
pcercuei 0:03b5121a232e 5978 *
pcercuei 0:03b5121a232e 5979 * Validity constraints for attribute values syntax are checked in
pcercuei 0:03b5121a232e 5980 * xmlValidateAttributeValue()
pcercuei 0:03b5121a232e 5981 *
pcercuei 0:03b5121a232e 5982 * [ VC: ID ]
pcercuei 0:03b5121a232e 5983 * Values of type ID must match the Name production. A name must not
pcercuei 0:03b5121a232e 5984 * appear more than once in an XML document as a value of this type;
pcercuei 0:03b5121a232e 5985 * i.e., ID values must uniquely identify the elements which bear them.
pcercuei 0:03b5121a232e 5986 *
pcercuei 0:03b5121a232e 5987 * [ VC: One ID per Element Type ]
pcercuei 0:03b5121a232e 5988 * No element type may have more than one ID attribute specified.
pcercuei 0:03b5121a232e 5989 *
pcercuei 0:03b5121a232e 5990 * [ VC: ID Attribute Default ]
pcercuei 0:03b5121a232e 5991 * An ID attribute must have a declared default of #IMPLIED or #REQUIRED.
pcercuei 0:03b5121a232e 5992 *
pcercuei 0:03b5121a232e 5993 * [ VC: IDREF ]
pcercuei 0:03b5121a232e 5994 * Values of type IDREF must match the Name production, and values
pcercuei 0:03b5121a232e 5995 * of type IDREFS must match Names; each IDREF Name must match the value
pcercuei 0:03b5121a232e 5996 * of an ID attribute on some element in the XML document; i.e. IDREF
pcercuei 0:03b5121a232e 5997 * values must match the value of some ID attribute.
pcercuei 0:03b5121a232e 5998 *
pcercuei 0:03b5121a232e 5999 * [ VC: Entity Name ]
pcercuei 0:03b5121a232e 6000 * Values of type ENTITY must match the Name production, values
pcercuei 0:03b5121a232e 6001 * of type ENTITIES must match Names; each Entity Name must match the
pcercuei 0:03b5121a232e 6002 * name of an unparsed entity declared in the DTD.
pcercuei 0:03b5121a232e 6003 *
pcercuei 0:03b5121a232e 6004 * [ VC: Name Token ]
pcercuei 0:03b5121a232e 6005 * Values of type NMTOKEN must match the Nmtoken production; values
pcercuei 0:03b5121a232e 6006 * of type NMTOKENS must match Nmtokens.
pcercuei 0:03b5121a232e 6007 *
pcercuei 0:03b5121a232e 6008 * Returns the attribute type
pcercuei 0:03b5121a232e 6009 */
pcercuei 0:03b5121a232e 6010 int
pcercuei 0:03b5121a232e 6011 xmlParseAttributeType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
pcercuei 0:03b5121a232e 6012 SHRINK;
pcercuei 0:03b5121a232e 6013 if (CMP5(CUR_PTR, 'C', 'D', 'A', 'T', 'A')) {
pcercuei 0:03b5121a232e 6014 SKIP(5);
pcercuei 0:03b5121a232e 6015 return(XML_ATTRIBUTE_CDATA);
pcercuei 0:03b5121a232e 6016 } else if (CMP6(CUR_PTR, 'I', 'D', 'R', 'E', 'F', 'S')) {
pcercuei 0:03b5121a232e 6017 SKIP(6);
pcercuei 0:03b5121a232e 6018 return(XML_ATTRIBUTE_IDREFS);
pcercuei 0:03b5121a232e 6019 } else if (CMP5(CUR_PTR, 'I', 'D', 'R', 'E', 'F')) {
pcercuei 0:03b5121a232e 6020 SKIP(5);
pcercuei 0:03b5121a232e 6021 return(XML_ATTRIBUTE_IDREF);
pcercuei 0:03b5121a232e 6022 } else if ((RAW == 'I') && (NXT(1) == 'D')) {
pcercuei 0:03b5121a232e 6023 SKIP(2);
pcercuei 0:03b5121a232e 6024 return(XML_ATTRIBUTE_ID);
pcercuei 0:03b5121a232e 6025 } else if (CMP6(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'Y')) {
pcercuei 0:03b5121a232e 6026 SKIP(6);
pcercuei 0:03b5121a232e 6027 return(XML_ATTRIBUTE_ENTITY);
pcercuei 0:03b5121a232e 6028 } else if (CMP8(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S')) {
pcercuei 0:03b5121a232e 6029 SKIP(8);
pcercuei 0:03b5121a232e 6030 return(XML_ATTRIBUTE_ENTITIES);
pcercuei 0:03b5121a232e 6031 } else if (CMP8(CUR_PTR, 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S')) {
pcercuei 0:03b5121a232e 6032 SKIP(8);
pcercuei 0:03b5121a232e 6033 return(XML_ATTRIBUTE_NMTOKENS);
pcercuei 0:03b5121a232e 6034 } else if (CMP7(CUR_PTR, 'N', 'M', 'T', 'O', 'K', 'E', 'N')) {
pcercuei 0:03b5121a232e 6035 SKIP(7);
pcercuei 0:03b5121a232e 6036 return(XML_ATTRIBUTE_NMTOKEN);
pcercuei 0:03b5121a232e 6037 }
pcercuei 0:03b5121a232e 6038 return(xmlParseEnumeratedType(ctxt, tree));
pcercuei 0:03b5121a232e 6039 }
pcercuei 0:03b5121a232e 6040
pcercuei 0:03b5121a232e 6041 /**
pcercuei 0:03b5121a232e 6042 * xmlParseAttributeListDecl:
pcercuei 0:03b5121a232e 6043 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 6044 *
pcercuei 0:03b5121a232e 6045 * : parse the Attribute list def for an element
pcercuei 0:03b5121a232e 6046 *
pcercuei 0:03b5121a232e 6047 * [52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
pcercuei 0:03b5121a232e 6048 *
pcercuei 0:03b5121a232e 6049 * [53] AttDef ::= S Name S AttType S DefaultDecl
pcercuei 0:03b5121a232e 6050 *
pcercuei 0:03b5121a232e 6051 */
pcercuei 0:03b5121a232e 6052 void
pcercuei 0:03b5121a232e 6053 xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 6054 const xmlChar *elemName;
pcercuei 0:03b5121a232e 6055 const xmlChar *attrName;
pcercuei 0:03b5121a232e 6056 xmlEnumerationPtr tree;
pcercuei 0:03b5121a232e 6057
pcercuei 0:03b5121a232e 6058 if (CMP9(CUR_PTR, '<', '!', 'A', 'T', 'T', 'L', 'I', 'S', 'T')) {
pcercuei 0:03b5121a232e 6059 xmlParserInputPtr input = ctxt->input;
pcercuei 0:03b5121a232e 6060
pcercuei 0:03b5121a232e 6061 SKIP(9);
pcercuei 0:03b5121a232e 6062 if (!IS_BLANK_CH(CUR)) {
pcercuei 0:03b5121a232e 6063 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
pcercuei 0:03b5121a232e 6064 "Space required after '<!ATTLIST'\n");
pcercuei 0:03b5121a232e 6065 }
pcercuei 0:03b5121a232e 6066 SKIP_BLANKS;
pcercuei 0:03b5121a232e 6067 elemName = xmlParseName(ctxt);
pcercuei 0:03b5121a232e 6068 if (elemName == NULL) {
pcercuei 0:03b5121a232e 6069 xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
pcercuei 0:03b5121a232e 6070 "ATTLIST: no name for Element\n");
pcercuei 0:03b5121a232e 6071 return;
pcercuei 0:03b5121a232e 6072 }
pcercuei 0:03b5121a232e 6073 SKIP_BLANKS;
pcercuei 0:03b5121a232e 6074 GROW;
pcercuei 0:03b5121a232e 6075 while ((RAW != '>') && (ctxt->instate != XML_PARSER_EOF)) {
pcercuei 0:03b5121a232e 6076 const xmlChar *check = CUR_PTR;
pcercuei 0:03b5121a232e 6077 int type;
pcercuei 0:03b5121a232e 6078 int def;
pcercuei 0:03b5121a232e 6079 xmlChar *defaultValue = NULL;
pcercuei 0:03b5121a232e 6080
pcercuei 0:03b5121a232e 6081 GROW;
pcercuei 0:03b5121a232e 6082 tree = NULL;
pcercuei 0:03b5121a232e 6083 attrName = xmlParseName(ctxt);
pcercuei 0:03b5121a232e 6084 if (attrName == NULL) {
pcercuei 0:03b5121a232e 6085 xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
pcercuei 0:03b5121a232e 6086 "ATTLIST: no name for Attribute\n");
pcercuei 0:03b5121a232e 6087 break;
pcercuei 0:03b5121a232e 6088 }
pcercuei 0:03b5121a232e 6089 GROW;
pcercuei 0:03b5121a232e 6090 if (!IS_BLANK_CH(CUR)) {
pcercuei 0:03b5121a232e 6091 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
pcercuei 0:03b5121a232e 6092 "Space required after the attribute name\n");
pcercuei 0:03b5121a232e 6093 break;
pcercuei 0:03b5121a232e 6094 }
pcercuei 0:03b5121a232e 6095 SKIP_BLANKS;
pcercuei 0:03b5121a232e 6096
pcercuei 0:03b5121a232e 6097 type = xmlParseAttributeType(ctxt, &tree);
pcercuei 0:03b5121a232e 6098 if (type <= 0) {
pcercuei 0:03b5121a232e 6099 break;
pcercuei 0:03b5121a232e 6100 }
pcercuei 0:03b5121a232e 6101
pcercuei 0:03b5121a232e 6102 GROW;
pcercuei 0:03b5121a232e 6103 if (!IS_BLANK_CH(CUR)) {
pcercuei 0:03b5121a232e 6104 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
pcercuei 0:03b5121a232e 6105 "Space required after the attribute type\n");
pcercuei 0:03b5121a232e 6106 if (tree != NULL)
pcercuei 0:03b5121a232e 6107 xmlFreeEnumeration(tree);
pcercuei 0:03b5121a232e 6108 break;
pcercuei 0:03b5121a232e 6109 }
pcercuei 0:03b5121a232e 6110 SKIP_BLANKS;
pcercuei 0:03b5121a232e 6111
pcercuei 0:03b5121a232e 6112 def = xmlParseDefaultDecl(ctxt, &defaultValue);
pcercuei 0:03b5121a232e 6113 if (def <= 0) {
pcercuei 0:03b5121a232e 6114 if (defaultValue != NULL)
pcercuei 0:03b5121a232e 6115 xmlFree(defaultValue);
pcercuei 0:03b5121a232e 6116 if (tree != NULL)
pcercuei 0:03b5121a232e 6117 xmlFreeEnumeration(tree);
pcercuei 0:03b5121a232e 6118 break;
pcercuei 0:03b5121a232e 6119 }
pcercuei 0:03b5121a232e 6120 if ((type != XML_ATTRIBUTE_CDATA) && (defaultValue != NULL))
pcercuei 0:03b5121a232e 6121 xmlAttrNormalizeSpace(defaultValue, defaultValue);
pcercuei 0:03b5121a232e 6122
pcercuei 0:03b5121a232e 6123 GROW;
pcercuei 0:03b5121a232e 6124 if (RAW != '>') {
pcercuei 0:03b5121a232e 6125 if (!IS_BLANK_CH(CUR)) {
pcercuei 0:03b5121a232e 6126 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
pcercuei 0:03b5121a232e 6127 "Space required after the attribute default value\n");
pcercuei 0:03b5121a232e 6128 if (defaultValue != NULL)
pcercuei 0:03b5121a232e 6129 xmlFree(defaultValue);
pcercuei 0:03b5121a232e 6130 if (tree != NULL)
pcercuei 0:03b5121a232e 6131 xmlFreeEnumeration(tree);
pcercuei 0:03b5121a232e 6132 break;
pcercuei 0:03b5121a232e 6133 }
pcercuei 0:03b5121a232e 6134 SKIP_BLANKS;
pcercuei 0:03b5121a232e 6135 }
pcercuei 0:03b5121a232e 6136 if (check == CUR_PTR) {
pcercuei 0:03b5121a232e 6137 xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
pcercuei 0:03b5121a232e 6138 "in xmlParseAttributeListDecl\n");
pcercuei 0:03b5121a232e 6139 if (defaultValue != NULL)
pcercuei 0:03b5121a232e 6140 xmlFree(defaultValue);
pcercuei 0:03b5121a232e 6141 if (tree != NULL)
pcercuei 0:03b5121a232e 6142 xmlFreeEnumeration(tree);
pcercuei 0:03b5121a232e 6143 break;
pcercuei 0:03b5121a232e 6144 }
pcercuei 0:03b5121a232e 6145 if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
pcercuei 0:03b5121a232e 6146 (ctxt->sax->attributeDecl != NULL))
pcercuei 0:03b5121a232e 6147 ctxt->sax->attributeDecl(ctxt->userData, elemName, attrName,
pcercuei 0:03b5121a232e 6148 type, def, defaultValue, tree);
pcercuei 0:03b5121a232e 6149 else if (tree != NULL)
pcercuei 0:03b5121a232e 6150 xmlFreeEnumeration(tree);
pcercuei 0:03b5121a232e 6151
pcercuei 0:03b5121a232e 6152 if ((ctxt->sax2) && (defaultValue != NULL) &&
pcercuei 0:03b5121a232e 6153 (def != XML_ATTRIBUTE_IMPLIED) &&
pcercuei 0:03b5121a232e 6154 (def != XML_ATTRIBUTE_REQUIRED)) {
pcercuei 0:03b5121a232e 6155 xmlAddDefAttrs(ctxt, elemName, attrName, defaultValue);
pcercuei 0:03b5121a232e 6156 }
pcercuei 0:03b5121a232e 6157 if (ctxt->sax2) {
pcercuei 0:03b5121a232e 6158 xmlAddSpecialAttr(ctxt, elemName, attrName, type);
pcercuei 0:03b5121a232e 6159 }
pcercuei 0:03b5121a232e 6160 if (defaultValue != NULL)
pcercuei 0:03b5121a232e 6161 xmlFree(defaultValue);
pcercuei 0:03b5121a232e 6162 GROW;
pcercuei 0:03b5121a232e 6163 }
pcercuei 0:03b5121a232e 6164 if (RAW == '>') {
pcercuei 0:03b5121a232e 6165 if (input != ctxt->input) {
pcercuei 0:03b5121a232e 6166 xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
pcercuei 0:03b5121a232e 6167 "Attribute list declaration doesn't start and stop in the same entity\n",
pcercuei 0:03b5121a232e 6168 NULL, NULL);
pcercuei 0:03b5121a232e 6169 }
pcercuei 0:03b5121a232e 6170 NEXT;
pcercuei 0:03b5121a232e 6171 }
pcercuei 0:03b5121a232e 6172 }
pcercuei 0:03b5121a232e 6173 }
pcercuei 0:03b5121a232e 6174
pcercuei 0:03b5121a232e 6175 /**
pcercuei 0:03b5121a232e 6176 * xmlParseElementMixedContentDecl:
pcercuei 0:03b5121a232e 6177 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 6178 * @inputchk: the input used for the current entity, needed for boundary checks
pcercuei 0:03b5121a232e 6179 *
pcercuei 0:03b5121a232e 6180 * parse the declaration for a Mixed Element content
pcercuei 0:03b5121a232e 6181 * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
pcercuei 0:03b5121a232e 6182 *
pcercuei 0:03b5121a232e 6183 * [51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' |
pcercuei 0:03b5121a232e 6184 * '(' S? '#PCDATA' S? ')'
pcercuei 0:03b5121a232e 6185 *
pcercuei 0:03b5121a232e 6186 * [ VC: Proper Group/PE Nesting ] applies to [51] too (see [49])
pcercuei 0:03b5121a232e 6187 *
pcercuei 0:03b5121a232e 6188 * [ VC: No Duplicate Types ]
pcercuei 0:03b5121a232e 6189 * The same name must not appear more than once in a single
pcercuei 0:03b5121a232e 6190 * mixed-content declaration.
pcercuei 0:03b5121a232e 6191 *
pcercuei 0:03b5121a232e 6192 * returns: the list of the xmlElementContentPtr describing the element choices
pcercuei 0:03b5121a232e 6193 */
pcercuei 0:03b5121a232e 6194 xmlElementContentPtr
pcercuei 0:03b5121a232e 6195 xmlParseElementMixedContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
pcercuei 0:03b5121a232e 6196 xmlElementContentPtr ret = NULL, cur = NULL, n;
pcercuei 0:03b5121a232e 6197 const xmlChar *elem = NULL;
pcercuei 0:03b5121a232e 6198
pcercuei 0:03b5121a232e 6199 GROW;
pcercuei 0:03b5121a232e 6200 if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
pcercuei 0:03b5121a232e 6201 SKIP(7);
pcercuei 0:03b5121a232e 6202 SKIP_BLANKS;
pcercuei 0:03b5121a232e 6203 SHRINK;
pcercuei 0:03b5121a232e 6204 if (RAW == ')') {
pcercuei 0:03b5121a232e 6205 if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
pcercuei 0:03b5121a232e 6206 xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
pcercuei 0:03b5121a232e 6207 "Element content declaration doesn't start and stop in the same entity\n",
pcercuei 0:03b5121a232e 6208 NULL, NULL);
pcercuei 0:03b5121a232e 6209 }
pcercuei 0:03b5121a232e 6210 NEXT;
pcercuei 0:03b5121a232e 6211 ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_PCDATA);
pcercuei 0:03b5121a232e 6212 if (ret == NULL)
pcercuei 0:03b5121a232e 6213 return(NULL);
pcercuei 0:03b5121a232e 6214 if (RAW == '*') {
pcercuei 0:03b5121a232e 6215 ret->ocur = XML_ELEMENT_CONTENT_MULT;
pcercuei 0:03b5121a232e 6216 NEXT;
pcercuei 0:03b5121a232e 6217 }
pcercuei 0:03b5121a232e 6218 return(ret);
pcercuei 0:03b5121a232e 6219 }
pcercuei 0:03b5121a232e 6220 if ((RAW == '(') || (RAW == '|')) {
pcercuei 0:03b5121a232e 6221 ret = cur = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_PCDATA);
pcercuei 0:03b5121a232e 6222 if (ret == NULL) return(NULL);
pcercuei 0:03b5121a232e 6223 }
pcercuei 0:03b5121a232e 6224 while ((RAW == '|') && (ctxt->instate != XML_PARSER_EOF)) {
pcercuei 0:03b5121a232e 6225 NEXT;
pcercuei 0:03b5121a232e 6226 if (elem == NULL) {
pcercuei 0:03b5121a232e 6227 ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
pcercuei 0:03b5121a232e 6228 if (ret == NULL) return(NULL);
pcercuei 0:03b5121a232e 6229 ret->c1 = cur;
pcercuei 0:03b5121a232e 6230 if (cur != NULL)
pcercuei 0:03b5121a232e 6231 cur->parent = ret;
pcercuei 0:03b5121a232e 6232 cur = ret;
pcercuei 0:03b5121a232e 6233 } else {
pcercuei 0:03b5121a232e 6234 n = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
pcercuei 0:03b5121a232e 6235 if (n == NULL) return(NULL);
pcercuei 0:03b5121a232e 6236 n->c1 = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
pcercuei 0:03b5121a232e 6237 if (n->c1 != NULL)
pcercuei 0:03b5121a232e 6238 n->c1->parent = n;
pcercuei 0:03b5121a232e 6239 cur->c2 = n;
pcercuei 0:03b5121a232e 6240 if (n != NULL)
pcercuei 0:03b5121a232e 6241 n->parent = cur;
pcercuei 0:03b5121a232e 6242 cur = n;
pcercuei 0:03b5121a232e 6243 }
pcercuei 0:03b5121a232e 6244 SKIP_BLANKS;
pcercuei 0:03b5121a232e 6245 elem = xmlParseName(ctxt);
pcercuei 0:03b5121a232e 6246 if (elem == NULL) {
pcercuei 0:03b5121a232e 6247 xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
pcercuei 0:03b5121a232e 6248 "xmlParseElementMixedContentDecl : Name expected\n");
pcercuei 0:03b5121a232e 6249 xmlFreeDocElementContent(ctxt->myDoc, cur);
pcercuei 0:03b5121a232e 6250 return(NULL);
pcercuei 0:03b5121a232e 6251 }
pcercuei 0:03b5121a232e 6252 SKIP_BLANKS;
pcercuei 0:03b5121a232e 6253 GROW;
pcercuei 0:03b5121a232e 6254 }
pcercuei 0:03b5121a232e 6255 if ((RAW == ')') && (NXT(1) == '*')) {
pcercuei 0:03b5121a232e 6256 if (elem != NULL) {
pcercuei 0:03b5121a232e 6257 cur->c2 = xmlNewDocElementContent(ctxt->myDoc, elem,
pcercuei 0:03b5121a232e 6258 XML_ELEMENT_CONTENT_ELEMENT);
pcercuei 0:03b5121a232e 6259 if (cur->c2 != NULL)
pcercuei 0:03b5121a232e 6260 cur->c2->parent = cur;
pcercuei 0:03b5121a232e 6261 }
pcercuei 0:03b5121a232e 6262 if (ret != NULL)
pcercuei 0:03b5121a232e 6263 ret->ocur = XML_ELEMENT_CONTENT_MULT;
pcercuei 0:03b5121a232e 6264 if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
pcercuei 0:03b5121a232e 6265 xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
pcercuei 0:03b5121a232e 6266 "Element content declaration doesn't start and stop in the same entity\n",
pcercuei 0:03b5121a232e 6267 NULL, NULL);
pcercuei 0:03b5121a232e 6268 }
pcercuei 0:03b5121a232e 6269 SKIP(2);
pcercuei 0:03b5121a232e 6270 } else {
pcercuei 0:03b5121a232e 6271 xmlFreeDocElementContent(ctxt->myDoc, ret);
pcercuei 0:03b5121a232e 6272 xmlFatalErr(ctxt, XML_ERR_MIXED_NOT_STARTED, NULL);
pcercuei 0:03b5121a232e 6273 return(NULL);
pcercuei 0:03b5121a232e 6274 }
pcercuei 0:03b5121a232e 6275
pcercuei 0:03b5121a232e 6276 } else {
pcercuei 0:03b5121a232e 6277 xmlFatalErr(ctxt, XML_ERR_PCDATA_REQUIRED, NULL);
pcercuei 0:03b5121a232e 6278 }
pcercuei 0:03b5121a232e 6279 return(ret);
pcercuei 0:03b5121a232e 6280 }
pcercuei 0:03b5121a232e 6281
pcercuei 0:03b5121a232e 6282 /**
pcercuei 0:03b5121a232e 6283 * xmlParseElementChildrenContentDeclPriv:
pcercuei 0:03b5121a232e 6284 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 6285 * @inputchk: the input used for the current entity, needed for boundary checks
pcercuei 0:03b5121a232e 6286 * @depth: the level of recursion
pcercuei 0:03b5121a232e 6287 *
pcercuei 0:03b5121a232e 6288 * parse the declaration for a Mixed Element content
pcercuei 0:03b5121a232e 6289 * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
pcercuei 0:03b5121a232e 6290 *
pcercuei 0:03b5121a232e 6291 *
pcercuei 0:03b5121a232e 6292 * [47] children ::= (choice | seq) ('?' | '*' | '+')?
pcercuei 0:03b5121a232e 6293 *
pcercuei 0:03b5121a232e 6294 * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
pcercuei 0:03b5121a232e 6295 *
pcercuei 0:03b5121a232e 6296 * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
pcercuei 0:03b5121a232e 6297 *
pcercuei 0:03b5121a232e 6298 * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
pcercuei 0:03b5121a232e 6299 *
pcercuei 0:03b5121a232e 6300 * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
pcercuei 0:03b5121a232e 6301 * TODO Parameter-entity replacement text must be properly nested
pcercuei 0:03b5121a232e 6302 * with parenthesized groups. That is to say, if either of the
pcercuei 0:03b5121a232e 6303 * opening or closing parentheses in a choice, seq, or Mixed
pcercuei 0:03b5121a232e 6304 * construct is contained in the replacement text for a parameter
pcercuei 0:03b5121a232e 6305 * entity, both must be contained in the same replacement text. For
pcercuei 0:03b5121a232e 6306 * interoperability, if a parameter-entity reference appears in a
pcercuei 0:03b5121a232e 6307 * choice, seq, or Mixed construct, its replacement text should not
pcercuei 0:03b5121a232e 6308 * be empty, and neither the first nor last non-blank character of
pcercuei 0:03b5121a232e 6309 * the replacement text should be a connector (| or ,).
pcercuei 0:03b5121a232e 6310 *
pcercuei 0:03b5121a232e 6311 * Returns the tree of xmlElementContentPtr describing the element
pcercuei 0:03b5121a232e 6312 * hierarchy.
pcercuei 0:03b5121a232e 6313 */
pcercuei 0:03b5121a232e 6314 static xmlElementContentPtr
pcercuei 0:03b5121a232e 6315 xmlParseElementChildrenContentDeclPriv(xmlParserCtxtPtr ctxt, int inputchk,
pcercuei 0:03b5121a232e 6316 int depth) {
pcercuei 0:03b5121a232e 6317 xmlElementContentPtr ret = NULL, cur = NULL, last = NULL, op = NULL;
pcercuei 0:03b5121a232e 6318 const xmlChar *elem;
pcercuei 0:03b5121a232e 6319 xmlChar type = 0;
pcercuei 0:03b5121a232e 6320
pcercuei 0:03b5121a232e 6321 if (((depth > 128) && ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
pcercuei 0:03b5121a232e 6322 (depth > 2048)) {
pcercuei 0:03b5121a232e 6323 xmlFatalErrMsgInt(ctxt, XML_ERR_ELEMCONTENT_NOT_FINISHED,
pcercuei 0:03b5121a232e 6324 "xmlParseElementChildrenContentDecl : depth %d too deep, use XML_PARSE_HUGE\n",
pcercuei 0:03b5121a232e 6325 depth);
pcercuei 0:03b5121a232e 6326 return(NULL);
pcercuei 0:03b5121a232e 6327 }
pcercuei 0:03b5121a232e 6328 SKIP_BLANKS;
pcercuei 0:03b5121a232e 6329 GROW;
pcercuei 0:03b5121a232e 6330 if (RAW == '(') {
pcercuei 0:03b5121a232e 6331 int inputid = ctxt->input->id;
pcercuei 0:03b5121a232e 6332
pcercuei 0:03b5121a232e 6333 /* Recurse on first child */
pcercuei 0:03b5121a232e 6334 NEXT;
pcercuei 0:03b5121a232e 6335 SKIP_BLANKS;
pcercuei 0:03b5121a232e 6336 cur = ret = xmlParseElementChildrenContentDeclPriv(ctxt, inputid,
pcercuei 0:03b5121a232e 6337 depth + 1);
pcercuei 0:03b5121a232e 6338 SKIP_BLANKS;
pcercuei 0:03b5121a232e 6339 GROW;
pcercuei 0:03b5121a232e 6340 } else {
pcercuei 0:03b5121a232e 6341 elem = xmlParseName(ctxt);
pcercuei 0:03b5121a232e 6342 if (elem == NULL) {
pcercuei 0:03b5121a232e 6343 xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL);
pcercuei 0:03b5121a232e 6344 return(NULL);
pcercuei 0:03b5121a232e 6345 }
pcercuei 0:03b5121a232e 6346 cur = ret = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
pcercuei 0:03b5121a232e 6347 if (cur == NULL) {
pcercuei 0:03b5121a232e 6348 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 6349 return(NULL);
pcercuei 0:03b5121a232e 6350 }
pcercuei 0:03b5121a232e 6351 GROW;
pcercuei 0:03b5121a232e 6352 if (RAW == '?') {
pcercuei 0:03b5121a232e 6353 cur->ocur = XML_ELEMENT_CONTENT_OPT;
pcercuei 0:03b5121a232e 6354 NEXT;
pcercuei 0:03b5121a232e 6355 } else if (RAW == '*') {
pcercuei 0:03b5121a232e 6356 cur->ocur = XML_ELEMENT_CONTENT_MULT;
pcercuei 0:03b5121a232e 6357 NEXT;
pcercuei 0:03b5121a232e 6358 } else if (RAW == '+') {
pcercuei 0:03b5121a232e 6359 cur->ocur = XML_ELEMENT_CONTENT_PLUS;
pcercuei 0:03b5121a232e 6360 NEXT;
pcercuei 0:03b5121a232e 6361 } else {
pcercuei 0:03b5121a232e 6362 cur->ocur = XML_ELEMENT_CONTENT_ONCE;
pcercuei 0:03b5121a232e 6363 }
pcercuei 0:03b5121a232e 6364 GROW;
pcercuei 0:03b5121a232e 6365 }
pcercuei 0:03b5121a232e 6366 SKIP_BLANKS;
pcercuei 0:03b5121a232e 6367 SHRINK;
pcercuei 0:03b5121a232e 6368 while ((RAW != ')') && (ctxt->instate != XML_PARSER_EOF)) {
pcercuei 0:03b5121a232e 6369 /*
pcercuei 0:03b5121a232e 6370 * Each loop we parse one separator and one element.
pcercuei 0:03b5121a232e 6371 */
pcercuei 0:03b5121a232e 6372 if (RAW == ',') {
pcercuei 0:03b5121a232e 6373 if (type == 0) type = CUR;
pcercuei 0:03b5121a232e 6374
pcercuei 0:03b5121a232e 6375 /*
pcercuei 0:03b5121a232e 6376 * Detect "Name | Name , Name" error
pcercuei 0:03b5121a232e 6377 */
pcercuei 0:03b5121a232e 6378 else if (type != CUR) {
pcercuei 0:03b5121a232e 6379 xmlFatalErrMsgInt(ctxt, XML_ERR_SEPARATOR_REQUIRED,
pcercuei 0:03b5121a232e 6380 "xmlParseElementChildrenContentDecl : '%c' expected\n",
pcercuei 0:03b5121a232e 6381 type);
pcercuei 0:03b5121a232e 6382 if ((last != NULL) && (last != ret))
pcercuei 0:03b5121a232e 6383 xmlFreeDocElementContent(ctxt->myDoc, last);
pcercuei 0:03b5121a232e 6384 if (ret != NULL)
pcercuei 0:03b5121a232e 6385 xmlFreeDocElementContent(ctxt->myDoc, ret);
pcercuei 0:03b5121a232e 6386 return(NULL);
pcercuei 0:03b5121a232e 6387 }
pcercuei 0:03b5121a232e 6388 NEXT;
pcercuei 0:03b5121a232e 6389
pcercuei 0:03b5121a232e 6390 op = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_SEQ);
pcercuei 0:03b5121a232e 6391 if (op == NULL) {
pcercuei 0:03b5121a232e 6392 if ((last != NULL) && (last != ret))
pcercuei 0:03b5121a232e 6393 xmlFreeDocElementContent(ctxt->myDoc, last);
pcercuei 0:03b5121a232e 6394 xmlFreeDocElementContent(ctxt->myDoc, ret);
pcercuei 0:03b5121a232e 6395 return(NULL);
pcercuei 0:03b5121a232e 6396 }
pcercuei 0:03b5121a232e 6397 if (last == NULL) {
pcercuei 0:03b5121a232e 6398 op->c1 = ret;
pcercuei 0:03b5121a232e 6399 if (ret != NULL)
pcercuei 0:03b5121a232e 6400 ret->parent = op;
pcercuei 0:03b5121a232e 6401 ret = cur = op;
pcercuei 0:03b5121a232e 6402 } else {
pcercuei 0:03b5121a232e 6403 cur->c2 = op;
pcercuei 0:03b5121a232e 6404 if (op != NULL)
pcercuei 0:03b5121a232e 6405 op->parent = cur;
pcercuei 0:03b5121a232e 6406 op->c1 = last;
pcercuei 0:03b5121a232e 6407 if (last != NULL)
pcercuei 0:03b5121a232e 6408 last->parent = op;
pcercuei 0:03b5121a232e 6409 cur =op;
pcercuei 0:03b5121a232e 6410 last = NULL;
pcercuei 0:03b5121a232e 6411 }
pcercuei 0:03b5121a232e 6412 } else if (RAW == '|') {
pcercuei 0:03b5121a232e 6413 if (type == 0) type = CUR;
pcercuei 0:03b5121a232e 6414
pcercuei 0:03b5121a232e 6415 /*
pcercuei 0:03b5121a232e 6416 * Detect "Name , Name | Name" error
pcercuei 0:03b5121a232e 6417 */
pcercuei 0:03b5121a232e 6418 else if (type != CUR) {
pcercuei 0:03b5121a232e 6419 xmlFatalErrMsgInt(ctxt, XML_ERR_SEPARATOR_REQUIRED,
pcercuei 0:03b5121a232e 6420 "xmlParseElementChildrenContentDecl : '%c' expected\n",
pcercuei 0:03b5121a232e 6421 type);
pcercuei 0:03b5121a232e 6422 if ((last != NULL) && (last != ret))
pcercuei 0:03b5121a232e 6423 xmlFreeDocElementContent(ctxt->myDoc, last);
pcercuei 0:03b5121a232e 6424 if (ret != NULL)
pcercuei 0:03b5121a232e 6425 xmlFreeDocElementContent(ctxt->myDoc, ret);
pcercuei 0:03b5121a232e 6426 return(NULL);
pcercuei 0:03b5121a232e 6427 }
pcercuei 0:03b5121a232e 6428 NEXT;
pcercuei 0:03b5121a232e 6429
pcercuei 0:03b5121a232e 6430 op = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
pcercuei 0:03b5121a232e 6431 if (op == NULL) {
pcercuei 0:03b5121a232e 6432 if ((last != NULL) && (last != ret))
pcercuei 0:03b5121a232e 6433 xmlFreeDocElementContent(ctxt->myDoc, last);
pcercuei 0:03b5121a232e 6434 if (ret != NULL)
pcercuei 0:03b5121a232e 6435 xmlFreeDocElementContent(ctxt->myDoc, ret);
pcercuei 0:03b5121a232e 6436 return(NULL);
pcercuei 0:03b5121a232e 6437 }
pcercuei 0:03b5121a232e 6438 if (last == NULL) {
pcercuei 0:03b5121a232e 6439 op->c1 = ret;
pcercuei 0:03b5121a232e 6440 if (ret != NULL)
pcercuei 0:03b5121a232e 6441 ret->parent = op;
pcercuei 0:03b5121a232e 6442 ret = cur = op;
pcercuei 0:03b5121a232e 6443 } else {
pcercuei 0:03b5121a232e 6444 cur->c2 = op;
pcercuei 0:03b5121a232e 6445 if (op != NULL)
pcercuei 0:03b5121a232e 6446 op->parent = cur;
pcercuei 0:03b5121a232e 6447 op->c1 = last;
pcercuei 0:03b5121a232e 6448 if (last != NULL)
pcercuei 0:03b5121a232e 6449 last->parent = op;
pcercuei 0:03b5121a232e 6450 cur =op;
pcercuei 0:03b5121a232e 6451 last = NULL;
pcercuei 0:03b5121a232e 6452 }
pcercuei 0:03b5121a232e 6453 } else {
pcercuei 0:03b5121a232e 6454 xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_FINISHED, NULL);
pcercuei 0:03b5121a232e 6455 if ((last != NULL) && (last != ret))
pcercuei 0:03b5121a232e 6456 xmlFreeDocElementContent(ctxt->myDoc, last);
pcercuei 0:03b5121a232e 6457 if (ret != NULL)
pcercuei 0:03b5121a232e 6458 xmlFreeDocElementContent(ctxt->myDoc, ret);
pcercuei 0:03b5121a232e 6459 return(NULL);
pcercuei 0:03b5121a232e 6460 }
pcercuei 0:03b5121a232e 6461 GROW;
pcercuei 0:03b5121a232e 6462 SKIP_BLANKS;
pcercuei 0:03b5121a232e 6463 GROW;
pcercuei 0:03b5121a232e 6464 if (RAW == '(') {
pcercuei 0:03b5121a232e 6465 int inputid = ctxt->input->id;
pcercuei 0:03b5121a232e 6466 /* Recurse on second child */
pcercuei 0:03b5121a232e 6467 NEXT;
pcercuei 0:03b5121a232e 6468 SKIP_BLANKS;
pcercuei 0:03b5121a232e 6469 last = xmlParseElementChildrenContentDeclPriv(ctxt, inputid,
pcercuei 0:03b5121a232e 6470 depth + 1);
pcercuei 0:03b5121a232e 6471 SKIP_BLANKS;
pcercuei 0:03b5121a232e 6472 } else {
pcercuei 0:03b5121a232e 6473 elem = xmlParseName(ctxt);
pcercuei 0:03b5121a232e 6474 if (elem == NULL) {
pcercuei 0:03b5121a232e 6475 xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL);
pcercuei 0:03b5121a232e 6476 if (ret != NULL)
pcercuei 0:03b5121a232e 6477 xmlFreeDocElementContent(ctxt->myDoc, ret);
pcercuei 0:03b5121a232e 6478 return(NULL);
pcercuei 0:03b5121a232e 6479 }
pcercuei 0:03b5121a232e 6480 last = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
pcercuei 0:03b5121a232e 6481 if (last == NULL) {
pcercuei 0:03b5121a232e 6482 if (ret != NULL)
pcercuei 0:03b5121a232e 6483 xmlFreeDocElementContent(ctxt->myDoc, ret);
pcercuei 0:03b5121a232e 6484 return(NULL);
pcercuei 0:03b5121a232e 6485 }
pcercuei 0:03b5121a232e 6486 if (RAW == '?') {
pcercuei 0:03b5121a232e 6487 last->ocur = XML_ELEMENT_CONTENT_OPT;
pcercuei 0:03b5121a232e 6488 NEXT;
pcercuei 0:03b5121a232e 6489 } else if (RAW == '*') {
pcercuei 0:03b5121a232e 6490 last->ocur = XML_ELEMENT_CONTENT_MULT;
pcercuei 0:03b5121a232e 6491 NEXT;
pcercuei 0:03b5121a232e 6492 } else if (RAW == '+') {
pcercuei 0:03b5121a232e 6493 last->ocur = XML_ELEMENT_CONTENT_PLUS;
pcercuei 0:03b5121a232e 6494 NEXT;
pcercuei 0:03b5121a232e 6495 } else {
pcercuei 0:03b5121a232e 6496 last->ocur = XML_ELEMENT_CONTENT_ONCE;
pcercuei 0:03b5121a232e 6497 }
pcercuei 0:03b5121a232e 6498 }
pcercuei 0:03b5121a232e 6499 SKIP_BLANKS;
pcercuei 0:03b5121a232e 6500 GROW;
pcercuei 0:03b5121a232e 6501 }
pcercuei 0:03b5121a232e 6502 if ((cur != NULL) && (last != NULL)) {
pcercuei 0:03b5121a232e 6503 cur->c2 = last;
pcercuei 0:03b5121a232e 6504 if (last != NULL)
pcercuei 0:03b5121a232e 6505 last->parent = cur;
pcercuei 0:03b5121a232e 6506 }
pcercuei 0:03b5121a232e 6507 if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
pcercuei 0:03b5121a232e 6508 xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
pcercuei 0:03b5121a232e 6509 "Element content declaration doesn't start and stop in the same entity\n",
pcercuei 0:03b5121a232e 6510 NULL, NULL);
pcercuei 0:03b5121a232e 6511 }
pcercuei 0:03b5121a232e 6512 NEXT;
pcercuei 0:03b5121a232e 6513 if (RAW == '?') {
pcercuei 0:03b5121a232e 6514 if (ret != NULL) {
pcercuei 0:03b5121a232e 6515 if ((ret->ocur == XML_ELEMENT_CONTENT_PLUS) ||
pcercuei 0:03b5121a232e 6516 (ret->ocur == XML_ELEMENT_CONTENT_MULT))
pcercuei 0:03b5121a232e 6517 ret->ocur = XML_ELEMENT_CONTENT_MULT;
pcercuei 0:03b5121a232e 6518 else
pcercuei 0:03b5121a232e 6519 ret->ocur = XML_ELEMENT_CONTENT_OPT;
pcercuei 0:03b5121a232e 6520 }
pcercuei 0:03b5121a232e 6521 NEXT;
pcercuei 0:03b5121a232e 6522 } else if (RAW == '*') {
pcercuei 0:03b5121a232e 6523 if (ret != NULL) {
pcercuei 0:03b5121a232e 6524 ret->ocur = XML_ELEMENT_CONTENT_MULT;
pcercuei 0:03b5121a232e 6525 cur = ret;
pcercuei 0:03b5121a232e 6526 /*
pcercuei 0:03b5121a232e 6527 * Some normalization:
pcercuei 0:03b5121a232e 6528 * (a | b* | c?)* == (a | b | c)*
pcercuei 0:03b5121a232e 6529 */
pcercuei 0:03b5121a232e 6530 while ((cur != NULL) && (cur->type == XML_ELEMENT_CONTENT_OR)) {
pcercuei 0:03b5121a232e 6531 if ((cur->c1 != NULL) &&
pcercuei 0:03b5121a232e 6532 ((cur->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
pcercuei 0:03b5121a232e 6533 (cur->c1->ocur == XML_ELEMENT_CONTENT_MULT)))
pcercuei 0:03b5121a232e 6534 cur->c1->ocur = XML_ELEMENT_CONTENT_ONCE;
pcercuei 0:03b5121a232e 6535 if ((cur->c2 != NULL) &&
pcercuei 0:03b5121a232e 6536 ((cur->c2->ocur == XML_ELEMENT_CONTENT_OPT) ||
pcercuei 0:03b5121a232e 6537 (cur->c2->ocur == XML_ELEMENT_CONTENT_MULT)))
pcercuei 0:03b5121a232e 6538 cur->c2->ocur = XML_ELEMENT_CONTENT_ONCE;
pcercuei 0:03b5121a232e 6539 cur = cur->c2;
pcercuei 0:03b5121a232e 6540 }
pcercuei 0:03b5121a232e 6541 }
pcercuei 0:03b5121a232e 6542 NEXT;
pcercuei 0:03b5121a232e 6543 } else if (RAW == '+') {
pcercuei 0:03b5121a232e 6544 if (ret != NULL) {
pcercuei 0:03b5121a232e 6545 int found = 0;
pcercuei 0:03b5121a232e 6546
pcercuei 0:03b5121a232e 6547 if ((ret->ocur == XML_ELEMENT_CONTENT_OPT) ||
pcercuei 0:03b5121a232e 6548 (ret->ocur == XML_ELEMENT_CONTENT_MULT))
pcercuei 0:03b5121a232e 6549 ret->ocur = XML_ELEMENT_CONTENT_MULT;
pcercuei 0:03b5121a232e 6550 else
pcercuei 0:03b5121a232e 6551 ret->ocur = XML_ELEMENT_CONTENT_PLUS;
pcercuei 0:03b5121a232e 6552 /*
pcercuei 0:03b5121a232e 6553 * Some normalization:
pcercuei 0:03b5121a232e 6554 * (a | b*)+ == (a | b)*
pcercuei 0:03b5121a232e 6555 * (a | b?)+ == (a | b)*
pcercuei 0:03b5121a232e 6556 */
pcercuei 0:03b5121a232e 6557 while ((cur != NULL) && (cur->type == XML_ELEMENT_CONTENT_OR)) {
pcercuei 0:03b5121a232e 6558 if ((cur->c1 != NULL) &&
pcercuei 0:03b5121a232e 6559 ((cur->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
pcercuei 0:03b5121a232e 6560 (cur->c1->ocur == XML_ELEMENT_CONTENT_MULT))) {
pcercuei 0:03b5121a232e 6561 cur->c1->ocur = XML_ELEMENT_CONTENT_ONCE;
pcercuei 0:03b5121a232e 6562 found = 1;
pcercuei 0:03b5121a232e 6563 }
pcercuei 0:03b5121a232e 6564 if ((cur->c2 != NULL) &&
pcercuei 0:03b5121a232e 6565 ((cur->c2->ocur == XML_ELEMENT_CONTENT_OPT) ||
pcercuei 0:03b5121a232e 6566 (cur->c2->ocur == XML_ELEMENT_CONTENT_MULT))) {
pcercuei 0:03b5121a232e 6567 cur->c2->ocur = XML_ELEMENT_CONTENT_ONCE;
pcercuei 0:03b5121a232e 6568 found = 1;
pcercuei 0:03b5121a232e 6569 }
pcercuei 0:03b5121a232e 6570 cur = cur->c2;
pcercuei 0:03b5121a232e 6571 }
pcercuei 0:03b5121a232e 6572 if (found)
pcercuei 0:03b5121a232e 6573 ret->ocur = XML_ELEMENT_CONTENT_MULT;
pcercuei 0:03b5121a232e 6574 }
pcercuei 0:03b5121a232e 6575 NEXT;
pcercuei 0:03b5121a232e 6576 }
pcercuei 0:03b5121a232e 6577 return(ret);
pcercuei 0:03b5121a232e 6578 }
pcercuei 0:03b5121a232e 6579
pcercuei 0:03b5121a232e 6580 /**
pcercuei 0:03b5121a232e 6581 * xmlParseElementChildrenContentDecl:
pcercuei 0:03b5121a232e 6582 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 6583 * @inputchk: the input used for the current entity, needed for boundary checks
pcercuei 0:03b5121a232e 6584 *
pcercuei 0:03b5121a232e 6585 * parse the declaration for a Mixed Element content
pcercuei 0:03b5121a232e 6586 * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
pcercuei 0:03b5121a232e 6587 *
pcercuei 0:03b5121a232e 6588 * [47] children ::= (choice | seq) ('?' | '*' | '+')?
pcercuei 0:03b5121a232e 6589 *
pcercuei 0:03b5121a232e 6590 * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
pcercuei 0:03b5121a232e 6591 *
pcercuei 0:03b5121a232e 6592 * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
pcercuei 0:03b5121a232e 6593 *
pcercuei 0:03b5121a232e 6594 * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
pcercuei 0:03b5121a232e 6595 *
pcercuei 0:03b5121a232e 6596 * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
pcercuei 0:03b5121a232e 6597 * TODO Parameter-entity replacement text must be properly nested
pcercuei 0:03b5121a232e 6598 * with parenthesized groups. That is to say, if either of the
pcercuei 0:03b5121a232e 6599 * opening or closing parentheses in a choice, seq, or Mixed
pcercuei 0:03b5121a232e 6600 * construct is contained in the replacement text for a parameter
pcercuei 0:03b5121a232e 6601 * entity, both must be contained in the same replacement text. For
pcercuei 0:03b5121a232e 6602 * interoperability, if a parameter-entity reference appears in a
pcercuei 0:03b5121a232e 6603 * choice, seq, or Mixed construct, its replacement text should not
pcercuei 0:03b5121a232e 6604 * be empty, and neither the first nor last non-blank character of
pcercuei 0:03b5121a232e 6605 * the replacement text should be a connector (| or ,).
pcercuei 0:03b5121a232e 6606 *
pcercuei 0:03b5121a232e 6607 * Returns the tree of xmlElementContentPtr describing the element
pcercuei 0:03b5121a232e 6608 * hierarchy.
pcercuei 0:03b5121a232e 6609 */
pcercuei 0:03b5121a232e 6610 xmlElementContentPtr
pcercuei 0:03b5121a232e 6611 xmlParseElementChildrenContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
pcercuei 0:03b5121a232e 6612 /* stub left for API/ABI compat */
pcercuei 0:03b5121a232e 6613 return(xmlParseElementChildrenContentDeclPriv(ctxt, inputchk, 1));
pcercuei 0:03b5121a232e 6614 }
pcercuei 0:03b5121a232e 6615
pcercuei 0:03b5121a232e 6616 /**
pcercuei 0:03b5121a232e 6617 * xmlParseElementContentDecl:
pcercuei 0:03b5121a232e 6618 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 6619 * @name: the name of the element being defined.
pcercuei 0:03b5121a232e 6620 * @result: the Element Content pointer will be stored here if any
pcercuei 0:03b5121a232e 6621 *
pcercuei 0:03b5121a232e 6622 * parse the declaration for an Element content either Mixed or Children,
pcercuei 0:03b5121a232e 6623 * the cases EMPTY and ANY are handled directly in xmlParseElementDecl
pcercuei 0:03b5121a232e 6624 *
pcercuei 0:03b5121a232e 6625 * [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
pcercuei 0:03b5121a232e 6626 *
pcercuei 0:03b5121a232e 6627 * returns: the type of element content XML_ELEMENT_TYPE_xxx
pcercuei 0:03b5121a232e 6628 */
pcercuei 0:03b5121a232e 6629
pcercuei 0:03b5121a232e 6630 int
pcercuei 0:03b5121a232e 6631 xmlParseElementContentDecl(xmlParserCtxtPtr ctxt, const xmlChar *name,
pcercuei 0:03b5121a232e 6632 xmlElementContentPtr *result) {
pcercuei 0:03b5121a232e 6633
pcercuei 0:03b5121a232e 6634 xmlElementContentPtr tree = NULL;
pcercuei 0:03b5121a232e 6635 int inputid = ctxt->input->id;
pcercuei 0:03b5121a232e 6636 int res;
pcercuei 0:03b5121a232e 6637
pcercuei 0:03b5121a232e 6638 *result = NULL;
pcercuei 0:03b5121a232e 6639
pcercuei 0:03b5121a232e 6640 if (RAW != '(') {
pcercuei 0:03b5121a232e 6641 xmlFatalErrMsgStr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED,
pcercuei 0:03b5121a232e 6642 "xmlParseElementContentDecl : %s '(' expected\n", name);
pcercuei 0:03b5121a232e 6643 return(-1);
pcercuei 0:03b5121a232e 6644 }
pcercuei 0:03b5121a232e 6645 NEXT;
pcercuei 0:03b5121a232e 6646 GROW;
pcercuei 0:03b5121a232e 6647 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 6648 return(-1);
pcercuei 0:03b5121a232e 6649 SKIP_BLANKS;
pcercuei 0:03b5121a232e 6650 if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
pcercuei 0:03b5121a232e 6651 tree = xmlParseElementMixedContentDecl(ctxt, inputid);
pcercuei 0:03b5121a232e 6652 res = XML_ELEMENT_TYPE_MIXED;
pcercuei 0:03b5121a232e 6653 } else {
pcercuei 0:03b5121a232e 6654 tree = xmlParseElementChildrenContentDeclPriv(ctxt, inputid, 1);
pcercuei 0:03b5121a232e 6655 res = XML_ELEMENT_TYPE_ELEMENT;
pcercuei 0:03b5121a232e 6656 }
pcercuei 0:03b5121a232e 6657 SKIP_BLANKS;
pcercuei 0:03b5121a232e 6658 *result = tree;
pcercuei 0:03b5121a232e 6659 return(res);
pcercuei 0:03b5121a232e 6660 }
pcercuei 0:03b5121a232e 6661
pcercuei 0:03b5121a232e 6662 /**
pcercuei 0:03b5121a232e 6663 * xmlParseElementDecl:
pcercuei 0:03b5121a232e 6664 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 6665 *
pcercuei 0:03b5121a232e 6666 * parse an Element declaration.
pcercuei 0:03b5121a232e 6667 *
pcercuei 0:03b5121a232e 6668 * [45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'
pcercuei 0:03b5121a232e 6669 *
pcercuei 0:03b5121a232e 6670 * [ VC: Unique Element Type Declaration ]
pcercuei 0:03b5121a232e 6671 * No element type may be declared more than once
pcercuei 0:03b5121a232e 6672 *
pcercuei 0:03b5121a232e 6673 * Returns the type of the element, or -1 in case of error
pcercuei 0:03b5121a232e 6674 */
pcercuei 0:03b5121a232e 6675 int
pcercuei 0:03b5121a232e 6676 xmlParseElementDecl(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 6677 const xmlChar *name;
pcercuei 0:03b5121a232e 6678 int ret = -1;
pcercuei 0:03b5121a232e 6679 xmlElementContentPtr content = NULL;
pcercuei 0:03b5121a232e 6680
pcercuei 0:03b5121a232e 6681 /* GROW; done in the caller */
pcercuei 0:03b5121a232e 6682 if (CMP9(CUR_PTR, '<', '!', 'E', 'L', 'E', 'M', 'E', 'N', 'T')) {
pcercuei 0:03b5121a232e 6683 xmlParserInputPtr input = ctxt->input;
pcercuei 0:03b5121a232e 6684
pcercuei 0:03b5121a232e 6685 SKIP(9);
pcercuei 0:03b5121a232e 6686 if (!IS_BLANK_CH(CUR)) {
pcercuei 0:03b5121a232e 6687 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
pcercuei 0:03b5121a232e 6688 "Space required after 'ELEMENT'\n");
pcercuei 0:03b5121a232e 6689 }
pcercuei 0:03b5121a232e 6690 SKIP_BLANKS;
pcercuei 0:03b5121a232e 6691 name = xmlParseName(ctxt);
pcercuei 0:03b5121a232e 6692 if (name == NULL) {
pcercuei 0:03b5121a232e 6693 xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
pcercuei 0:03b5121a232e 6694 "xmlParseElementDecl: no name for Element\n");
pcercuei 0:03b5121a232e 6695 return(-1);
pcercuei 0:03b5121a232e 6696 }
pcercuei 0:03b5121a232e 6697 while ((RAW == 0) && (ctxt->inputNr > 1))
pcercuei 0:03b5121a232e 6698 xmlPopInput(ctxt);
pcercuei 0:03b5121a232e 6699 if (!IS_BLANK_CH(CUR)) {
pcercuei 0:03b5121a232e 6700 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
pcercuei 0:03b5121a232e 6701 "Space required after the element name\n");
pcercuei 0:03b5121a232e 6702 }
pcercuei 0:03b5121a232e 6703 SKIP_BLANKS;
pcercuei 0:03b5121a232e 6704 if (CMP5(CUR_PTR, 'E', 'M', 'P', 'T', 'Y')) {
pcercuei 0:03b5121a232e 6705 SKIP(5);
pcercuei 0:03b5121a232e 6706 /*
pcercuei 0:03b5121a232e 6707 * Element must always be empty.
pcercuei 0:03b5121a232e 6708 */
pcercuei 0:03b5121a232e 6709 ret = XML_ELEMENT_TYPE_EMPTY;
pcercuei 0:03b5121a232e 6710 } else if ((RAW == 'A') && (NXT(1) == 'N') &&
pcercuei 0:03b5121a232e 6711 (NXT(2) == 'Y')) {
pcercuei 0:03b5121a232e 6712 SKIP(3);
pcercuei 0:03b5121a232e 6713 /*
pcercuei 0:03b5121a232e 6714 * Element is a generic container.
pcercuei 0:03b5121a232e 6715 */
pcercuei 0:03b5121a232e 6716 ret = XML_ELEMENT_TYPE_ANY;
pcercuei 0:03b5121a232e 6717 } else if (RAW == '(') {
pcercuei 0:03b5121a232e 6718 ret = xmlParseElementContentDecl(ctxt, name, &content);
pcercuei 0:03b5121a232e 6719 } else {
pcercuei 0:03b5121a232e 6720 /*
pcercuei 0:03b5121a232e 6721 * [ WFC: PEs in Internal Subset ] error handling.
pcercuei 0:03b5121a232e 6722 */
pcercuei 0:03b5121a232e 6723 if ((RAW == '%') && (ctxt->external == 0) &&
pcercuei 0:03b5121a232e 6724 (ctxt->inputNr == 1)) {
pcercuei 0:03b5121a232e 6725 xmlFatalErrMsg(ctxt, XML_ERR_PEREF_IN_INT_SUBSET,
pcercuei 0:03b5121a232e 6726 "PEReference: forbidden within markup decl in internal subset\n");
pcercuei 0:03b5121a232e 6727 } else {
pcercuei 0:03b5121a232e 6728 xmlFatalErrMsg(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED,
pcercuei 0:03b5121a232e 6729 "xmlParseElementDecl: 'EMPTY', 'ANY' or '(' expected\n");
pcercuei 0:03b5121a232e 6730 }
pcercuei 0:03b5121a232e 6731 return(-1);
pcercuei 0:03b5121a232e 6732 }
pcercuei 0:03b5121a232e 6733
pcercuei 0:03b5121a232e 6734 SKIP_BLANKS;
pcercuei 0:03b5121a232e 6735 /*
pcercuei 0:03b5121a232e 6736 * Pop-up of finished entities.
pcercuei 0:03b5121a232e 6737 */
pcercuei 0:03b5121a232e 6738 while ((RAW == 0) && (ctxt->inputNr > 1))
pcercuei 0:03b5121a232e 6739 xmlPopInput(ctxt);
pcercuei 0:03b5121a232e 6740 SKIP_BLANKS;
pcercuei 0:03b5121a232e 6741
pcercuei 0:03b5121a232e 6742 if (RAW != '>') {
pcercuei 0:03b5121a232e 6743 xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
pcercuei 0:03b5121a232e 6744 if (content != NULL) {
pcercuei 0:03b5121a232e 6745 xmlFreeDocElementContent(ctxt->myDoc, content);
pcercuei 0:03b5121a232e 6746 }
pcercuei 0:03b5121a232e 6747 } else {
pcercuei 0:03b5121a232e 6748 if (input != ctxt->input) {
pcercuei 0:03b5121a232e 6749 xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
pcercuei 0:03b5121a232e 6750 "Element declaration doesn't start and stop in the same entity\n");
pcercuei 0:03b5121a232e 6751 }
pcercuei 0:03b5121a232e 6752
pcercuei 0:03b5121a232e 6753 NEXT;
pcercuei 0:03b5121a232e 6754 if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
pcercuei 0:03b5121a232e 6755 (ctxt->sax->elementDecl != NULL)) {
pcercuei 0:03b5121a232e 6756 if (content != NULL)
pcercuei 0:03b5121a232e 6757 content->parent = NULL;
pcercuei 0:03b5121a232e 6758 ctxt->sax->elementDecl(ctxt->userData, name, ret,
pcercuei 0:03b5121a232e 6759 content);
pcercuei 0:03b5121a232e 6760 if ((content != NULL) && (content->parent == NULL)) {
pcercuei 0:03b5121a232e 6761 /*
pcercuei 0:03b5121a232e 6762 * this is a trick: if xmlAddElementDecl is called,
pcercuei 0:03b5121a232e 6763 * instead of copying the full tree it is plugged directly
pcercuei 0:03b5121a232e 6764 * if called from the parser. Avoid duplicating the
pcercuei 0:03b5121a232e 6765 * interfaces or change the API/ABI
pcercuei 0:03b5121a232e 6766 */
pcercuei 0:03b5121a232e 6767 xmlFreeDocElementContent(ctxt->myDoc, content);
pcercuei 0:03b5121a232e 6768 }
pcercuei 0:03b5121a232e 6769 } else if (content != NULL) {
pcercuei 0:03b5121a232e 6770 xmlFreeDocElementContent(ctxt->myDoc, content);
pcercuei 0:03b5121a232e 6771 }
pcercuei 0:03b5121a232e 6772 }
pcercuei 0:03b5121a232e 6773 }
pcercuei 0:03b5121a232e 6774 return(ret);
pcercuei 0:03b5121a232e 6775 }
pcercuei 0:03b5121a232e 6776
pcercuei 0:03b5121a232e 6777 /**
pcercuei 0:03b5121a232e 6778 * xmlParseConditionalSections
pcercuei 0:03b5121a232e 6779 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 6780 *
pcercuei 0:03b5121a232e 6781 * [61] conditionalSect ::= includeSect | ignoreSect
pcercuei 0:03b5121a232e 6782 * [62] includeSect ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>'
pcercuei 0:03b5121a232e 6783 * [63] ignoreSect ::= '<![' S? 'IGNORE' S? '[' ignoreSectContents* ']]>'
pcercuei 0:03b5121a232e 6784 * [64] ignoreSectContents ::= Ignore ('<![' ignoreSectContents ']]>' Ignore)*
pcercuei 0:03b5121a232e 6785 * [65] Ignore ::= Char* - (Char* ('<![' | ']]>') Char*)
pcercuei 0:03b5121a232e 6786 */
pcercuei 0:03b5121a232e 6787
pcercuei 0:03b5121a232e 6788 static void
pcercuei 0:03b5121a232e 6789 xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 6790 int id = ctxt->input->id;
pcercuei 0:03b5121a232e 6791
pcercuei 0:03b5121a232e 6792 SKIP(3);
pcercuei 0:03b5121a232e 6793 SKIP_BLANKS;
pcercuei 0:03b5121a232e 6794 if (CMP7(CUR_PTR, 'I', 'N', 'C', 'L', 'U', 'D', 'E')) {
pcercuei 0:03b5121a232e 6795 SKIP(7);
pcercuei 0:03b5121a232e 6796 SKIP_BLANKS;
pcercuei 0:03b5121a232e 6797 if (RAW != '[') {
pcercuei 0:03b5121a232e 6798 xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
pcercuei 0:03b5121a232e 6799 xmlHaltParser(ctxt);
pcercuei 0:03b5121a232e 6800 return;
pcercuei 0:03b5121a232e 6801 } else {
pcercuei 0:03b5121a232e 6802 if (ctxt->input->id != id) {
pcercuei 0:03b5121a232e 6803 xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
pcercuei 0:03b5121a232e 6804 "All markup of the conditional section is not in the same entity\n",
pcercuei 0:03b5121a232e 6805 NULL, NULL);
pcercuei 0:03b5121a232e 6806 }
pcercuei 0:03b5121a232e 6807 NEXT;
pcercuei 0:03b5121a232e 6808 }
pcercuei 0:03b5121a232e 6809 if (xmlParserDebugEntities) {
pcercuei 0:03b5121a232e 6810 if ((ctxt->input != NULL) && (ctxt->input->filename))
pcercuei 0:03b5121a232e 6811 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 6812 "%s(%d): ", ctxt->input->filename,
pcercuei 0:03b5121a232e 6813 ctxt->input->line);
pcercuei 0:03b5121a232e 6814 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 6815 "Entering INCLUDE Conditional Section\n");
pcercuei 0:03b5121a232e 6816 }
pcercuei 0:03b5121a232e 6817
pcercuei 0:03b5121a232e 6818 while (((RAW != 0) && ((RAW != ']') || (NXT(1) != ']') ||
pcercuei 0:03b5121a232e 6819 (NXT(2) != '>'))) && (ctxt->instate != XML_PARSER_EOF)) {
pcercuei 0:03b5121a232e 6820 const xmlChar *check = CUR_PTR;
pcercuei 0:03b5121a232e 6821 unsigned int cons = ctxt->input->consumed;
pcercuei 0:03b5121a232e 6822
pcercuei 0:03b5121a232e 6823 if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
pcercuei 0:03b5121a232e 6824 xmlParseConditionalSections(ctxt);
pcercuei 0:03b5121a232e 6825 } else if (IS_BLANK_CH(CUR)) {
pcercuei 0:03b5121a232e 6826 NEXT;
pcercuei 0:03b5121a232e 6827 } else if (RAW == '%') {
pcercuei 0:03b5121a232e 6828 xmlParsePEReference(ctxt);
pcercuei 0:03b5121a232e 6829 } else
pcercuei 0:03b5121a232e 6830 xmlParseMarkupDecl(ctxt);
pcercuei 0:03b5121a232e 6831
pcercuei 0:03b5121a232e 6832 /*
pcercuei 0:03b5121a232e 6833 * Pop-up of finished entities.
pcercuei 0:03b5121a232e 6834 */
pcercuei 0:03b5121a232e 6835 while ((RAW == 0) && (ctxt->inputNr > 1))
pcercuei 0:03b5121a232e 6836 xmlPopInput(ctxt);
pcercuei 0:03b5121a232e 6837
pcercuei 0:03b5121a232e 6838 if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
pcercuei 0:03b5121a232e 6839 xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
pcercuei 0:03b5121a232e 6840 break;
pcercuei 0:03b5121a232e 6841 }
pcercuei 0:03b5121a232e 6842 }
pcercuei 0:03b5121a232e 6843 if (xmlParserDebugEntities) {
pcercuei 0:03b5121a232e 6844 if ((ctxt->input != NULL) && (ctxt->input->filename))
pcercuei 0:03b5121a232e 6845 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 6846 "%s(%d): ", ctxt->input->filename,
pcercuei 0:03b5121a232e 6847 ctxt->input->line);
pcercuei 0:03b5121a232e 6848 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 6849 "Leaving INCLUDE Conditional Section\n");
pcercuei 0:03b5121a232e 6850 }
pcercuei 0:03b5121a232e 6851
pcercuei 0:03b5121a232e 6852 } else if (CMP6(CUR_PTR, 'I', 'G', 'N', 'O', 'R', 'E')) {
pcercuei 0:03b5121a232e 6853 int state;
pcercuei 0:03b5121a232e 6854 xmlParserInputState instate;
pcercuei 0:03b5121a232e 6855 int depth = 0;
pcercuei 0:03b5121a232e 6856
pcercuei 0:03b5121a232e 6857 SKIP(6);
pcercuei 0:03b5121a232e 6858 SKIP_BLANKS;
pcercuei 0:03b5121a232e 6859 if (RAW != '[') {
pcercuei 0:03b5121a232e 6860 xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
pcercuei 0:03b5121a232e 6861 xmlHaltParser(ctxt);
pcercuei 0:03b5121a232e 6862 return;
pcercuei 0:03b5121a232e 6863 } else {
pcercuei 0:03b5121a232e 6864 if (ctxt->input->id != id) {
pcercuei 0:03b5121a232e 6865 xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
pcercuei 0:03b5121a232e 6866 "All markup of the conditional section is not in the same entity\n",
pcercuei 0:03b5121a232e 6867 NULL, NULL);
pcercuei 0:03b5121a232e 6868 }
pcercuei 0:03b5121a232e 6869 NEXT;
pcercuei 0:03b5121a232e 6870 }
pcercuei 0:03b5121a232e 6871 if (xmlParserDebugEntities) {
pcercuei 0:03b5121a232e 6872 if ((ctxt->input != NULL) && (ctxt->input->filename))
pcercuei 0:03b5121a232e 6873 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 6874 "%s(%d): ", ctxt->input->filename,
pcercuei 0:03b5121a232e 6875 ctxt->input->line);
pcercuei 0:03b5121a232e 6876 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 6877 "Entering IGNORE Conditional Section\n");
pcercuei 0:03b5121a232e 6878 }
pcercuei 0:03b5121a232e 6879
pcercuei 0:03b5121a232e 6880 /*
pcercuei 0:03b5121a232e 6881 * Parse up to the end of the conditional section
pcercuei 0:03b5121a232e 6882 * But disable SAX event generating DTD building in the meantime
pcercuei 0:03b5121a232e 6883 */
pcercuei 0:03b5121a232e 6884 state = ctxt->disableSAX;
pcercuei 0:03b5121a232e 6885 instate = ctxt->instate;
pcercuei 0:03b5121a232e 6886 if (ctxt->recovery == 0) ctxt->disableSAX = 1;
pcercuei 0:03b5121a232e 6887 ctxt->instate = XML_PARSER_IGNORE;
pcercuei 0:03b5121a232e 6888
pcercuei 0:03b5121a232e 6889 while (((depth >= 0) && (RAW != 0)) &&
pcercuei 0:03b5121a232e 6890 (ctxt->instate != XML_PARSER_EOF)) {
pcercuei 0:03b5121a232e 6891 if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
pcercuei 0:03b5121a232e 6892 depth++;
pcercuei 0:03b5121a232e 6893 SKIP(3);
pcercuei 0:03b5121a232e 6894 continue;
pcercuei 0:03b5121a232e 6895 }
pcercuei 0:03b5121a232e 6896 if ((RAW == ']') && (NXT(1) == ']') && (NXT(2) == '>')) {
pcercuei 0:03b5121a232e 6897 if (--depth >= 0) SKIP(3);
pcercuei 0:03b5121a232e 6898 continue;
pcercuei 0:03b5121a232e 6899 }
pcercuei 0:03b5121a232e 6900 NEXT;
pcercuei 0:03b5121a232e 6901 continue;
pcercuei 0:03b5121a232e 6902 }
pcercuei 0:03b5121a232e 6903
pcercuei 0:03b5121a232e 6904 ctxt->disableSAX = state;
pcercuei 0:03b5121a232e 6905 ctxt->instate = instate;
pcercuei 0:03b5121a232e 6906
pcercuei 0:03b5121a232e 6907 if (xmlParserDebugEntities) {
pcercuei 0:03b5121a232e 6908 if ((ctxt->input != NULL) && (ctxt->input->filename))
pcercuei 0:03b5121a232e 6909 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 6910 "%s(%d): ", ctxt->input->filename,
pcercuei 0:03b5121a232e 6911 ctxt->input->line);
pcercuei 0:03b5121a232e 6912 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 6913 "Leaving IGNORE Conditional Section\n");
pcercuei 0:03b5121a232e 6914 }
pcercuei 0:03b5121a232e 6915
pcercuei 0:03b5121a232e 6916 } else {
pcercuei 0:03b5121a232e 6917 xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID_KEYWORD, NULL);
pcercuei 0:03b5121a232e 6918 xmlHaltParser(ctxt);
pcercuei 0:03b5121a232e 6919 return;
pcercuei 0:03b5121a232e 6920 }
pcercuei 0:03b5121a232e 6921
pcercuei 0:03b5121a232e 6922 if (RAW == 0)
pcercuei 0:03b5121a232e 6923 SHRINK;
pcercuei 0:03b5121a232e 6924
pcercuei 0:03b5121a232e 6925 if (RAW == 0) {
pcercuei 0:03b5121a232e 6926 xmlFatalErr(ctxt, XML_ERR_CONDSEC_NOT_FINISHED, NULL);
pcercuei 0:03b5121a232e 6927 } else {
pcercuei 0:03b5121a232e 6928 if (ctxt->input->id != id) {
pcercuei 0:03b5121a232e 6929 xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
pcercuei 0:03b5121a232e 6930 "All markup of the conditional section is not in the same entity\n",
pcercuei 0:03b5121a232e 6931 NULL, NULL);
pcercuei 0:03b5121a232e 6932 }
pcercuei 0:03b5121a232e 6933 if ((ctxt-> instate != XML_PARSER_EOF) &&
pcercuei 0:03b5121a232e 6934 ((ctxt->input->cur + 3) <= ctxt->input->end))
pcercuei 0:03b5121a232e 6935 SKIP(3);
pcercuei 0:03b5121a232e 6936 }
pcercuei 0:03b5121a232e 6937 }
pcercuei 0:03b5121a232e 6938
pcercuei 0:03b5121a232e 6939 /**
pcercuei 0:03b5121a232e 6940 * xmlParseMarkupDecl:
pcercuei 0:03b5121a232e 6941 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 6942 *
pcercuei 0:03b5121a232e 6943 * parse Markup declarations
pcercuei 0:03b5121a232e 6944 *
pcercuei 0:03b5121a232e 6945 * [29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl |
pcercuei 0:03b5121a232e 6946 * NotationDecl | PI | Comment
pcercuei 0:03b5121a232e 6947 *
pcercuei 0:03b5121a232e 6948 * [ VC: Proper Declaration/PE Nesting ]
pcercuei 0:03b5121a232e 6949 * Parameter-entity replacement text must be properly nested with
pcercuei 0:03b5121a232e 6950 * markup declarations. That is to say, if either the first character
pcercuei 0:03b5121a232e 6951 * or the last character of a markup declaration (markupdecl above) is
pcercuei 0:03b5121a232e 6952 * contained in the replacement text for a parameter-entity reference,
pcercuei 0:03b5121a232e 6953 * both must be contained in the same replacement text.
pcercuei 0:03b5121a232e 6954 *
pcercuei 0:03b5121a232e 6955 * [ WFC: PEs in Internal Subset ]
pcercuei 0:03b5121a232e 6956 * In the internal DTD subset, parameter-entity references can occur
pcercuei 0:03b5121a232e 6957 * only where markup declarations can occur, not within markup declarations.
pcercuei 0:03b5121a232e 6958 * (This does not apply to references that occur in external parameter
pcercuei 0:03b5121a232e 6959 * entities or to the external subset.)
pcercuei 0:03b5121a232e 6960 */
pcercuei 0:03b5121a232e 6961 void
pcercuei 0:03b5121a232e 6962 xmlParseMarkupDecl(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 6963 GROW;
pcercuei 0:03b5121a232e 6964 if (CUR == '<') {
pcercuei 0:03b5121a232e 6965 if (NXT(1) == '!') {
pcercuei 0:03b5121a232e 6966 switch (NXT(2)) {
pcercuei 0:03b5121a232e 6967 case 'E':
pcercuei 0:03b5121a232e 6968 if (NXT(3) == 'L')
pcercuei 0:03b5121a232e 6969 xmlParseElementDecl(ctxt);
pcercuei 0:03b5121a232e 6970 else if (NXT(3) == 'N')
pcercuei 0:03b5121a232e 6971 xmlParseEntityDecl(ctxt);
pcercuei 0:03b5121a232e 6972 break;
pcercuei 0:03b5121a232e 6973 case 'A':
pcercuei 0:03b5121a232e 6974 xmlParseAttributeListDecl(ctxt);
pcercuei 0:03b5121a232e 6975 break;
pcercuei 0:03b5121a232e 6976 case 'N':
pcercuei 0:03b5121a232e 6977 xmlParseNotationDecl(ctxt);
pcercuei 0:03b5121a232e 6978 break;
pcercuei 0:03b5121a232e 6979 case '-':
pcercuei 0:03b5121a232e 6980 xmlParseComment(ctxt);
pcercuei 0:03b5121a232e 6981 break;
pcercuei 0:03b5121a232e 6982 default:
pcercuei 0:03b5121a232e 6983 /* there is an error but it will be detected later */
pcercuei 0:03b5121a232e 6984 break;
pcercuei 0:03b5121a232e 6985 }
pcercuei 0:03b5121a232e 6986 } else if (NXT(1) == '?') {
pcercuei 0:03b5121a232e 6987 xmlParsePI(ctxt);
pcercuei 0:03b5121a232e 6988 }
pcercuei 0:03b5121a232e 6989 }
pcercuei 0:03b5121a232e 6990
pcercuei 0:03b5121a232e 6991 /*
pcercuei 0:03b5121a232e 6992 * detect requirement to exit there and act accordingly
pcercuei 0:03b5121a232e 6993 * and avoid having instate overriden later on
pcercuei 0:03b5121a232e 6994 */
pcercuei 0:03b5121a232e 6995 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 6996 return;
pcercuei 0:03b5121a232e 6997
pcercuei 0:03b5121a232e 6998 /*
pcercuei 0:03b5121a232e 6999 * This is only for internal subset. On external entities,
pcercuei 0:03b5121a232e 7000 * the replacement is done before parsing stage
pcercuei 0:03b5121a232e 7001 */
pcercuei 0:03b5121a232e 7002 if ((ctxt->external == 0) && (ctxt->inputNr == 1))
pcercuei 0:03b5121a232e 7003 xmlParsePEReference(ctxt);
pcercuei 0:03b5121a232e 7004
pcercuei 0:03b5121a232e 7005 /*
pcercuei 0:03b5121a232e 7006 * Conditional sections are allowed from entities included
pcercuei 0:03b5121a232e 7007 * by PE References in the internal subset.
pcercuei 0:03b5121a232e 7008 */
pcercuei 0:03b5121a232e 7009 if ((ctxt->external == 0) && (ctxt->inputNr > 1)) {
pcercuei 0:03b5121a232e 7010 if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
pcercuei 0:03b5121a232e 7011 xmlParseConditionalSections(ctxt);
pcercuei 0:03b5121a232e 7012 }
pcercuei 0:03b5121a232e 7013 }
pcercuei 0:03b5121a232e 7014
pcercuei 0:03b5121a232e 7015 ctxt->instate = XML_PARSER_DTD;
pcercuei 0:03b5121a232e 7016 }
pcercuei 0:03b5121a232e 7017
pcercuei 0:03b5121a232e 7018 /**
pcercuei 0:03b5121a232e 7019 * xmlParseTextDecl:
pcercuei 0:03b5121a232e 7020 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 7021 *
pcercuei 0:03b5121a232e 7022 * parse an XML declaration header for external entities
pcercuei 0:03b5121a232e 7023 *
pcercuei 0:03b5121a232e 7024 * [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
pcercuei 0:03b5121a232e 7025 */
pcercuei 0:03b5121a232e 7026
pcercuei 0:03b5121a232e 7027 void
pcercuei 0:03b5121a232e 7028 xmlParseTextDecl(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 7029 xmlChar *version;
pcercuei 0:03b5121a232e 7030 const xmlChar *encoding;
pcercuei 0:03b5121a232e 7031
pcercuei 0:03b5121a232e 7032 /*
pcercuei 0:03b5121a232e 7033 * We know that '<?xml' is here.
pcercuei 0:03b5121a232e 7034 */
pcercuei 0:03b5121a232e 7035 if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
pcercuei 0:03b5121a232e 7036 SKIP(5);
pcercuei 0:03b5121a232e 7037 } else {
pcercuei 0:03b5121a232e 7038 xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_STARTED, NULL);
pcercuei 0:03b5121a232e 7039 return;
pcercuei 0:03b5121a232e 7040 }
pcercuei 0:03b5121a232e 7041
pcercuei 0:03b5121a232e 7042 if (!IS_BLANK_CH(CUR)) {
pcercuei 0:03b5121a232e 7043 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
pcercuei 0:03b5121a232e 7044 "Space needed after '<?xml'\n");
pcercuei 0:03b5121a232e 7045 }
pcercuei 0:03b5121a232e 7046 SKIP_BLANKS;
pcercuei 0:03b5121a232e 7047
pcercuei 0:03b5121a232e 7048 /*
pcercuei 0:03b5121a232e 7049 * We may have the VersionInfo here.
pcercuei 0:03b5121a232e 7050 */
pcercuei 0:03b5121a232e 7051 version = xmlParseVersionInfo(ctxt);
pcercuei 0:03b5121a232e 7052 if (version == NULL)
pcercuei 0:03b5121a232e 7053 version = xmlCharStrdup(XML_DEFAULT_VERSION);
pcercuei 0:03b5121a232e 7054 else {
pcercuei 0:03b5121a232e 7055 if (!IS_BLANK_CH(CUR)) {
pcercuei 0:03b5121a232e 7056 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
pcercuei 0:03b5121a232e 7057 "Space needed here\n");
pcercuei 0:03b5121a232e 7058 }
pcercuei 0:03b5121a232e 7059 }
pcercuei 0:03b5121a232e 7060 ctxt->input->version = version;
pcercuei 0:03b5121a232e 7061
pcercuei 0:03b5121a232e 7062 /*
pcercuei 0:03b5121a232e 7063 * We must have the encoding declaration
pcercuei 0:03b5121a232e 7064 */
pcercuei 0:03b5121a232e 7065 encoding = xmlParseEncodingDecl(ctxt);
pcercuei 0:03b5121a232e 7066 if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
pcercuei 0:03b5121a232e 7067 /*
pcercuei 0:03b5121a232e 7068 * The XML REC instructs us to stop parsing right here
pcercuei 0:03b5121a232e 7069 */
pcercuei 0:03b5121a232e 7070 return;
pcercuei 0:03b5121a232e 7071 }
pcercuei 0:03b5121a232e 7072 if ((encoding == NULL) && (ctxt->errNo == XML_ERR_OK)) {
pcercuei 0:03b5121a232e 7073 xmlFatalErrMsg(ctxt, XML_ERR_MISSING_ENCODING,
pcercuei 0:03b5121a232e 7074 "Missing encoding in text declaration\n");
pcercuei 0:03b5121a232e 7075 }
pcercuei 0:03b5121a232e 7076
pcercuei 0:03b5121a232e 7077 SKIP_BLANKS;
pcercuei 0:03b5121a232e 7078 if ((RAW == '?') && (NXT(1) == '>')) {
pcercuei 0:03b5121a232e 7079 SKIP(2);
pcercuei 0:03b5121a232e 7080 } else if (RAW == '>') {
pcercuei 0:03b5121a232e 7081 /* Deprecated old WD ... */
pcercuei 0:03b5121a232e 7082 xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
pcercuei 0:03b5121a232e 7083 NEXT;
pcercuei 0:03b5121a232e 7084 } else {
pcercuei 0:03b5121a232e 7085 xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
pcercuei 0:03b5121a232e 7086 MOVETO_ENDTAG(CUR_PTR);
pcercuei 0:03b5121a232e 7087 NEXT;
pcercuei 0:03b5121a232e 7088 }
pcercuei 0:03b5121a232e 7089 }
pcercuei 0:03b5121a232e 7090
pcercuei 0:03b5121a232e 7091 /**
pcercuei 0:03b5121a232e 7092 * xmlParseExternalSubset:
pcercuei 0:03b5121a232e 7093 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 7094 * @ExternalID: the external identifier
pcercuei 0:03b5121a232e 7095 * @SystemID: the system identifier (or URL)
pcercuei 0:03b5121a232e 7096 *
pcercuei 0:03b5121a232e 7097 * parse Markup declarations from an external subset
pcercuei 0:03b5121a232e 7098 *
pcercuei 0:03b5121a232e 7099 * [30] extSubset ::= textDecl? extSubsetDecl
pcercuei 0:03b5121a232e 7100 *
pcercuei 0:03b5121a232e 7101 * [31] extSubsetDecl ::= (markupdecl | conditionalSect | PEReference | S) *
pcercuei 0:03b5121a232e 7102 */
pcercuei 0:03b5121a232e 7103 void
pcercuei 0:03b5121a232e 7104 xmlParseExternalSubset(xmlParserCtxtPtr ctxt, const xmlChar *ExternalID,
pcercuei 0:03b5121a232e 7105 const xmlChar *SystemID) {
pcercuei 0:03b5121a232e 7106 xmlDetectSAX2(ctxt);
pcercuei 0:03b5121a232e 7107 GROW;
pcercuei 0:03b5121a232e 7108
pcercuei 0:03b5121a232e 7109 if ((ctxt->encoding == NULL) &&
pcercuei 0:03b5121a232e 7110 (ctxt->input->end - ctxt->input->cur >= 4)) {
pcercuei 0:03b5121a232e 7111 xmlChar start[4];
pcercuei 0:03b5121a232e 7112 xmlCharEncoding enc;
pcercuei 0:03b5121a232e 7113
pcercuei 0:03b5121a232e 7114 start[0] = RAW;
pcercuei 0:03b5121a232e 7115 start[1] = NXT(1);
pcercuei 0:03b5121a232e 7116 start[2] = NXT(2);
pcercuei 0:03b5121a232e 7117 start[3] = NXT(3);
pcercuei 0:03b5121a232e 7118 enc = xmlDetectCharEncoding(start, 4);
pcercuei 0:03b5121a232e 7119 if (enc != XML_CHAR_ENCODING_NONE)
pcercuei 0:03b5121a232e 7120 xmlSwitchEncoding(ctxt, enc);
pcercuei 0:03b5121a232e 7121 }
pcercuei 0:03b5121a232e 7122
pcercuei 0:03b5121a232e 7123 if (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) {
pcercuei 0:03b5121a232e 7124 xmlParseTextDecl(ctxt);
pcercuei 0:03b5121a232e 7125 if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
pcercuei 0:03b5121a232e 7126 /*
pcercuei 0:03b5121a232e 7127 * The XML REC instructs us to stop parsing right here
pcercuei 0:03b5121a232e 7128 */
pcercuei 0:03b5121a232e 7129 xmlHaltParser(ctxt);
pcercuei 0:03b5121a232e 7130 return;
pcercuei 0:03b5121a232e 7131 }
pcercuei 0:03b5121a232e 7132 }
pcercuei 0:03b5121a232e 7133 if (ctxt->myDoc == NULL) {
pcercuei 0:03b5121a232e 7134 ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
pcercuei 0:03b5121a232e 7135 if (ctxt->myDoc == NULL) {
pcercuei 0:03b5121a232e 7136 xmlErrMemory(ctxt, "New Doc failed");
pcercuei 0:03b5121a232e 7137 return;
pcercuei 0:03b5121a232e 7138 }
pcercuei 0:03b5121a232e 7139 ctxt->myDoc->properties = XML_DOC_INTERNAL;
pcercuei 0:03b5121a232e 7140 }
pcercuei 0:03b5121a232e 7141 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->intSubset == NULL))
pcercuei 0:03b5121a232e 7142 xmlCreateIntSubset(ctxt->myDoc, NULL, ExternalID, SystemID);
pcercuei 0:03b5121a232e 7143
pcercuei 0:03b5121a232e 7144 ctxt->instate = XML_PARSER_DTD;
pcercuei 0:03b5121a232e 7145 ctxt->external = 1;
pcercuei 0:03b5121a232e 7146 while (((RAW == '<') && (NXT(1) == '?')) ||
pcercuei 0:03b5121a232e 7147 ((RAW == '<') && (NXT(1) == '!')) ||
pcercuei 0:03b5121a232e 7148 (RAW == '%') || IS_BLANK_CH(CUR)) {
pcercuei 0:03b5121a232e 7149 const xmlChar *check = CUR_PTR;
pcercuei 0:03b5121a232e 7150 unsigned int cons = ctxt->input->consumed;
pcercuei 0:03b5121a232e 7151
pcercuei 0:03b5121a232e 7152 GROW;
pcercuei 0:03b5121a232e 7153 if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
pcercuei 0:03b5121a232e 7154 xmlParseConditionalSections(ctxt);
pcercuei 0:03b5121a232e 7155 } else if (IS_BLANK_CH(CUR)) {
pcercuei 0:03b5121a232e 7156 NEXT;
pcercuei 0:03b5121a232e 7157 } else if (RAW == '%') {
pcercuei 0:03b5121a232e 7158 xmlParsePEReference(ctxt);
pcercuei 0:03b5121a232e 7159 } else
pcercuei 0:03b5121a232e 7160 xmlParseMarkupDecl(ctxt);
pcercuei 0:03b5121a232e 7161
pcercuei 0:03b5121a232e 7162 /*
pcercuei 0:03b5121a232e 7163 * Pop-up of finished entities.
pcercuei 0:03b5121a232e 7164 */
pcercuei 0:03b5121a232e 7165 while ((RAW == 0) && (ctxt->inputNr > 1))
pcercuei 0:03b5121a232e 7166 xmlPopInput(ctxt);
pcercuei 0:03b5121a232e 7167
pcercuei 0:03b5121a232e 7168 if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
pcercuei 0:03b5121a232e 7169 xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
pcercuei 0:03b5121a232e 7170 break;
pcercuei 0:03b5121a232e 7171 }
pcercuei 0:03b5121a232e 7172 }
pcercuei 0:03b5121a232e 7173
pcercuei 0:03b5121a232e 7174 if (RAW != 0) {
pcercuei 0:03b5121a232e 7175 xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
pcercuei 0:03b5121a232e 7176 }
pcercuei 0:03b5121a232e 7177
pcercuei 0:03b5121a232e 7178 }
pcercuei 0:03b5121a232e 7179
pcercuei 0:03b5121a232e 7180 /**
pcercuei 0:03b5121a232e 7181 * xmlParseReference:
pcercuei 0:03b5121a232e 7182 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 7183 *
pcercuei 0:03b5121a232e 7184 * parse and handle entity references in content, depending on the SAX
pcercuei 0:03b5121a232e 7185 * interface, this may end-up in a call to character() if this is a
pcercuei 0:03b5121a232e 7186 * CharRef, a predefined entity, if there is no reference() callback.
pcercuei 0:03b5121a232e 7187 * or if the parser was asked to switch to that mode.
pcercuei 0:03b5121a232e 7188 *
pcercuei 0:03b5121a232e 7189 * [67] Reference ::= EntityRef | CharRef
pcercuei 0:03b5121a232e 7190 */
pcercuei 0:03b5121a232e 7191 void
pcercuei 0:03b5121a232e 7192 xmlParseReference(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 7193 xmlEntityPtr ent;
pcercuei 0:03b5121a232e 7194 xmlChar *val;
pcercuei 0:03b5121a232e 7195 int was_checked;
pcercuei 0:03b5121a232e 7196 xmlNodePtr list = NULL;
pcercuei 0:03b5121a232e 7197 xmlParserErrors ret = XML_ERR_OK;
pcercuei 0:03b5121a232e 7198
pcercuei 0:03b5121a232e 7199
pcercuei 0:03b5121a232e 7200 if (RAW != '&')
pcercuei 0:03b5121a232e 7201 return;
pcercuei 0:03b5121a232e 7202
pcercuei 0:03b5121a232e 7203 /*
pcercuei 0:03b5121a232e 7204 * Simple case of a CharRef
pcercuei 0:03b5121a232e 7205 */
pcercuei 0:03b5121a232e 7206 if (NXT(1) == '#') {
pcercuei 0:03b5121a232e 7207 int i = 0;
pcercuei 0:03b5121a232e 7208 xmlChar out[10];
pcercuei 0:03b5121a232e 7209 int hex = NXT(2);
pcercuei 0:03b5121a232e 7210 int value = xmlParseCharRef(ctxt);
pcercuei 0:03b5121a232e 7211
pcercuei 0:03b5121a232e 7212 if (value == 0)
pcercuei 0:03b5121a232e 7213 return;
pcercuei 0:03b5121a232e 7214 if (ctxt->charset != XML_CHAR_ENCODING_UTF8) {
pcercuei 0:03b5121a232e 7215 /*
pcercuei 0:03b5121a232e 7216 * So we are using non-UTF-8 buffers
pcercuei 0:03b5121a232e 7217 * Check that the char fit on 8bits, if not
pcercuei 0:03b5121a232e 7218 * generate a CharRef.
pcercuei 0:03b5121a232e 7219 */
pcercuei 0:03b5121a232e 7220 if (value <= 0xFF) {
pcercuei 0:03b5121a232e 7221 out[0] = value;
pcercuei 0:03b5121a232e 7222 out[1] = 0;
pcercuei 0:03b5121a232e 7223 if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
pcercuei 0:03b5121a232e 7224 (!ctxt->disableSAX))
pcercuei 0:03b5121a232e 7225 ctxt->sax->characters(ctxt->userData, out, 1);
pcercuei 0:03b5121a232e 7226 } else {
pcercuei 0:03b5121a232e 7227 if ((hex == 'x') || (hex == 'X'))
pcercuei 0:03b5121a232e 7228 snprintf((char *)out, sizeof(out), "#x%X", value);
pcercuei 0:03b5121a232e 7229 else
pcercuei 0:03b5121a232e 7230 snprintf((char *)out, sizeof(out), "#%d", value);
pcercuei 0:03b5121a232e 7231 if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
pcercuei 0:03b5121a232e 7232 (!ctxt->disableSAX))
pcercuei 0:03b5121a232e 7233 ctxt->sax->reference(ctxt->userData, out);
pcercuei 0:03b5121a232e 7234 }
pcercuei 0:03b5121a232e 7235 } else {
pcercuei 0:03b5121a232e 7236 /*
pcercuei 0:03b5121a232e 7237 * Just encode the value in UTF-8
pcercuei 0:03b5121a232e 7238 */
pcercuei 0:03b5121a232e 7239 COPY_BUF(0 ,out, i, value);
pcercuei 0:03b5121a232e 7240 out[i] = 0;
pcercuei 0:03b5121a232e 7241 if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
pcercuei 0:03b5121a232e 7242 (!ctxt->disableSAX))
pcercuei 0:03b5121a232e 7243 ctxt->sax->characters(ctxt->userData, out, i);
pcercuei 0:03b5121a232e 7244 }
pcercuei 0:03b5121a232e 7245 return;
pcercuei 0:03b5121a232e 7246 }
pcercuei 0:03b5121a232e 7247
pcercuei 0:03b5121a232e 7248 /*
pcercuei 0:03b5121a232e 7249 * We are seeing an entity reference
pcercuei 0:03b5121a232e 7250 */
pcercuei 0:03b5121a232e 7251 ent = xmlParseEntityRef(ctxt);
pcercuei 0:03b5121a232e 7252 if (ent == NULL) return;
pcercuei 0:03b5121a232e 7253 if (!ctxt->wellFormed)
pcercuei 0:03b5121a232e 7254 return;
pcercuei 0:03b5121a232e 7255 was_checked = ent->checked;
pcercuei 0:03b5121a232e 7256
pcercuei 0:03b5121a232e 7257 /* special case of predefined entities */
pcercuei 0:03b5121a232e 7258 if ((ent->name == NULL) ||
pcercuei 0:03b5121a232e 7259 (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
pcercuei 0:03b5121a232e 7260 val = ent->content;
pcercuei 0:03b5121a232e 7261 if (val == NULL) return;
pcercuei 0:03b5121a232e 7262 /*
pcercuei 0:03b5121a232e 7263 * inline the entity.
pcercuei 0:03b5121a232e 7264 */
pcercuei 0:03b5121a232e 7265 if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
pcercuei 0:03b5121a232e 7266 (!ctxt->disableSAX))
pcercuei 0:03b5121a232e 7267 ctxt->sax->characters(ctxt->userData, val, xmlStrlen(val));
pcercuei 0:03b5121a232e 7268 return;
pcercuei 0:03b5121a232e 7269 }
pcercuei 0:03b5121a232e 7270
pcercuei 0:03b5121a232e 7271 /*
pcercuei 0:03b5121a232e 7272 * The first reference to the entity trigger a parsing phase
pcercuei 0:03b5121a232e 7273 * where the ent->children is filled with the result from
pcercuei 0:03b5121a232e 7274 * the parsing.
pcercuei 0:03b5121a232e 7275 * Note: external parsed entities will not be loaded, it is not
pcercuei 0:03b5121a232e 7276 * required for a non-validating parser, unless the parsing option
pcercuei 0:03b5121a232e 7277 * of validating, or substituting entities were given. Doing so is
pcercuei 0:03b5121a232e 7278 * far more secure as the parser will only process data coming from
pcercuei 0:03b5121a232e 7279 * the document entity by default.
pcercuei 0:03b5121a232e 7280 */
pcercuei 0:03b5121a232e 7281 if (((ent->checked == 0) ||
pcercuei 0:03b5121a232e 7282 ((ent->children == NULL) && (ctxt->options & XML_PARSE_NOENT))) &&
pcercuei 0:03b5121a232e 7283 ((ent->etype != XML_EXTERNAL_GENERAL_PARSED_ENTITY) ||
pcercuei 0:03b5121a232e 7284 (ctxt->options & (XML_PARSE_NOENT | XML_PARSE_DTDVALID)))) {
pcercuei 0:03b5121a232e 7285 unsigned long oldnbent = ctxt->nbentities;
pcercuei 0:03b5121a232e 7286
pcercuei 0:03b5121a232e 7287 /*
pcercuei 0:03b5121a232e 7288 * This is a bit hackish but this seems the best
pcercuei 0:03b5121a232e 7289 * way to make sure both SAX and DOM entity support
pcercuei 0:03b5121a232e 7290 * behaves okay.
pcercuei 0:03b5121a232e 7291 */
pcercuei 0:03b5121a232e 7292 void *user_data;
pcercuei 0:03b5121a232e 7293 if (ctxt->userData == ctxt)
pcercuei 0:03b5121a232e 7294 user_data = NULL;
pcercuei 0:03b5121a232e 7295 else
pcercuei 0:03b5121a232e 7296 user_data = ctxt->userData;
pcercuei 0:03b5121a232e 7297
pcercuei 0:03b5121a232e 7298 /*
pcercuei 0:03b5121a232e 7299 * Check that this entity is well formed
pcercuei 0:03b5121a232e 7300 * 4.3.2: An internal general parsed entity is well-formed
pcercuei 0:03b5121a232e 7301 * if its replacement text matches the production labeled
pcercuei 0:03b5121a232e 7302 * content.
pcercuei 0:03b5121a232e 7303 */
pcercuei 0:03b5121a232e 7304 if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
pcercuei 0:03b5121a232e 7305 ctxt->depth++;
pcercuei 0:03b5121a232e 7306 ret = xmlParseBalancedChunkMemoryInternal(ctxt, ent->content,
pcercuei 0:03b5121a232e 7307 user_data, &list);
pcercuei 0:03b5121a232e 7308 ctxt->depth--;
pcercuei 0:03b5121a232e 7309
pcercuei 0:03b5121a232e 7310 } else if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
pcercuei 0:03b5121a232e 7311 ctxt->depth++;
pcercuei 0:03b5121a232e 7312 ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt, ctxt->sax,
pcercuei 0:03b5121a232e 7313 user_data, ctxt->depth, ent->URI,
pcercuei 0:03b5121a232e 7314 ent->ExternalID, &list);
pcercuei 0:03b5121a232e 7315 ctxt->depth--;
pcercuei 0:03b5121a232e 7316 } else {
pcercuei 0:03b5121a232e 7317 ret = XML_ERR_ENTITY_PE_INTERNAL;
pcercuei 0:03b5121a232e 7318 xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
pcercuei 0:03b5121a232e 7319 "invalid entity type found\n", NULL);
pcercuei 0:03b5121a232e 7320 }
pcercuei 0:03b5121a232e 7321
pcercuei 0:03b5121a232e 7322 /*
pcercuei 0:03b5121a232e 7323 * Store the number of entities needing parsing for this entity
pcercuei 0:03b5121a232e 7324 * content and do checkings
pcercuei 0:03b5121a232e 7325 */
pcercuei 0:03b5121a232e 7326 ent->checked = (ctxt->nbentities - oldnbent + 1) * 2;
pcercuei 0:03b5121a232e 7327 if ((ent->content != NULL) && (xmlStrchr(ent->content, '<')))
pcercuei 0:03b5121a232e 7328 ent->checked |= 1;
pcercuei 0:03b5121a232e 7329 if (ret == XML_ERR_ENTITY_LOOP) {
pcercuei 0:03b5121a232e 7330 xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
pcercuei 0:03b5121a232e 7331 xmlFreeNodeList(list);
pcercuei 0:03b5121a232e 7332 return;
pcercuei 0:03b5121a232e 7333 }
pcercuei 0:03b5121a232e 7334 if (xmlParserEntityCheck(ctxt, 0, ent, 0)) {
pcercuei 0:03b5121a232e 7335 xmlFreeNodeList(list);
pcercuei 0:03b5121a232e 7336 return;
pcercuei 0:03b5121a232e 7337 }
pcercuei 0:03b5121a232e 7338
pcercuei 0:03b5121a232e 7339 if ((ret == XML_ERR_OK) && (list != NULL)) {
pcercuei 0:03b5121a232e 7340 if (((ent->etype == XML_INTERNAL_GENERAL_ENTITY) ||
pcercuei 0:03b5121a232e 7341 (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY))&&
pcercuei 0:03b5121a232e 7342 (ent->children == NULL)) {
pcercuei 0:03b5121a232e 7343 ent->children = list;
pcercuei 0:03b5121a232e 7344 if (ctxt->replaceEntities) {
pcercuei 0:03b5121a232e 7345 /*
pcercuei 0:03b5121a232e 7346 * Prune it directly in the generated document
pcercuei 0:03b5121a232e 7347 * except for single text nodes.
pcercuei 0:03b5121a232e 7348 */
pcercuei 0:03b5121a232e 7349 if (((list->type == XML_TEXT_NODE) &&
pcercuei 0:03b5121a232e 7350 (list->next == NULL)) ||
pcercuei 0:03b5121a232e 7351 (ctxt->parseMode == XML_PARSE_READER)) {
pcercuei 0:03b5121a232e 7352 list->parent = (xmlNodePtr) ent;
pcercuei 0:03b5121a232e 7353 list = NULL;
pcercuei 0:03b5121a232e 7354 ent->owner = 1;
pcercuei 0:03b5121a232e 7355 } else {
pcercuei 0:03b5121a232e 7356 ent->owner = 0;
pcercuei 0:03b5121a232e 7357 while (list != NULL) {
pcercuei 0:03b5121a232e 7358 list->parent = (xmlNodePtr) ctxt->node;
pcercuei 0:03b5121a232e 7359 list->doc = ctxt->myDoc;
pcercuei 0:03b5121a232e 7360 if (list->next == NULL)
pcercuei 0:03b5121a232e 7361 ent->last = list;
pcercuei 0:03b5121a232e 7362 list = list->next;
pcercuei 0:03b5121a232e 7363 }
pcercuei 0:03b5121a232e 7364 list = ent->children;
pcercuei 0:03b5121a232e 7365 #ifdef LIBXML_LEGACY_ENABLED
pcercuei 0:03b5121a232e 7366 if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
pcercuei 0:03b5121a232e 7367 xmlAddEntityReference(ent, list, NULL);
pcercuei 0:03b5121a232e 7368 #endif /* LIBXML_LEGACY_ENABLED */
pcercuei 0:03b5121a232e 7369 }
pcercuei 0:03b5121a232e 7370 } else {
pcercuei 0:03b5121a232e 7371 ent->owner = 1;
pcercuei 0:03b5121a232e 7372 while (list != NULL) {
pcercuei 0:03b5121a232e 7373 list->parent = (xmlNodePtr) ent;
pcercuei 0:03b5121a232e 7374 xmlSetTreeDoc(list, ent->doc);
pcercuei 0:03b5121a232e 7375 if (list->next == NULL)
pcercuei 0:03b5121a232e 7376 ent->last = list;
pcercuei 0:03b5121a232e 7377 list = list->next;
pcercuei 0:03b5121a232e 7378 }
pcercuei 0:03b5121a232e 7379 }
pcercuei 0:03b5121a232e 7380 } else {
pcercuei 0:03b5121a232e 7381 xmlFreeNodeList(list);
pcercuei 0:03b5121a232e 7382 list = NULL;
pcercuei 0:03b5121a232e 7383 }
pcercuei 0:03b5121a232e 7384 } else if ((ret != XML_ERR_OK) &&
pcercuei 0:03b5121a232e 7385 (ret != XML_WAR_UNDECLARED_ENTITY)) {
pcercuei 0:03b5121a232e 7386 xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
pcercuei 0:03b5121a232e 7387 "Entity '%s' failed to parse\n", ent->name);
pcercuei 0:03b5121a232e 7388 xmlParserEntityCheck(ctxt, 0, ent, 0);
pcercuei 0:03b5121a232e 7389 } else if (list != NULL) {
pcercuei 0:03b5121a232e 7390 xmlFreeNodeList(list);
pcercuei 0:03b5121a232e 7391 list = NULL;
pcercuei 0:03b5121a232e 7392 }
pcercuei 0:03b5121a232e 7393 if (ent->checked == 0)
pcercuei 0:03b5121a232e 7394 ent->checked = 2;
pcercuei 0:03b5121a232e 7395 } else if (ent->checked != 1) {
pcercuei 0:03b5121a232e 7396 ctxt->nbentities += ent->checked / 2;
pcercuei 0:03b5121a232e 7397 }
pcercuei 0:03b5121a232e 7398
pcercuei 0:03b5121a232e 7399 /*
pcercuei 0:03b5121a232e 7400 * Now that the entity content has been gathered
pcercuei 0:03b5121a232e 7401 * provide it to the application, this can take different forms based
pcercuei 0:03b5121a232e 7402 * on the parsing modes.
pcercuei 0:03b5121a232e 7403 */
pcercuei 0:03b5121a232e 7404 if (ent->children == NULL) {
pcercuei 0:03b5121a232e 7405 /*
pcercuei 0:03b5121a232e 7406 * Probably running in SAX mode and the callbacks don't
pcercuei 0:03b5121a232e 7407 * build the entity content. So unless we already went
pcercuei 0:03b5121a232e 7408 * though parsing for first checking go though the entity
pcercuei 0:03b5121a232e 7409 * content to generate callbacks associated to the entity
pcercuei 0:03b5121a232e 7410 */
pcercuei 0:03b5121a232e 7411 if (was_checked != 0) {
pcercuei 0:03b5121a232e 7412 void *user_data;
pcercuei 0:03b5121a232e 7413 /*
pcercuei 0:03b5121a232e 7414 * This is a bit hackish but this seems the best
pcercuei 0:03b5121a232e 7415 * way to make sure both SAX and DOM entity support
pcercuei 0:03b5121a232e 7416 * behaves okay.
pcercuei 0:03b5121a232e 7417 */
pcercuei 0:03b5121a232e 7418 if (ctxt->userData == ctxt)
pcercuei 0:03b5121a232e 7419 user_data = NULL;
pcercuei 0:03b5121a232e 7420 else
pcercuei 0:03b5121a232e 7421 user_data = ctxt->userData;
pcercuei 0:03b5121a232e 7422
pcercuei 0:03b5121a232e 7423 if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
pcercuei 0:03b5121a232e 7424 ctxt->depth++;
pcercuei 0:03b5121a232e 7425 ret = xmlParseBalancedChunkMemoryInternal(ctxt,
pcercuei 0:03b5121a232e 7426 ent->content, user_data, NULL);
pcercuei 0:03b5121a232e 7427 ctxt->depth--;
pcercuei 0:03b5121a232e 7428 } else if (ent->etype ==
pcercuei 0:03b5121a232e 7429 XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
pcercuei 0:03b5121a232e 7430 ctxt->depth++;
pcercuei 0:03b5121a232e 7431 ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt,
pcercuei 0:03b5121a232e 7432 ctxt->sax, user_data, ctxt->depth,
pcercuei 0:03b5121a232e 7433 ent->URI, ent->ExternalID, NULL);
pcercuei 0:03b5121a232e 7434 ctxt->depth--;
pcercuei 0:03b5121a232e 7435 } else {
pcercuei 0:03b5121a232e 7436 ret = XML_ERR_ENTITY_PE_INTERNAL;
pcercuei 0:03b5121a232e 7437 xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
pcercuei 0:03b5121a232e 7438 "invalid entity type found\n", NULL);
pcercuei 0:03b5121a232e 7439 }
pcercuei 0:03b5121a232e 7440 if (ret == XML_ERR_ENTITY_LOOP) {
pcercuei 0:03b5121a232e 7441 xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
pcercuei 0:03b5121a232e 7442 return;
pcercuei 0:03b5121a232e 7443 }
pcercuei 0:03b5121a232e 7444 }
pcercuei 0:03b5121a232e 7445 if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
pcercuei 0:03b5121a232e 7446 (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
pcercuei 0:03b5121a232e 7447 /*
pcercuei 0:03b5121a232e 7448 * Entity reference callback comes second, it's somewhat
pcercuei 0:03b5121a232e 7449 * superfluous but a compatibility to historical behaviour
pcercuei 0:03b5121a232e 7450 */
pcercuei 0:03b5121a232e 7451 ctxt->sax->reference(ctxt->userData, ent->name);
pcercuei 0:03b5121a232e 7452 }
pcercuei 0:03b5121a232e 7453 return;
pcercuei 0:03b5121a232e 7454 }
pcercuei 0:03b5121a232e 7455
pcercuei 0:03b5121a232e 7456 /*
pcercuei 0:03b5121a232e 7457 * If we didn't get any children for the entity being built
pcercuei 0:03b5121a232e 7458 */
pcercuei 0:03b5121a232e 7459 if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
pcercuei 0:03b5121a232e 7460 (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
pcercuei 0:03b5121a232e 7461 /*
pcercuei 0:03b5121a232e 7462 * Create a node.
pcercuei 0:03b5121a232e 7463 */
pcercuei 0:03b5121a232e 7464 ctxt->sax->reference(ctxt->userData, ent->name);
pcercuei 0:03b5121a232e 7465 return;
pcercuei 0:03b5121a232e 7466 }
pcercuei 0:03b5121a232e 7467
pcercuei 0:03b5121a232e 7468 if ((ctxt->replaceEntities) || (ent->children == NULL)) {
pcercuei 0:03b5121a232e 7469 /*
pcercuei 0:03b5121a232e 7470 * There is a problem on the handling of _private for entities
pcercuei 0:03b5121a232e 7471 * (bug 155816): Should we copy the content of the field from
pcercuei 0:03b5121a232e 7472 * the entity (possibly overwriting some value set by the user
pcercuei 0:03b5121a232e 7473 * when a copy is created), should we leave it alone, or should
pcercuei 0:03b5121a232e 7474 * we try to take care of different situations? The problem
pcercuei 0:03b5121a232e 7475 * is exacerbated by the usage of this field by the xmlReader.
pcercuei 0:03b5121a232e 7476 * To fix this bug, we look at _private on the created node
pcercuei 0:03b5121a232e 7477 * and, if it's NULL, we copy in whatever was in the entity.
pcercuei 0:03b5121a232e 7478 * If it's not NULL we leave it alone. This is somewhat of a
pcercuei 0:03b5121a232e 7479 * hack - maybe we should have further tests to determine
pcercuei 0:03b5121a232e 7480 * what to do.
pcercuei 0:03b5121a232e 7481 */
pcercuei 0:03b5121a232e 7482 if ((ctxt->node != NULL) && (ent->children != NULL)) {
pcercuei 0:03b5121a232e 7483 /*
pcercuei 0:03b5121a232e 7484 * Seems we are generating the DOM content, do
pcercuei 0:03b5121a232e 7485 * a simple tree copy for all references except the first
pcercuei 0:03b5121a232e 7486 * In the first occurrence list contains the replacement.
pcercuei 0:03b5121a232e 7487 */
pcercuei 0:03b5121a232e 7488 if (((list == NULL) && (ent->owner == 0)) ||
pcercuei 0:03b5121a232e 7489 (ctxt->parseMode == XML_PARSE_READER)) {
pcercuei 0:03b5121a232e 7490 xmlNodePtr nw = NULL, cur, firstChild = NULL;
pcercuei 0:03b5121a232e 7491
pcercuei 0:03b5121a232e 7492 /*
pcercuei 0:03b5121a232e 7493 * We are copying here, make sure there is no abuse
pcercuei 0:03b5121a232e 7494 */
pcercuei 0:03b5121a232e 7495 ctxt->sizeentcopy += ent->length + 5;
pcercuei 0:03b5121a232e 7496 if (xmlParserEntityCheck(ctxt, 0, ent, ctxt->sizeentcopy))
pcercuei 0:03b5121a232e 7497 return;
pcercuei 0:03b5121a232e 7498
pcercuei 0:03b5121a232e 7499 /*
pcercuei 0:03b5121a232e 7500 * when operating on a reader, the entities definitions
pcercuei 0:03b5121a232e 7501 * are always owning the entities subtree.
pcercuei 0:03b5121a232e 7502 if (ctxt->parseMode == XML_PARSE_READER)
pcercuei 0:03b5121a232e 7503 ent->owner = 1;
pcercuei 0:03b5121a232e 7504 */
pcercuei 0:03b5121a232e 7505
pcercuei 0:03b5121a232e 7506 cur = ent->children;
pcercuei 0:03b5121a232e 7507 while (cur != NULL) {
pcercuei 0:03b5121a232e 7508 nw = xmlDocCopyNode(cur, ctxt->myDoc, 1);
pcercuei 0:03b5121a232e 7509 if (nw != NULL) {
pcercuei 0:03b5121a232e 7510 if (nw->_private == NULL)
pcercuei 0:03b5121a232e 7511 nw->_private = cur->_private;
pcercuei 0:03b5121a232e 7512 if (firstChild == NULL){
pcercuei 0:03b5121a232e 7513 firstChild = nw;
pcercuei 0:03b5121a232e 7514 }
pcercuei 0:03b5121a232e 7515 nw = xmlAddChild(ctxt->node, nw);
pcercuei 0:03b5121a232e 7516 }
pcercuei 0:03b5121a232e 7517 if (cur == ent->last) {
pcercuei 0:03b5121a232e 7518 /*
pcercuei 0:03b5121a232e 7519 * needed to detect some strange empty
pcercuei 0:03b5121a232e 7520 * node cases in the reader tests
pcercuei 0:03b5121a232e 7521 */
pcercuei 0:03b5121a232e 7522 if ((ctxt->parseMode == XML_PARSE_READER) &&
pcercuei 0:03b5121a232e 7523 (nw != NULL) &&
pcercuei 0:03b5121a232e 7524 (nw->type == XML_ELEMENT_NODE) &&
pcercuei 0:03b5121a232e 7525 (nw->children == NULL))
pcercuei 0:03b5121a232e 7526 nw->extra = 1;
pcercuei 0:03b5121a232e 7527
pcercuei 0:03b5121a232e 7528 break;
pcercuei 0:03b5121a232e 7529 }
pcercuei 0:03b5121a232e 7530 cur = cur->next;
pcercuei 0:03b5121a232e 7531 }
pcercuei 0:03b5121a232e 7532 #ifdef LIBXML_LEGACY_ENABLED
pcercuei 0:03b5121a232e 7533 if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
pcercuei 0:03b5121a232e 7534 xmlAddEntityReference(ent, firstChild, nw);
pcercuei 0:03b5121a232e 7535 #endif /* LIBXML_LEGACY_ENABLED */
pcercuei 0:03b5121a232e 7536 } else if ((list == NULL) || (ctxt->inputNr > 0)) {
pcercuei 0:03b5121a232e 7537 xmlNodePtr nw = NULL, cur, next, last,
pcercuei 0:03b5121a232e 7538 firstChild = NULL;
pcercuei 0:03b5121a232e 7539
pcercuei 0:03b5121a232e 7540 /*
pcercuei 0:03b5121a232e 7541 * We are copying here, make sure there is no abuse
pcercuei 0:03b5121a232e 7542 */
pcercuei 0:03b5121a232e 7543 ctxt->sizeentcopy += ent->length + 5;
pcercuei 0:03b5121a232e 7544 if (xmlParserEntityCheck(ctxt, 0, ent, ctxt->sizeentcopy))
pcercuei 0:03b5121a232e 7545 return;
pcercuei 0:03b5121a232e 7546
pcercuei 0:03b5121a232e 7547 /*
pcercuei 0:03b5121a232e 7548 * Copy the entity child list and make it the new
pcercuei 0:03b5121a232e 7549 * entity child list. The goal is to make sure any
pcercuei 0:03b5121a232e 7550 * ID or REF referenced will be the one from the
pcercuei 0:03b5121a232e 7551 * document content and not the entity copy.
pcercuei 0:03b5121a232e 7552 */
pcercuei 0:03b5121a232e 7553 cur = ent->children;
pcercuei 0:03b5121a232e 7554 ent->children = NULL;
pcercuei 0:03b5121a232e 7555 last = ent->last;
pcercuei 0:03b5121a232e 7556 ent->last = NULL;
pcercuei 0:03b5121a232e 7557 while (cur != NULL) {
pcercuei 0:03b5121a232e 7558 next = cur->next;
pcercuei 0:03b5121a232e 7559 cur->next = NULL;
pcercuei 0:03b5121a232e 7560 cur->parent = NULL;
pcercuei 0:03b5121a232e 7561 nw = xmlDocCopyNode(cur, ctxt->myDoc, 1);
pcercuei 0:03b5121a232e 7562 if (nw != NULL) {
pcercuei 0:03b5121a232e 7563 if (nw->_private == NULL)
pcercuei 0:03b5121a232e 7564 nw->_private = cur->_private;
pcercuei 0:03b5121a232e 7565 if (firstChild == NULL){
pcercuei 0:03b5121a232e 7566 firstChild = cur;
pcercuei 0:03b5121a232e 7567 }
pcercuei 0:03b5121a232e 7568 xmlAddChild((xmlNodePtr) ent, nw);
pcercuei 0:03b5121a232e 7569 xmlAddChild(ctxt->node, cur);
pcercuei 0:03b5121a232e 7570 }
pcercuei 0:03b5121a232e 7571 if (cur == last)
pcercuei 0:03b5121a232e 7572 break;
pcercuei 0:03b5121a232e 7573 cur = next;
pcercuei 0:03b5121a232e 7574 }
pcercuei 0:03b5121a232e 7575 if (ent->owner == 0)
pcercuei 0:03b5121a232e 7576 ent->owner = 1;
pcercuei 0:03b5121a232e 7577 #ifdef LIBXML_LEGACY_ENABLED
pcercuei 0:03b5121a232e 7578 if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
pcercuei 0:03b5121a232e 7579 xmlAddEntityReference(ent, firstChild, nw);
pcercuei 0:03b5121a232e 7580 #endif /* LIBXML_LEGACY_ENABLED */
pcercuei 0:03b5121a232e 7581 } else {
pcercuei 0:03b5121a232e 7582 const xmlChar *nbktext;
pcercuei 0:03b5121a232e 7583
pcercuei 0:03b5121a232e 7584 /*
pcercuei 0:03b5121a232e 7585 * the name change is to avoid coalescing of the
pcercuei 0:03b5121a232e 7586 * node with a possible previous text one which
pcercuei 0:03b5121a232e 7587 * would make ent->children a dangling pointer
pcercuei 0:03b5121a232e 7588 */
pcercuei 0:03b5121a232e 7589 nbktext = xmlDictLookup(ctxt->dict, BAD_CAST "nbktext",
pcercuei 0:03b5121a232e 7590 -1);
pcercuei 0:03b5121a232e 7591 if (ent->children->type == XML_TEXT_NODE)
pcercuei 0:03b5121a232e 7592 ent->children->name = nbktext;
pcercuei 0:03b5121a232e 7593 if ((ent->last != ent->children) &&
pcercuei 0:03b5121a232e 7594 (ent->last->type == XML_TEXT_NODE))
pcercuei 0:03b5121a232e 7595 ent->last->name = nbktext;
pcercuei 0:03b5121a232e 7596 xmlAddChildList(ctxt->node, ent->children);
pcercuei 0:03b5121a232e 7597 }
pcercuei 0:03b5121a232e 7598
pcercuei 0:03b5121a232e 7599 /*
pcercuei 0:03b5121a232e 7600 * This is to avoid a nasty side effect, see
pcercuei 0:03b5121a232e 7601 * characters() in SAX.c
pcercuei 0:03b5121a232e 7602 */
pcercuei 0:03b5121a232e 7603 ctxt->nodemem = 0;
pcercuei 0:03b5121a232e 7604 ctxt->nodelen = 0;
pcercuei 0:03b5121a232e 7605 return;
pcercuei 0:03b5121a232e 7606 }
pcercuei 0:03b5121a232e 7607 }
pcercuei 0:03b5121a232e 7608 }
pcercuei 0:03b5121a232e 7609
pcercuei 0:03b5121a232e 7610 /**
pcercuei 0:03b5121a232e 7611 * xmlParseEntityRef:
pcercuei 0:03b5121a232e 7612 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 7613 *
pcercuei 0:03b5121a232e 7614 * parse ENTITY references declarations
pcercuei 0:03b5121a232e 7615 *
pcercuei 0:03b5121a232e 7616 * [68] EntityRef ::= '&' Name ';'
pcercuei 0:03b5121a232e 7617 *
pcercuei 0:03b5121a232e 7618 * [ WFC: Entity Declared ]
pcercuei 0:03b5121a232e 7619 * In a document without any DTD, a document with only an internal DTD
pcercuei 0:03b5121a232e 7620 * subset which contains no parameter entity references, or a document
pcercuei 0:03b5121a232e 7621 * with "standalone='yes'", the Name given in the entity reference
pcercuei 0:03b5121a232e 7622 * must match that in an entity declaration, except that well-formed
pcercuei 0:03b5121a232e 7623 * documents need not declare any of the following entities: amp, lt,
pcercuei 0:03b5121a232e 7624 * gt, apos, quot. The declaration of a parameter entity must precede
pcercuei 0:03b5121a232e 7625 * any reference to it. Similarly, the declaration of a general entity
pcercuei 0:03b5121a232e 7626 * must precede any reference to it which appears in a default value in an
pcercuei 0:03b5121a232e 7627 * attribute-list declaration. Note that if entities are declared in the
pcercuei 0:03b5121a232e 7628 * external subset or in external parameter entities, a non-validating
pcercuei 0:03b5121a232e 7629 * processor is not obligated to read and process their declarations;
pcercuei 0:03b5121a232e 7630 * for such documents, the rule that an entity must be declared is a
pcercuei 0:03b5121a232e 7631 * well-formedness constraint only if standalone='yes'.
pcercuei 0:03b5121a232e 7632 *
pcercuei 0:03b5121a232e 7633 * [ WFC: Parsed Entity ]
pcercuei 0:03b5121a232e 7634 * An entity reference must not contain the name of an unparsed entity
pcercuei 0:03b5121a232e 7635 *
pcercuei 0:03b5121a232e 7636 * Returns the xmlEntityPtr if found, or NULL otherwise.
pcercuei 0:03b5121a232e 7637 */
pcercuei 0:03b5121a232e 7638 xmlEntityPtr
pcercuei 0:03b5121a232e 7639 xmlParseEntityRef(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 7640 const xmlChar *name;
pcercuei 0:03b5121a232e 7641 xmlEntityPtr ent = NULL;
pcercuei 0:03b5121a232e 7642
pcercuei 0:03b5121a232e 7643 GROW;
pcercuei 0:03b5121a232e 7644 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 7645 return(NULL);
pcercuei 0:03b5121a232e 7646
pcercuei 0:03b5121a232e 7647 if (RAW != '&')
pcercuei 0:03b5121a232e 7648 return(NULL);
pcercuei 0:03b5121a232e 7649 NEXT;
pcercuei 0:03b5121a232e 7650 name = xmlParseName(ctxt);
pcercuei 0:03b5121a232e 7651 if (name == NULL) {
pcercuei 0:03b5121a232e 7652 xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
pcercuei 0:03b5121a232e 7653 "xmlParseEntityRef: no name\n");
pcercuei 0:03b5121a232e 7654 return(NULL);
pcercuei 0:03b5121a232e 7655 }
pcercuei 0:03b5121a232e 7656 if (RAW != ';') {
pcercuei 0:03b5121a232e 7657 xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
pcercuei 0:03b5121a232e 7658 return(NULL);
pcercuei 0:03b5121a232e 7659 }
pcercuei 0:03b5121a232e 7660 NEXT;
pcercuei 0:03b5121a232e 7661
pcercuei 0:03b5121a232e 7662 /*
pcercuei 0:03b5121a232e 7663 * Predefined entities override any extra definition
pcercuei 0:03b5121a232e 7664 */
pcercuei 0:03b5121a232e 7665 if ((ctxt->options & XML_PARSE_OLDSAX) == 0) {
pcercuei 0:03b5121a232e 7666 ent = xmlGetPredefinedEntity(name);
pcercuei 0:03b5121a232e 7667 if (ent != NULL)
pcercuei 0:03b5121a232e 7668 return(ent);
pcercuei 0:03b5121a232e 7669 }
pcercuei 0:03b5121a232e 7670
pcercuei 0:03b5121a232e 7671 /*
pcercuei 0:03b5121a232e 7672 * Increase the number of entity references parsed
pcercuei 0:03b5121a232e 7673 */
pcercuei 0:03b5121a232e 7674 ctxt->nbentities++;
pcercuei 0:03b5121a232e 7675
pcercuei 0:03b5121a232e 7676 /*
pcercuei 0:03b5121a232e 7677 * Ask first SAX for entity resolution, otherwise try the
pcercuei 0:03b5121a232e 7678 * entities which may have stored in the parser context.
pcercuei 0:03b5121a232e 7679 */
pcercuei 0:03b5121a232e 7680 if (ctxt->sax != NULL) {
pcercuei 0:03b5121a232e 7681 if (ctxt->sax->getEntity != NULL)
pcercuei 0:03b5121a232e 7682 ent = ctxt->sax->getEntity(ctxt->userData, name);
pcercuei 0:03b5121a232e 7683 if ((ctxt->wellFormed == 1 ) && (ent == NULL) &&
pcercuei 0:03b5121a232e 7684 (ctxt->options & XML_PARSE_OLDSAX))
pcercuei 0:03b5121a232e 7685 ent = xmlGetPredefinedEntity(name);
pcercuei 0:03b5121a232e 7686 if ((ctxt->wellFormed == 1 ) && (ent == NULL) &&
pcercuei 0:03b5121a232e 7687 (ctxt->userData==ctxt)) {
pcercuei 0:03b5121a232e 7688 ent = xmlSAX2GetEntity(ctxt, name);
pcercuei 0:03b5121a232e 7689 }
pcercuei 0:03b5121a232e 7690 }
pcercuei 0:03b5121a232e 7691 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 7692 return(NULL);
pcercuei 0:03b5121a232e 7693 /*
pcercuei 0:03b5121a232e 7694 * [ WFC: Entity Declared ]
pcercuei 0:03b5121a232e 7695 * In a document without any DTD, a document with only an
pcercuei 0:03b5121a232e 7696 * internal DTD subset which contains no parameter entity
pcercuei 0:03b5121a232e 7697 * references, or a document with "standalone='yes'", the
pcercuei 0:03b5121a232e 7698 * Name given in the entity reference must match that in an
pcercuei 0:03b5121a232e 7699 * entity declaration, except that well-formed documents
pcercuei 0:03b5121a232e 7700 * need not declare any of the following entities: amp, lt,
pcercuei 0:03b5121a232e 7701 * gt, apos, quot.
pcercuei 0:03b5121a232e 7702 * The declaration of a parameter entity must precede any
pcercuei 0:03b5121a232e 7703 * reference to it.
pcercuei 0:03b5121a232e 7704 * Similarly, the declaration of a general entity must
pcercuei 0:03b5121a232e 7705 * precede any reference to it which appears in a default
pcercuei 0:03b5121a232e 7706 * value in an attribute-list declaration. Note that if
pcercuei 0:03b5121a232e 7707 * entities are declared in the external subset or in
pcercuei 0:03b5121a232e 7708 * external parameter entities, a non-validating processor
pcercuei 0:03b5121a232e 7709 * is not obligated to read and process their declarations;
pcercuei 0:03b5121a232e 7710 * for such documents, the rule that an entity must be
pcercuei 0:03b5121a232e 7711 * declared is a well-formedness constraint only if
pcercuei 0:03b5121a232e 7712 * standalone='yes'.
pcercuei 0:03b5121a232e 7713 */
pcercuei 0:03b5121a232e 7714 if (ent == NULL) {
pcercuei 0:03b5121a232e 7715 if ((ctxt->standalone == 1) ||
pcercuei 0:03b5121a232e 7716 ((ctxt->hasExternalSubset == 0) &&
pcercuei 0:03b5121a232e 7717 (ctxt->hasPErefs == 0))) {
pcercuei 0:03b5121a232e 7718 xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
pcercuei 0:03b5121a232e 7719 "Entity '%s' not defined\n", name);
pcercuei 0:03b5121a232e 7720 } else {
pcercuei 0:03b5121a232e 7721 xmlErrMsgStr(ctxt, XML_WAR_UNDECLARED_ENTITY,
pcercuei 0:03b5121a232e 7722 "Entity '%s' not defined\n", name);
pcercuei 0:03b5121a232e 7723 if ((ctxt->inSubset == 0) &&
pcercuei 0:03b5121a232e 7724 (ctxt->sax != NULL) &&
pcercuei 0:03b5121a232e 7725 (ctxt->sax->reference != NULL)) {
pcercuei 0:03b5121a232e 7726 ctxt->sax->reference(ctxt->userData, name);
pcercuei 0:03b5121a232e 7727 }
pcercuei 0:03b5121a232e 7728 }
pcercuei 0:03b5121a232e 7729 xmlParserEntityCheck(ctxt, 0, ent, 0);
pcercuei 0:03b5121a232e 7730 ctxt->valid = 0;
pcercuei 0:03b5121a232e 7731 }
pcercuei 0:03b5121a232e 7732
pcercuei 0:03b5121a232e 7733 /*
pcercuei 0:03b5121a232e 7734 * [ WFC: Parsed Entity ]
pcercuei 0:03b5121a232e 7735 * An entity reference must not contain the name of an
pcercuei 0:03b5121a232e 7736 * unparsed entity
pcercuei 0:03b5121a232e 7737 */
pcercuei 0:03b5121a232e 7738 else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
pcercuei 0:03b5121a232e 7739 xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY,
pcercuei 0:03b5121a232e 7740 "Entity reference to unparsed entity %s\n", name);
pcercuei 0:03b5121a232e 7741 }
pcercuei 0:03b5121a232e 7742
pcercuei 0:03b5121a232e 7743 /*
pcercuei 0:03b5121a232e 7744 * [ WFC: No External Entity References ]
pcercuei 0:03b5121a232e 7745 * Attribute values cannot contain direct or indirect
pcercuei 0:03b5121a232e 7746 * entity references to external entities.
pcercuei 0:03b5121a232e 7747 */
pcercuei 0:03b5121a232e 7748 else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
pcercuei 0:03b5121a232e 7749 (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
pcercuei 0:03b5121a232e 7750 xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
pcercuei 0:03b5121a232e 7751 "Attribute references external entity '%s'\n", name);
pcercuei 0:03b5121a232e 7752 }
pcercuei 0:03b5121a232e 7753 /*
pcercuei 0:03b5121a232e 7754 * [ WFC: No < in Attribute Values ]
pcercuei 0:03b5121a232e 7755 * The replacement text of any entity referred to directly or
pcercuei 0:03b5121a232e 7756 * indirectly in an attribute value (other than "&lt;") must
pcercuei 0:03b5121a232e 7757 * not contain a <.
pcercuei 0:03b5121a232e 7758 */
pcercuei 0:03b5121a232e 7759 else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
pcercuei 0:03b5121a232e 7760 (ent != NULL) &&
pcercuei 0:03b5121a232e 7761 (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY)) {
pcercuei 0:03b5121a232e 7762 if (((ent->checked & 1) || (ent->checked == 0)) &&
pcercuei 0:03b5121a232e 7763 (ent->content != NULL) && (xmlStrchr(ent->content, '<'))) {
pcercuei 0:03b5121a232e 7764 xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
pcercuei 0:03b5121a232e 7765 "'<' in entity '%s' is not allowed in attributes values\n", name);
pcercuei 0:03b5121a232e 7766 }
pcercuei 0:03b5121a232e 7767 }
pcercuei 0:03b5121a232e 7768
pcercuei 0:03b5121a232e 7769 /*
pcercuei 0:03b5121a232e 7770 * Internal check, no parameter entities here ...
pcercuei 0:03b5121a232e 7771 */
pcercuei 0:03b5121a232e 7772 else {
pcercuei 0:03b5121a232e 7773 switch (ent->etype) {
pcercuei 0:03b5121a232e 7774 case XML_INTERNAL_PARAMETER_ENTITY:
pcercuei 0:03b5121a232e 7775 case XML_EXTERNAL_PARAMETER_ENTITY:
pcercuei 0:03b5121a232e 7776 xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
pcercuei 0:03b5121a232e 7777 "Attempt to reference the parameter entity '%s'\n",
pcercuei 0:03b5121a232e 7778 name);
pcercuei 0:03b5121a232e 7779 break;
pcercuei 0:03b5121a232e 7780 default:
pcercuei 0:03b5121a232e 7781 break;
pcercuei 0:03b5121a232e 7782 }
pcercuei 0:03b5121a232e 7783 }
pcercuei 0:03b5121a232e 7784
pcercuei 0:03b5121a232e 7785 /*
pcercuei 0:03b5121a232e 7786 * [ WFC: No Recursion ]
pcercuei 0:03b5121a232e 7787 * A parsed entity must not contain a recursive reference
pcercuei 0:03b5121a232e 7788 * to itself, either directly or indirectly.
pcercuei 0:03b5121a232e 7789 * Done somewhere else
pcercuei 0:03b5121a232e 7790 */
pcercuei 0:03b5121a232e 7791 return(ent);
pcercuei 0:03b5121a232e 7792 }
pcercuei 0:03b5121a232e 7793
pcercuei 0:03b5121a232e 7794 /**
pcercuei 0:03b5121a232e 7795 * xmlParseStringEntityRef:
pcercuei 0:03b5121a232e 7796 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 7797 * @str: a pointer to an index in the string
pcercuei 0:03b5121a232e 7798 *
pcercuei 0:03b5121a232e 7799 * parse ENTITY references declarations, but this version parses it from
pcercuei 0:03b5121a232e 7800 * a string value.
pcercuei 0:03b5121a232e 7801 *
pcercuei 0:03b5121a232e 7802 * [68] EntityRef ::= '&' Name ';'
pcercuei 0:03b5121a232e 7803 *
pcercuei 0:03b5121a232e 7804 * [ WFC: Entity Declared ]
pcercuei 0:03b5121a232e 7805 * In a document without any DTD, a document with only an internal DTD
pcercuei 0:03b5121a232e 7806 * subset which contains no parameter entity references, or a document
pcercuei 0:03b5121a232e 7807 * with "standalone='yes'", the Name given in the entity reference
pcercuei 0:03b5121a232e 7808 * must match that in an entity declaration, except that well-formed
pcercuei 0:03b5121a232e 7809 * documents need not declare any of the following entities: amp, lt,
pcercuei 0:03b5121a232e 7810 * gt, apos, quot. The declaration of a parameter entity must precede
pcercuei 0:03b5121a232e 7811 * any reference to it. Similarly, the declaration of a general entity
pcercuei 0:03b5121a232e 7812 * must precede any reference to it which appears in a default value in an
pcercuei 0:03b5121a232e 7813 * attribute-list declaration. Note that if entities are declared in the
pcercuei 0:03b5121a232e 7814 * external subset or in external parameter entities, a non-validating
pcercuei 0:03b5121a232e 7815 * processor is not obligated to read and process their declarations;
pcercuei 0:03b5121a232e 7816 * for such documents, the rule that an entity must be declared is a
pcercuei 0:03b5121a232e 7817 * well-formedness constraint only if standalone='yes'.
pcercuei 0:03b5121a232e 7818 *
pcercuei 0:03b5121a232e 7819 * [ WFC: Parsed Entity ]
pcercuei 0:03b5121a232e 7820 * An entity reference must not contain the name of an unparsed entity
pcercuei 0:03b5121a232e 7821 *
pcercuei 0:03b5121a232e 7822 * Returns the xmlEntityPtr if found, or NULL otherwise. The str pointer
pcercuei 0:03b5121a232e 7823 * is updated to the current location in the string.
pcercuei 0:03b5121a232e 7824 */
pcercuei 0:03b5121a232e 7825 static xmlEntityPtr
pcercuei 0:03b5121a232e 7826 xmlParseStringEntityRef(xmlParserCtxtPtr ctxt, const xmlChar ** str) {
pcercuei 0:03b5121a232e 7827 xmlChar *name;
pcercuei 0:03b5121a232e 7828 const xmlChar *ptr;
pcercuei 0:03b5121a232e 7829 xmlChar cur;
pcercuei 0:03b5121a232e 7830 xmlEntityPtr ent = NULL;
pcercuei 0:03b5121a232e 7831
pcercuei 0:03b5121a232e 7832 if ((str == NULL) || (*str == NULL))
pcercuei 0:03b5121a232e 7833 return(NULL);
pcercuei 0:03b5121a232e 7834 ptr = *str;
pcercuei 0:03b5121a232e 7835 cur = *ptr;
pcercuei 0:03b5121a232e 7836 if (cur != '&')
pcercuei 0:03b5121a232e 7837 return(NULL);
pcercuei 0:03b5121a232e 7838
pcercuei 0:03b5121a232e 7839 ptr++;
pcercuei 0:03b5121a232e 7840 name = xmlParseStringName(ctxt, &ptr);
pcercuei 0:03b5121a232e 7841 if (name == NULL) {
pcercuei 0:03b5121a232e 7842 xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
pcercuei 0:03b5121a232e 7843 "xmlParseStringEntityRef: no name\n");
pcercuei 0:03b5121a232e 7844 *str = ptr;
pcercuei 0:03b5121a232e 7845 return(NULL);
pcercuei 0:03b5121a232e 7846 }
pcercuei 0:03b5121a232e 7847 if (*ptr != ';') {
pcercuei 0:03b5121a232e 7848 xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
pcercuei 0:03b5121a232e 7849 xmlFree(name);
pcercuei 0:03b5121a232e 7850 *str = ptr;
pcercuei 0:03b5121a232e 7851 return(NULL);
pcercuei 0:03b5121a232e 7852 }
pcercuei 0:03b5121a232e 7853 ptr++;
pcercuei 0:03b5121a232e 7854
pcercuei 0:03b5121a232e 7855
pcercuei 0:03b5121a232e 7856 /*
pcercuei 0:03b5121a232e 7857 * Predefined entities override any extra definition
pcercuei 0:03b5121a232e 7858 */
pcercuei 0:03b5121a232e 7859 if ((ctxt->options & XML_PARSE_OLDSAX) == 0) {
pcercuei 0:03b5121a232e 7860 ent = xmlGetPredefinedEntity(name);
pcercuei 0:03b5121a232e 7861 if (ent != NULL) {
pcercuei 0:03b5121a232e 7862 xmlFree(name);
pcercuei 0:03b5121a232e 7863 *str = ptr;
pcercuei 0:03b5121a232e 7864 return(ent);
pcercuei 0:03b5121a232e 7865 }
pcercuei 0:03b5121a232e 7866 }
pcercuei 0:03b5121a232e 7867
pcercuei 0:03b5121a232e 7868 /*
pcercuei 0:03b5121a232e 7869 * Increate the number of entity references parsed
pcercuei 0:03b5121a232e 7870 */
pcercuei 0:03b5121a232e 7871 ctxt->nbentities++;
pcercuei 0:03b5121a232e 7872
pcercuei 0:03b5121a232e 7873 /*
pcercuei 0:03b5121a232e 7874 * Ask first SAX for entity resolution, otherwise try the
pcercuei 0:03b5121a232e 7875 * entities which may have stored in the parser context.
pcercuei 0:03b5121a232e 7876 */
pcercuei 0:03b5121a232e 7877 if (ctxt->sax != NULL) {
pcercuei 0:03b5121a232e 7878 if (ctxt->sax->getEntity != NULL)
pcercuei 0:03b5121a232e 7879 ent = ctxt->sax->getEntity(ctxt->userData, name);
pcercuei 0:03b5121a232e 7880 if ((ent == NULL) && (ctxt->options & XML_PARSE_OLDSAX))
pcercuei 0:03b5121a232e 7881 ent = xmlGetPredefinedEntity(name);
pcercuei 0:03b5121a232e 7882 if ((ent == NULL) && (ctxt->userData==ctxt)) {
pcercuei 0:03b5121a232e 7883 ent = xmlSAX2GetEntity(ctxt, name);
pcercuei 0:03b5121a232e 7884 }
pcercuei 0:03b5121a232e 7885 }
pcercuei 0:03b5121a232e 7886 if (ctxt->instate == XML_PARSER_EOF) {
pcercuei 0:03b5121a232e 7887 xmlFree(name);
pcercuei 0:03b5121a232e 7888 return(NULL);
pcercuei 0:03b5121a232e 7889 }
pcercuei 0:03b5121a232e 7890
pcercuei 0:03b5121a232e 7891 /*
pcercuei 0:03b5121a232e 7892 * [ WFC: Entity Declared ]
pcercuei 0:03b5121a232e 7893 * In a document without any DTD, a document with only an
pcercuei 0:03b5121a232e 7894 * internal DTD subset which contains no parameter entity
pcercuei 0:03b5121a232e 7895 * references, or a document with "standalone='yes'", the
pcercuei 0:03b5121a232e 7896 * Name given in the entity reference must match that in an
pcercuei 0:03b5121a232e 7897 * entity declaration, except that well-formed documents
pcercuei 0:03b5121a232e 7898 * need not declare any of the following entities: amp, lt,
pcercuei 0:03b5121a232e 7899 * gt, apos, quot.
pcercuei 0:03b5121a232e 7900 * The declaration of a parameter entity must precede any
pcercuei 0:03b5121a232e 7901 * reference to it.
pcercuei 0:03b5121a232e 7902 * Similarly, the declaration of a general entity must
pcercuei 0:03b5121a232e 7903 * precede any reference to it which appears in a default
pcercuei 0:03b5121a232e 7904 * value in an attribute-list declaration. Note that if
pcercuei 0:03b5121a232e 7905 * entities are declared in the external subset or in
pcercuei 0:03b5121a232e 7906 * external parameter entities, a non-validating processor
pcercuei 0:03b5121a232e 7907 * is not obligated to read and process their declarations;
pcercuei 0:03b5121a232e 7908 * for such documents, the rule that an entity must be
pcercuei 0:03b5121a232e 7909 * declared is a well-formedness constraint only if
pcercuei 0:03b5121a232e 7910 * standalone='yes'.
pcercuei 0:03b5121a232e 7911 */
pcercuei 0:03b5121a232e 7912 if (ent == NULL) {
pcercuei 0:03b5121a232e 7913 if ((ctxt->standalone == 1) ||
pcercuei 0:03b5121a232e 7914 ((ctxt->hasExternalSubset == 0) &&
pcercuei 0:03b5121a232e 7915 (ctxt->hasPErefs == 0))) {
pcercuei 0:03b5121a232e 7916 xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
pcercuei 0:03b5121a232e 7917 "Entity '%s' not defined\n", name);
pcercuei 0:03b5121a232e 7918 } else {
pcercuei 0:03b5121a232e 7919 xmlErrMsgStr(ctxt, XML_WAR_UNDECLARED_ENTITY,
pcercuei 0:03b5121a232e 7920 "Entity '%s' not defined\n",
pcercuei 0:03b5121a232e 7921 name);
pcercuei 0:03b5121a232e 7922 }
pcercuei 0:03b5121a232e 7923 xmlParserEntityCheck(ctxt, 0, ent, 0);
pcercuei 0:03b5121a232e 7924 /* TODO ? check regressions ctxt->valid = 0; */
pcercuei 0:03b5121a232e 7925 }
pcercuei 0:03b5121a232e 7926
pcercuei 0:03b5121a232e 7927 /*
pcercuei 0:03b5121a232e 7928 * [ WFC: Parsed Entity ]
pcercuei 0:03b5121a232e 7929 * An entity reference must not contain the name of an
pcercuei 0:03b5121a232e 7930 * unparsed entity
pcercuei 0:03b5121a232e 7931 */
pcercuei 0:03b5121a232e 7932 else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
pcercuei 0:03b5121a232e 7933 xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY,
pcercuei 0:03b5121a232e 7934 "Entity reference to unparsed entity %s\n", name);
pcercuei 0:03b5121a232e 7935 }
pcercuei 0:03b5121a232e 7936
pcercuei 0:03b5121a232e 7937 /*
pcercuei 0:03b5121a232e 7938 * [ WFC: No External Entity References ]
pcercuei 0:03b5121a232e 7939 * Attribute values cannot contain direct or indirect
pcercuei 0:03b5121a232e 7940 * entity references to external entities.
pcercuei 0:03b5121a232e 7941 */
pcercuei 0:03b5121a232e 7942 else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
pcercuei 0:03b5121a232e 7943 (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
pcercuei 0:03b5121a232e 7944 xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
pcercuei 0:03b5121a232e 7945 "Attribute references external entity '%s'\n", name);
pcercuei 0:03b5121a232e 7946 }
pcercuei 0:03b5121a232e 7947 /*
pcercuei 0:03b5121a232e 7948 * [ WFC: No < in Attribute Values ]
pcercuei 0:03b5121a232e 7949 * The replacement text of any entity referred to directly or
pcercuei 0:03b5121a232e 7950 * indirectly in an attribute value (other than "&lt;") must
pcercuei 0:03b5121a232e 7951 * not contain a <.
pcercuei 0:03b5121a232e 7952 */
pcercuei 0:03b5121a232e 7953 else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
pcercuei 0:03b5121a232e 7954 (ent != NULL) && (ent->content != NULL) &&
pcercuei 0:03b5121a232e 7955 (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
pcercuei 0:03b5121a232e 7956 (xmlStrchr(ent->content, '<'))) {
pcercuei 0:03b5121a232e 7957 xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
pcercuei 0:03b5121a232e 7958 "'<' in entity '%s' is not allowed in attributes values\n",
pcercuei 0:03b5121a232e 7959 name);
pcercuei 0:03b5121a232e 7960 }
pcercuei 0:03b5121a232e 7961
pcercuei 0:03b5121a232e 7962 /*
pcercuei 0:03b5121a232e 7963 * Internal check, no parameter entities here ...
pcercuei 0:03b5121a232e 7964 */
pcercuei 0:03b5121a232e 7965 else {
pcercuei 0:03b5121a232e 7966 switch (ent->etype) {
pcercuei 0:03b5121a232e 7967 case XML_INTERNAL_PARAMETER_ENTITY:
pcercuei 0:03b5121a232e 7968 case XML_EXTERNAL_PARAMETER_ENTITY:
pcercuei 0:03b5121a232e 7969 xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
pcercuei 0:03b5121a232e 7970 "Attempt to reference the parameter entity '%s'\n",
pcercuei 0:03b5121a232e 7971 name);
pcercuei 0:03b5121a232e 7972 break;
pcercuei 0:03b5121a232e 7973 default:
pcercuei 0:03b5121a232e 7974 break;
pcercuei 0:03b5121a232e 7975 }
pcercuei 0:03b5121a232e 7976 }
pcercuei 0:03b5121a232e 7977
pcercuei 0:03b5121a232e 7978 /*
pcercuei 0:03b5121a232e 7979 * [ WFC: No Recursion ]
pcercuei 0:03b5121a232e 7980 * A parsed entity must not contain a recursive reference
pcercuei 0:03b5121a232e 7981 * to itself, either directly or indirectly.
pcercuei 0:03b5121a232e 7982 * Done somewhere else
pcercuei 0:03b5121a232e 7983 */
pcercuei 0:03b5121a232e 7984
pcercuei 0:03b5121a232e 7985 xmlFree(name);
pcercuei 0:03b5121a232e 7986 *str = ptr;
pcercuei 0:03b5121a232e 7987 return(ent);
pcercuei 0:03b5121a232e 7988 }
pcercuei 0:03b5121a232e 7989
pcercuei 0:03b5121a232e 7990 /**
pcercuei 0:03b5121a232e 7991 * xmlParsePEReference:
pcercuei 0:03b5121a232e 7992 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 7993 *
pcercuei 0:03b5121a232e 7994 * parse PEReference declarations
pcercuei 0:03b5121a232e 7995 * The entity content is handled directly by pushing it's content as
pcercuei 0:03b5121a232e 7996 * a new input stream.
pcercuei 0:03b5121a232e 7997 *
pcercuei 0:03b5121a232e 7998 * [69] PEReference ::= '%' Name ';'
pcercuei 0:03b5121a232e 7999 *
pcercuei 0:03b5121a232e 8000 * [ WFC: No Recursion ]
pcercuei 0:03b5121a232e 8001 * A parsed entity must not contain a recursive
pcercuei 0:03b5121a232e 8002 * reference to itself, either directly or indirectly.
pcercuei 0:03b5121a232e 8003 *
pcercuei 0:03b5121a232e 8004 * [ WFC: Entity Declared ]
pcercuei 0:03b5121a232e 8005 * In a document without any DTD, a document with only an internal DTD
pcercuei 0:03b5121a232e 8006 * subset which contains no parameter entity references, or a document
pcercuei 0:03b5121a232e 8007 * with "standalone='yes'", ... ... The declaration of a parameter
pcercuei 0:03b5121a232e 8008 * entity must precede any reference to it...
pcercuei 0:03b5121a232e 8009 *
pcercuei 0:03b5121a232e 8010 * [ VC: Entity Declared ]
pcercuei 0:03b5121a232e 8011 * In a document with an external subset or external parameter entities
pcercuei 0:03b5121a232e 8012 * with "standalone='no'", ... ... The declaration of a parameter entity
pcercuei 0:03b5121a232e 8013 * must precede any reference to it...
pcercuei 0:03b5121a232e 8014 *
pcercuei 0:03b5121a232e 8015 * [ WFC: In DTD ]
pcercuei 0:03b5121a232e 8016 * Parameter-entity references may only appear in the DTD.
pcercuei 0:03b5121a232e 8017 * NOTE: misleading but this is handled.
pcercuei 0:03b5121a232e 8018 */
pcercuei 0:03b5121a232e 8019 void
pcercuei 0:03b5121a232e 8020 xmlParsePEReference(xmlParserCtxtPtr ctxt)
pcercuei 0:03b5121a232e 8021 {
pcercuei 0:03b5121a232e 8022 const xmlChar *name;
pcercuei 0:03b5121a232e 8023 xmlEntityPtr entity = NULL;
pcercuei 0:03b5121a232e 8024 xmlParserInputPtr input;
pcercuei 0:03b5121a232e 8025
pcercuei 0:03b5121a232e 8026 if (RAW != '%')
pcercuei 0:03b5121a232e 8027 return;
pcercuei 0:03b5121a232e 8028 NEXT;
pcercuei 0:03b5121a232e 8029 name = xmlParseName(ctxt);
pcercuei 0:03b5121a232e 8030 if (name == NULL) {
pcercuei 0:03b5121a232e 8031 xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
pcercuei 0:03b5121a232e 8032 "xmlParsePEReference: no name\n");
pcercuei 0:03b5121a232e 8033 return;
pcercuei 0:03b5121a232e 8034 }
pcercuei 0:03b5121a232e 8035 if (RAW != ';') {
pcercuei 0:03b5121a232e 8036 xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
pcercuei 0:03b5121a232e 8037 return;
pcercuei 0:03b5121a232e 8038 }
pcercuei 0:03b5121a232e 8039
pcercuei 0:03b5121a232e 8040 NEXT;
pcercuei 0:03b5121a232e 8041
pcercuei 0:03b5121a232e 8042 /*
pcercuei 0:03b5121a232e 8043 * Increate the number of entity references parsed
pcercuei 0:03b5121a232e 8044 */
pcercuei 0:03b5121a232e 8045 ctxt->nbentities++;
pcercuei 0:03b5121a232e 8046
pcercuei 0:03b5121a232e 8047 /*
pcercuei 0:03b5121a232e 8048 * Request the entity from SAX
pcercuei 0:03b5121a232e 8049 */
pcercuei 0:03b5121a232e 8050 if ((ctxt->sax != NULL) &&
pcercuei 0:03b5121a232e 8051 (ctxt->sax->getParameterEntity != NULL))
pcercuei 0:03b5121a232e 8052 entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
pcercuei 0:03b5121a232e 8053 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 8054 return;
pcercuei 0:03b5121a232e 8055 if (entity == NULL) {
pcercuei 0:03b5121a232e 8056 /*
pcercuei 0:03b5121a232e 8057 * [ WFC: Entity Declared ]
pcercuei 0:03b5121a232e 8058 * In a document without any DTD, a document with only an
pcercuei 0:03b5121a232e 8059 * internal DTD subset which contains no parameter entity
pcercuei 0:03b5121a232e 8060 * references, or a document with "standalone='yes'", ...
pcercuei 0:03b5121a232e 8061 * ... The declaration of a parameter entity must precede
pcercuei 0:03b5121a232e 8062 * any reference to it...
pcercuei 0:03b5121a232e 8063 */
pcercuei 0:03b5121a232e 8064 if ((ctxt->standalone == 1) ||
pcercuei 0:03b5121a232e 8065 ((ctxt->hasExternalSubset == 0) &&
pcercuei 0:03b5121a232e 8066 (ctxt->hasPErefs == 0))) {
pcercuei 0:03b5121a232e 8067 xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
pcercuei 0:03b5121a232e 8068 "PEReference: %%%s; not found\n",
pcercuei 0:03b5121a232e 8069 name);
pcercuei 0:03b5121a232e 8070 } else {
pcercuei 0:03b5121a232e 8071 /*
pcercuei 0:03b5121a232e 8072 * [ VC: Entity Declared ]
pcercuei 0:03b5121a232e 8073 * In a document with an external subset or external
pcercuei 0:03b5121a232e 8074 * parameter entities with "standalone='no'", ...
pcercuei 0:03b5121a232e 8075 * ... The declaration of a parameter entity must
pcercuei 0:03b5121a232e 8076 * precede any reference to it...
pcercuei 0:03b5121a232e 8077 */
pcercuei 0:03b5121a232e 8078 xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
pcercuei 0:03b5121a232e 8079 "PEReference: %%%s; not found\n",
pcercuei 0:03b5121a232e 8080 name, NULL);
pcercuei 0:03b5121a232e 8081 ctxt->valid = 0;
pcercuei 0:03b5121a232e 8082 }
pcercuei 0:03b5121a232e 8083 xmlParserEntityCheck(ctxt, 0, NULL, 0);
pcercuei 0:03b5121a232e 8084 } else {
pcercuei 0:03b5121a232e 8085 /*
pcercuei 0:03b5121a232e 8086 * Internal checking in case the entity quest barfed
pcercuei 0:03b5121a232e 8087 */
pcercuei 0:03b5121a232e 8088 if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
pcercuei 0:03b5121a232e 8089 (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
pcercuei 0:03b5121a232e 8090 xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
pcercuei 0:03b5121a232e 8091 "Internal: %%%s; is not a parameter entity\n",
pcercuei 0:03b5121a232e 8092 name, NULL);
pcercuei 0:03b5121a232e 8093 } else if (ctxt->input->free != deallocblankswrapper) {
pcercuei 0:03b5121a232e 8094 input = xmlNewBlanksWrapperInputStream(ctxt, entity);
pcercuei 0:03b5121a232e 8095 if (xmlPushInput(ctxt, input) < 0)
pcercuei 0:03b5121a232e 8096 return;
pcercuei 0:03b5121a232e 8097 } else {
pcercuei 0:03b5121a232e 8098 /*
pcercuei 0:03b5121a232e 8099 * TODO !!!
pcercuei 0:03b5121a232e 8100 * handle the extra spaces added before and after
pcercuei 0:03b5121a232e 8101 * c.f. http://www.w3.org/TR/REC-xml#as-PE
pcercuei 0:03b5121a232e 8102 */
pcercuei 0:03b5121a232e 8103 input = xmlNewEntityInputStream(ctxt, entity);
pcercuei 0:03b5121a232e 8104 if (xmlPushInput(ctxt, input) < 0)
pcercuei 0:03b5121a232e 8105 return;
pcercuei 0:03b5121a232e 8106 if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
pcercuei 0:03b5121a232e 8107 (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) &&
pcercuei 0:03b5121a232e 8108 (IS_BLANK_CH(NXT(5)))) {
pcercuei 0:03b5121a232e 8109 xmlParseTextDecl(ctxt);
pcercuei 0:03b5121a232e 8110 if (ctxt->errNo ==
pcercuei 0:03b5121a232e 8111 XML_ERR_UNSUPPORTED_ENCODING) {
pcercuei 0:03b5121a232e 8112 /*
pcercuei 0:03b5121a232e 8113 * The XML REC instructs us to stop parsing
pcercuei 0:03b5121a232e 8114 * right here
pcercuei 0:03b5121a232e 8115 */
pcercuei 0:03b5121a232e 8116 xmlHaltParser(ctxt);
pcercuei 0:03b5121a232e 8117 return;
pcercuei 0:03b5121a232e 8118 }
pcercuei 0:03b5121a232e 8119 }
pcercuei 0:03b5121a232e 8120 }
pcercuei 0:03b5121a232e 8121 }
pcercuei 0:03b5121a232e 8122 ctxt->hasPErefs = 1;
pcercuei 0:03b5121a232e 8123 }
pcercuei 0:03b5121a232e 8124
pcercuei 0:03b5121a232e 8125 /**
pcercuei 0:03b5121a232e 8126 * xmlLoadEntityContent:
pcercuei 0:03b5121a232e 8127 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 8128 * @entity: an unloaded system entity
pcercuei 0:03b5121a232e 8129 *
pcercuei 0:03b5121a232e 8130 * Load the original content of the given system entity from the
pcercuei 0:03b5121a232e 8131 * ExternalID/SystemID given. This is to be used for Included in Literal
pcercuei 0:03b5121a232e 8132 * http://www.w3.org/TR/REC-xml/#inliteral processing of entities references
pcercuei 0:03b5121a232e 8133 *
pcercuei 0:03b5121a232e 8134 * Returns 0 in case of success and -1 in case of failure
pcercuei 0:03b5121a232e 8135 */
pcercuei 0:03b5121a232e 8136 static int
pcercuei 0:03b5121a232e 8137 xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
pcercuei 0:03b5121a232e 8138 xmlParserInputPtr input;
pcercuei 0:03b5121a232e 8139 xmlBufferPtr buf;
pcercuei 0:03b5121a232e 8140 int l, c;
pcercuei 0:03b5121a232e 8141 int count = 0;
pcercuei 0:03b5121a232e 8142
pcercuei 0:03b5121a232e 8143 if ((ctxt == NULL) || (entity == NULL) ||
pcercuei 0:03b5121a232e 8144 ((entity->etype != XML_EXTERNAL_PARAMETER_ENTITY) &&
pcercuei 0:03b5121a232e 8145 (entity->etype != XML_EXTERNAL_GENERAL_PARSED_ENTITY)) ||
pcercuei 0:03b5121a232e 8146 (entity->content != NULL)) {
pcercuei 0:03b5121a232e 8147 xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
pcercuei 0:03b5121a232e 8148 "xmlLoadEntityContent parameter error");
pcercuei 0:03b5121a232e 8149 return(-1);
pcercuei 0:03b5121a232e 8150 }
pcercuei 0:03b5121a232e 8151
pcercuei 0:03b5121a232e 8152 if (xmlParserDebugEntities)
pcercuei 0:03b5121a232e 8153 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 8154 "Reading %s entity content input\n", entity->name);
pcercuei 0:03b5121a232e 8155
pcercuei 0:03b5121a232e 8156 buf = xmlBufferCreate();
pcercuei 0:03b5121a232e 8157 if (buf == NULL) {
pcercuei 0:03b5121a232e 8158 xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
pcercuei 0:03b5121a232e 8159 "xmlLoadEntityContent parameter error");
pcercuei 0:03b5121a232e 8160 return(-1);
pcercuei 0:03b5121a232e 8161 }
pcercuei 0:03b5121a232e 8162
pcercuei 0:03b5121a232e 8163 input = xmlNewEntityInputStream(ctxt, entity);
pcercuei 0:03b5121a232e 8164 if (input == NULL) {
pcercuei 0:03b5121a232e 8165 xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
pcercuei 0:03b5121a232e 8166 "xmlLoadEntityContent input error");
pcercuei 0:03b5121a232e 8167 xmlBufferFree(buf);
pcercuei 0:03b5121a232e 8168 return(-1);
pcercuei 0:03b5121a232e 8169 }
pcercuei 0:03b5121a232e 8170
pcercuei 0:03b5121a232e 8171 /*
pcercuei 0:03b5121a232e 8172 * Push the entity as the current input, read char by char
pcercuei 0:03b5121a232e 8173 * saving to the buffer until the end of the entity or an error
pcercuei 0:03b5121a232e 8174 */
pcercuei 0:03b5121a232e 8175 if (xmlPushInput(ctxt, input) < 0) {
pcercuei 0:03b5121a232e 8176 xmlBufferFree(buf);
pcercuei 0:03b5121a232e 8177 return(-1);
pcercuei 0:03b5121a232e 8178 }
pcercuei 0:03b5121a232e 8179
pcercuei 0:03b5121a232e 8180 GROW;
pcercuei 0:03b5121a232e 8181 c = CUR_CHAR(l);
pcercuei 0:03b5121a232e 8182 while ((ctxt->input == input) && (ctxt->input->cur < ctxt->input->end) &&
pcercuei 0:03b5121a232e 8183 (IS_CHAR(c))) {
pcercuei 0:03b5121a232e 8184 xmlBufferAdd(buf, ctxt->input->cur, l);
pcercuei 0:03b5121a232e 8185 if (count++ > XML_PARSER_CHUNK_SIZE) {
pcercuei 0:03b5121a232e 8186 count = 0;
pcercuei 0:03b5121a232e 8187 GROW;
pcercuei 0:03b5121a232e 8188 if (ctxt->instate == XML_PARSER_EOF) {
pcercuei 0:03b5121a232e 8189 xmlBufferFree(buf);
pcercuei 0:03b5121a232e 8190 return(-1);
pcercuei 0:03b5121a232e 8191 }
pcercuei 0:03b5121a232e 8192 }
pcercuei 0:03b5121a232e 8193 NEXTL(l);
pcercuei 0:03b5121a232e 8194 c = CUR_CHAR(l);
pcercuei 0:03b5121a232e 8195 if (c == 0) {
pcercuei 0:03b5121a232e 8196 count = 0;
pcercuei 0:03b5121a232e 8197 GROW;
pcercuei 0:03b5121a232e 8198 if (ctxt->instate == XML_PARSER_EOF) {
pcercuei 0:03b5121a232e 8199 xmlBufferFree(buf);
pcercuei 0:03b5121a232e 8200 return(-1);
pcercuei 0:03b5121a232e 8201 }
pcercuei 0:03b5121a232e 8202 c = CUR_CHAR(l);
pcercuei 0:03b5121a232e 8203 }
pcercuei 0:03b5121a232e 8204 }
pcercuei 0:03b5121a232e 8205
pcercuei 0:03b5121a232e 8206 if ((ctxt->input == input) && (ctxt->input->cur >= ctxt->input->end)) {
pcercuei 0:03b5121a232e 8207 xmlPopInput(ctxt);
pcercuei 0:03b5121a232e 8208 } else if (!IS_CHAR(c)) {
pcercuei 0:03b5121a232e 8209 xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
pcercuei 0:03b5121a232e 8210 "xmlLoadEntityContent: invalid char value %d\n",
pcercuei 0:03b5121a232e 8211 c);
pcercuei 0:03b5121a232e 8212 xmlBufferFree(buf);
pcercuei 0:03b5121a232e 8213 return(-1);
pcercuei 0:03b5121a232e 8214 }
pcercuei 0:03b5121a232e 8215 entity->content = buf->content;
pcercuei 0:03b5121a232e 8216 buf->content = NULL;
pcercuei 0:03b5121a232e 8217 xmlBufferFree(buf);
pcercuei 0:03b5121a232e 8218
pcercuei 0:03b5121a232e 8219 return(0);
pcercuei 0:03b5121a232e 8220 }
pcercuei 0:03b5121a232e 8221
pcercuei 0:03b5121a232e 8222 /**
pcercuei 0:03b5121a232e 8223 * xmlParseStringPEReference:
pcercuei 0:03b5121a232e 8224 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 8225 * @str: a pointer to an index in the string
pcercuei 0:03b5121a232e 8226 *
pcercuei 0:03b5121a232e 8227 * parse PEReference declarations
pcercuei 0:03b5121a232e 8228 *
pcercuei 0:03b5121a232e 8229 * [69] PEReference ::= '%' Name ';'
pcercuei 0:03b5121a232e 8230 *
pcercuei 0:03b5121a232e 8231 * [ WFC: No Recursion ]
pcercuei 0:03b5121a232e 8232 * A parsed entity must not contain a recursive
pcercuei 0:03b5121a232e 8233 * reference to itself, either directly or indirectly.
pcercuei 0:03b5121a232e 8234 *
pcercuei 0:03b5121a232e 8235 * [ WFC: Entity Declared ]
pcercuei 0:03b5121a232e 8236 * In a document without any DTD, a document with only an internal DTD
pcercuei 0:03b5121a232e 8237 * subset which contains no parameter entity references, or a document
pcercuei 0:03b5121a232e 8238 * with "standalone='yes'", ... ... The declaration of a parameter
pcercuei 0:03b5121a232e 8239 * entity must precede any reference to it...
pcercuei 0:03b5121a232e 8240 *
pcercuei 0:03b5121a232e 8241 * [ VC: Entity Declared ]
pcercuei 0:03b5121a232e 8242 * In a document with an external subset or external parameter entities
pcercuei 0:03b5121a232e 8243 * with "standalone='no'", ... ... The declaration of a parameter entity
pcercuei 0:03b5121a232e 8244 * must precede any reference to it...
pcercuei 0:03b5121a232e 8245 *
pcercuei 0:03b5121a232e 8246 * [ WFC: In DTD ]
pcercuei 0:03b5121a232e 8247 * Parameter-entity references may only appear in the DTD.
pcercuei 0:03b5121a232e 8248 * NOTE: misleading but this is handled.
pcercuei 0:03b5121a232e 8249 *
pcercuei 0:03b5121a232e 8250 * Returns the string of the entity content.
pcercuei 0:03b5121a232e 8251 * str is updated to the current value of the index
pcercuei 0:03b5121a232e 8252 */
pcercuei 0:03b5121a232e 8253 static xmlEntityPtr
pcercuei 0:03b5121a232e 8254 xmlParseStringPEReference(xmlParserCtxtPtr ctxt, const xmlChar **str) {
pcercuei 0:03b5121a232e 8255 const xmlChar *ptr;
pcercuei 0:03b5121a232e 8256 xmlChar cur;
pcercuei 0:03b5121a232e 8257 xmlChar *name;
pcercuei 0:03b5121a232e 8258 xmlEntityPtr entity = NULL;
pcercuei 0:03b5121a232e 8259
pcercuei 0:03b5121a232e 8260 if ((str == NULL) || (*str == NULL)) return(NULL);
pcercuei 0:03b5121a232e 8261 ptr = *str;
pcercuei 0:03b5121a232e 8262 cur = *ptr;
pcercuei 0:03b5121a232e 8263 if (cur != '%')
pcercuei 0:03b5121a232e 8264 return(NULL);
pcercuei 0:03b5121a232e 8265 ptr++;
pcercuei 0:03b5121a232e 8266 name = xmlParseStringName(ctxt, &ptr);
pcercuei 0:03b5121a232e 8267 if (name == NULL) {
pcercuei 0:03b5121a232e 8268 xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
pcercuei 0:03b5121a232e 8269 "xmlParseStringPEReference: no name\n");
pcercuei 0:03b5121a232e 8270 *str = ptr;
pcercuei 0:03b5121a232e 8271 return(NULL);
pcercuei 0:03b5121a232e 8272 }
pcercuei 0:03b5121a232e 8273 cur = *ptr;
pcercuei 0:03b5121a232e 8274 if (cur != ';') {
pcercuei 0:03b5121a232e 8275 xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
pcercuei 0:03b5121a232e 8276 xmlFree(name);
pcercuei 0:03b5121a232e 8277 *str = ptr;
pcercuei 0:03b5121a232e 8278 return(NULL);
pcercuei 0:03b5121a232e 8279 }
pcercuei 0:03b5121a232e 8280 ptr++;
pcercuei 0:03b5121a232e 8281
pcercuei 0:03b5121a232e 8282 /*
pcercuei 0:03b5121a232e 8283 * Increate the number of entity references parsed
pcercuei 0:03b5121a232e 8284 */
pcercuei 0:03b5121a232e 8285 ctxt->nbentities++;
pcercuei 0:03b5121a232e 8286
pcercuei 0:03b5121a232e 8287 /*
pcercuei 0:03b5121a232e 8288 * Request the entity from SAX
pcercuei 0:03b5121a232e 8289 */
pcercuei 0:03b5121a232e 8290 if ((ctxt->sax != NULL) &&
pcercuei 0:03b5121a232e 8291 (ctxt->sax->getParameterEntity != NULL))
pcercuei 0:03b5121a232e 8292 entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
pcercuei 0:03b5121a232e 8293 if (ctxt->instate == XML_PARSER_EOF) {
pcercuei 0:03b5121a232e 8294 xmlFree(name);
pcercuei 0:03b5121a232e 8295 return(NULL);
pcercuei 0:03b5121a232e 8296 }
pcercuei 0:03b5121a232e 8297 if (entity == NULL) {
pcercuei 0:03b5121a232e 8298 /*
pcercuei 0:03b5121a232e 8299 * [ WFC: Entity Declared ]
pcercuei 0:03b5121a232e 8300 * In a document without any DTD, a document with only an
pcercuei 0:03b5121a232e 8301 * internal DTD subset which contains no parameter entity
pcercuei 0:03b5121a232e 8302 * references, or a document with "standalone='yes'", ...
pcercuei 0:03b5121a232e 8303 * ... The declaration of a parameter entity must precede
pcercuei 0:03b5121a232e 8304 * any reference to it...
pcercuei 0:03b5121a232e 8305 */
pcercuei 0:03b5121a232e 8306 if ((ctxt->standalone == 1) ||
pcercuei 0:03b5121a232e 8307 ((ctxt->hasExternalSubset == 0) && (ctxt->hasPErefs == 0))) {
pcercuei 0:03b5121a232e 8308 xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
pcercuei 0:03b5121a232e 8309 "PEReference: %%%s; not found\n", name);
pcercuei 0:03b5121a232e 8310 } else {
pcercuei 0:03b5121a232e 8311 /*
pcercuei 0:03b5121a232e 8312 * [ VC: Entity Declared ]
pcercuei 0:03b5121a232e 8313 * In a document with an external subset or external
pcercuei 0:03b5121a232e 8314 * parameter entities with "standalone='no'", ...
pcercuei 0:03b5121a232e 8315 * ... The declaration of a parameter entity must
pcercuei 0:03b5121a232e 8316 * precede any reference to it...
pcercuei 0:03b5121a232e 8317 */
pcercuei 0:03b5121a232e 8318 xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
pcercuei 0:03b5121a232e 8319 "PEReference: %%%s; not found\n",
pcercuei 0:03b5121a232e 8320 name, NULL);
pcercuei 0:03b5121a232e 8321 ctxt->valid = 0;
pcercuei 0:03b5121a232e 8322 }
pcercuei 0:03b5121a232e 8323 xmlParserEntityCheck(ctxt, 0, NULL, 0);
pcercuei 0:03b5121a232e 8324 } else {
pcercuei 0:03b5121a232e 8325 /*
pcercuei 0:03b5121a232e 8326 * Internal checking in case the entity quest barfed
pcercuei 0:03b5121a232e 8327 */
pcercuei 0:03b5121a232e 8328 if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
pcercuei 0:03b5121a232e 8329 (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
pcercuei 0:03b5121a232e 8330 xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
pcercuei 0:03b5121a232e 8331 "%%%s; is not a parameter entity\n",
pcercuei 0:03b5121a232e 8332 name, NULL);
pcercuei 0:03b5121a232e 8333 }
pcercuei 0:03b5121a232e 8334 }
pcercuei 0:03b5121a232e 8335 ctxt->hasPErefs = 1;
pcercuei 0:03b5121a232e 8336 xmlFree(name);
pcercuei 0:03b5121a232e 8337 *str = ptr;
pcercuei 0:03b5121a232e 8338 return(entity);
pcercuei 0:03b5121a232e 8339 }
pcercuei 0:03b5121a232e 8340
pcercuei 0:03b5121a232e 8341 /**
pcercuei 0:03b5121a232e 8342 * xmlParseDocTypeDecl:
pcercuei 0:03b5121a232e 8343 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 8344 *
pcercuei 0:03b5121a232e 8345 * parse a DOCTYPE declaration
pcercuei 0:03b5121a232e 8346 *
pcercuei 0:03b5121a232e 8347 * [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S?
pcercuei 0:03b5121a232e 8348 * ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
pcercuei 0:03b5121a232e 8349 *
pcercuei 0:03b5121a232e 8350 * [ VC: Root Element Type ]
pcercuei 0:03b5121a232e 8351 * The Name in the document type declaration must match the element
pcercuei 0:03b5121a232e 8352 * type of the root element.
pcercuei 0:03b5121a232e 8353 */
pcercuei 0:03b5121a232e 8354
pcercuei 0:03b5121a232e 8355 void
pcercuei 0:03b5121a232e 8356 xmlParseDocTypeDecl(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 8357 const xmlChar *name = NULL;
pcercuei 0:03b5121a232e 8358 xmlChar *ExternalID = NULL;
pcercuei 0:03b5121a232e 8359 xmlChar *URI = NULL;
pcercuei 0:03b5121a232e 8360
pcercuei 0:03b5121a232e 8361 /*
pcercuei 0:03b5121a232e 8362 * We know that '<!DOCTYPE' has been detected.
pcercuei 0:03b5121a232e 8363 */
pcercuei 0:03b5121a232e 8364 SKIP(9);
pcercuei 0:03b5121a232e 8365
pcercuei 0:03b5121a232e 8366 SKIP_BLANKS;
pcercuei 0:03b5121a232e 8367
pcercuei 0:03b5121a232e 8368 /*
pcercuei 0:03b5121a232e 8369 * Parse the DOCTYPE name.
pcercuei 0:03b5121a232e 8370 */
pcercuei 0:03b5121a232e 8371 name = xmlParseName(ctxt);
pcercuei 0:03b5121a232e 8372 if (name == NULL) {
pcercuei 0:03b5121a232e 8373 xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
pcercuei 0:03b5121a232e 8374 "xmlParseDocTypeDecl : no DOCTYPE name !\n");
pcercuei 0:03b5121a232e 8375 }
pcercuei 0:03b5121a232e 8376 ctxt->intSubName = name;
pcercuei 0:03b5121a232e 8377
pcercuei 0:03b5121a232e 8378 SKIP_BLANKS;
pcercuei 0:03b5121a232e 8379
pcercuei 0:03b5121a232e 8380 /*
pcercuei 0:03b5121a232e 8381 * Check for SystemID and ExternalID
pcercuei 0:03b5121a232e 8382 */
pcercuei 0:03b5121a232e 8383 URI = xmlParseExternalID(ctxt, &ExternalID, 1);
pcercuei 0:03b5121a232e 8384
pcercuei 0:03b5121a232e 8385 if ((URI != NULL) || (ExternalID != NULL)) {
pcercuei 0:03b5121a232e 8386 ctxt->hasExternalSubset = 1;
pcercuei 0:03b5121a232e 8387 }
pcercuei 0:03b5121a232e 8388 ctxt->extSubURI = URI;
pcercuei 0:03b5121a232e 8389 ctxt->extSubSystem = ExternalID;
pcercuei 0:03b5121a232e 8390
pcercuei 0:03b5121a232e 8391 SKIP_BLANKS;
pcercuei 0:03b5121a232e 8392
pcercuei 0:03b5121a232e 8393 /*
pcercuei 0:03b5121a232e 8394 * Create and update the internal subset.
pcercuei 0:03b5121a232e 8395 */
pcercuei 0:03b5121a232e 8396 if ((ctxt->sax != NULL) && (ctxt->sax->internalSubset != NULL) &&
pcercuei 0:03b5121a232e 8397 (!ctxt->disableSAX))
pcercuei 0:03b5121a232e 8398 ctxt->sax->internalSubset(ctxt->userData, name, ExternalID, URI);
pcercuei 0:03b5121a232e 8399 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 8400 return;
pcercuei 0:03b5121a232e 8401
pcercuei 0:03b5121a232e 8402 /*
pcercuei 0:03b5121a232e 8403 * Is there any internal subset declarations ?
pcercuei 0:03b5121a232e 8404 * they are handled separately in xmlParseInternalSubset()
pcercuei 0:03b5121a232e 8405 */
pcercuei 0:03b5121a232e 8406 if (RAW == '[')
pcercuei 0:03b5121a232e 8407 return;
pcercuei 0:03b5121a232e 8408
pcercuei 0:03b5121a232e 8409 /*
pcercuei 0:03b5121a232e 8410 * We should be at the end of the DOCTYPE declaration.
pcercuei 0:03b5121a232e 8411 */
pcercuei 0:03b5121a232e 8412 if (RAW != '>') {
pcercuei 0:03b5121a232e 8413 xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL);
pcercuei 0:03b5121a232e 8414 }
pcercuei 0:03b5121a232e 8415 NEXT;
pcercuei 0:03b5121a232e 8416 }
pcercuei 0:03b5121a232e 8417
pcercuei 0:03b5121a232e 8418 /**
pcercuei 0:03b5121a232e 8419 * xmlParseInternalSubset:
pcercuei 0:03b5121a232e 8420 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 8421 *
pcercuei 0:03b5121a232e 8422 * parse the internal subset declaration
pcercuei 0:03b5121a232e 8423 *
pcercuei 0:03b5121a232e 8424 * [28 end] ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
pcercuei 0:03b5121a232e 8425 */
pcercuei 0:03b5121a232e 8426
pcercuei 0:03b5121a232e 8427 static void
pcercuei 0:03b5121a232e 8428 xmlParseInternalSubset(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 8429 /*
pcercuei 0:03b5121a232e 8430 * Is there any DTD definition ?
pcercuei 0:03b5121a232e 8431 */
pcercuei 0:03b5121a232e 8432 if (RAW == '[') {
pcercuei 0:03b5121a232e 8433 ctxt->instate = XML_PARSER_DTD;
pcercuei 0:03b5121a232e 8434 NEXT;
pcercuei 0:03b5121a232e 8435 /*
pcercuei 0:03b5121a232e 8436 * Parse the succession of Markup declarations and
pcercuei 0:03b5121a232e 8437 * PEReferences.
pcercuei 0:03b5121a232e 8438 * Subsequence (markupdecl | PEReference | S)*
pcercuei 0:03b5121a232e 8439 */
pcercuei 0:03b5121a232e 8440 while ((RAW != ']') && (ctxt->instate != XML_PARSER_EOF)) {
pcercuei 0:03b5121a232e 8441 const xmlChar *check = CUR_PTR;
pcercuei 0:03b5121a232e 8442 unsigned int cons = ctxt->input->consumed;
pcercuei 0:03b5121a232e 8443
pcercuei 0:03b5121a232e 8444 SKIP_BLANKS;
pcercuei 0:03b5121a232e 8445 xmlParseMarkupDecl(ctxt);
pcercuei 0:03b5121a232e 8446 xmlParsePEReference(ctxt);
pcercuei 0:03b5121a232e 8447
pcercuei 0:03b5121a232e 8448 /*
pcercuei 0:03b5121a232e 8449 * Pop-up of finished entities.
pcercuei 0:03b5121a232e 8450 */
pcercuei 0:03b5121a232e 8451 while ((RAW == 0) && (ctxt->inputNr > 1))
pcercuei 0:03b5121a232e 8452 xmlPopInput(ctxt);
pcercuei 0:03b5121a232e 8453
pcercuei 0:03b5121a232e 8454 if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
pcercuei 0:03b5121a232e 8455 xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
pcercuei 0:03b5121a232e 8456 "xmlParseInternalSubset: error detected in Markup declaration\n");
pcercuei 0:03b5121a232e 8457 break;
pcercuei 0:03b5121a232e 8458 }
pcercuei 0:03b5121a232e 8459 }
pcercuei 0:03b5121a232e 8460 if (RAW == ']') {
pcercuei 0:03b5121a232e 8461 NEXT;
pcercuei 0:03b5121a232e 8462 SKIP_BLANKS;
pcercuei 0:03b5121a232e 8463 }
pcercuei 0:03b5121a232e 8464 }
pcercuei 0:03b5121a232e 8465
pcercuei 0:03b5121a232e 8466 /*
pcercuei 0:03b5121a232e 8467 * We should be at the end of the DOCTYPE declaration.
pcercuei 0:03b5121a232e 8468 */
pcercuei 0:03b5121a232e 8469 if (RAW != '>') {
pcercuei 0:03b5121a232e 8470 xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL);
pcercuei 0:03b5121a232e 8471 }
pcercuei 0:03b5121a232e 8472 NEXT;
pcercuei 0:03b5121a232e 8473 }
pcercuei 0:03b5121a232e 8474
pcercuei 0:03b5121a232e 8475 #ifdef LIBXML_SAX1_ENABLED
pcercuei 0:03b5121a232e 8476 /**
pcercuei 0:03b5121a232e 8477 * xmlParseAttribute:
pcercuei 0:03b5121a232e 8478 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 8479 * @value: a xmlChar ** used to store the value of the attribute
pcercuei 0:03b5121a232e 8480 *
pcercuei 0:03b5121a232e 8481 * parse an attribute
pcercuei 0:03b5121a232e 8482 *
pcercuei 0:03b5121a232e 8483 * [41] Attribute ::= Name Eq AttValue
pcercuei 0:03b5121a232e 8484 *
pcercuei 0:03b5121a232e 8485 * [ WFC: No External Entity References ]
pcercuei 0:03b5121a232e 8486 * Attribute values cannot contain direct or indirect entity references
pcercuei 0:03b5121a232e 8487 * to external entities.
pcercuei 0:03b5121a232e 8488 *
pcercuei 0:03b5121a232e 8489 * [ WFC: No < in Attribute Values ]
pcercuei 0:03b5121a232e 8490 * The replacement text of any entity referred to directly or indirectly in
pcercuei 0:03b5121a232e 8491 * an attribute value (other than "&lt;") must not contain a <.
pcercuei 0:03b5121a232e 8492 *
pcercuei 0:03b5121a232e 8493 * [ VC: Attribute Value Type ]
pcercuei 0:03b5121a232e 8494 * The attribute must have been declared; the value must be of the type
pcercuei 0:03b5121a232e 8495 * declared for it.
pcercuei 0:03b5121a232e 8496 *
pcercuei 0:03b5121a232e 8497 * [25] Eq ::= S? '=' S?
pcercuei 0:03b5121a232e 8498 *
pcercuei 0:03b5121a232e 8499 * With namespace:
pcercuei 0:03b5121a232e 8500 *
pcercuei 0:03b5121a232e 8501 * [NS 11] Attribute ::= QName Eq AttValue
pcercuei 0:03b5121a232e 8502 *
pcercuei 0:03b5121a232e 8503 * Also the case QName == xmlns:??? is handled independently as a namespace
pcercuei 0:03b5121a232e 8504 * definition.
pcercuei 0:03b5121a232e 8505 *
pcercuei 0:03b5121a232e 8506 * Returns the attribute name, and the value in *value.
pcercuei 0:03b5121a232e 8507 */
pcercuei 0:03b5121a232e 8508
pcercuei 0:03b5121a232e 8509 const xmlChar *
pcercuei 0:03b5121a232e 8510 xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlChar **value) {
pcercuei 0:03b5121a232e 8511 const xmlChar *name;
pcercuei 0:03b5121a232e 8512 xmlChar *val;
pcercuei 0:03b5121a232e 8513
pcercuei 0:03b5121a232e 8514 *value = NULL;
pcercuei 0:03b5121a232e 8515 GROW;
pcercuei 0:03b5121a232e 8516 name = xmlParseName(ctxt);
pcercuei 0:03b5121a232e 8517 if (name == NULL) {
pcercuei 0:03b5121a232e 8518 xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
pcercuei 0:03b5121a232e 8519 "error parsing attribute name\n");
pcercuei 0:03b5121a232e 8520 return(NULL);
pcercuei 0:03b5121a232e 8521 }
pcercuei 0:03b5121a232e 8522
pcercuei 0:03b5121a232e 8523 /*
pcercuei 0:03b5121a232e 8524 * read the value
pcercuei 0:03b5121a232e 8525 */
pcercuei 0:03b5121a232e 8526 SKIP_BLANKS;
pcercuei 0:03b5121a232e 8527 if (RAW == '=') {
pcercuei 0:03b5121a232e 8528 NEXT;
pcercuei 0:03b5121a232e 8529 SKIP_BLANKS;
pcercuei 0:03b5121a232e 8530 val = xmlParseAttValue(ctxt);
pcercuei 0:03b5121a232e 8531 ctxt->instate = XML_PARSER_CONTENT;
pcercuei 0:03b5121a232e 8532 } else {
pcercuei 0:03b5121a232e 8533 xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
pcercuei 0:03b5121a232e 8534 "Specification mandate value for attribute %s\n", name);
pcercuei 0:03b5121a232e 8535 return(NULL);
pcercuei 0:03b5121a232e 8536 }
pcercuei 0:03b5121a232e 8537
pcercuei 0:03b5121a232e 8538 /*
pcercuei 0:03b5121a232e 8539 * Check that xml:lang conforms to the specification
pcercuei 0:03b5121a232e 8540 * No more registered as an error, just generate a warning now
pcercuei 0:03b5121a232e 8541 * since this was deprecated in XML second edition
pcercuei 0:03b5121a232e 8542 */
pcercuei 0:03b5121a232e 8543 if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "xml:lang"))) {
pcercuei 0:03b5121a232e 8544 if (!xmlCheckLanguageID(val)) {
pcercuei 0:03b5121a232e 8545 xmlWarningMsg(ctxt, XML_WAR_LANG_VALUE,
pcercuei 0:03b5121a232e 8546 "Malformed value for xml:lang : %s\n",
pcercuei 0:03b5121a232e 8547 val, NULL);
pcercuei 0:03b5121a232e 8548 }
pcercuei 0:03b5121a232e 8549 }
pcercuei 0:03b5121a232e 8550
pcercuei 0:03b5121a232e 8551 /*
pcercuei 0:03b5121a232e 8552 * Check that xml:space conforms to the specification
pcercuei 0:03b5121a232e 8553 */
pcercuei 0:03b5121a232e 8554 if (xmlStrEqual(name, BAD_CAST "xml:space")) {
pcercuei 0:03b5121a232e 8555 if (xmlStrEqual(val, BAD_CAST "default"))
pcercuei 0:03b5121a232e 8556 *(ctxt->space) = 0;
pcercuei 0:03b5121a232e 8557 else if (xmlStrEqual(val, BAD_CAST "preserve"))
pcercuei 0:03b5121a232e 8558 *(ctxt->space) = 1;
pcercuei 0:03b5121a232e 8559 else {
pcercuei 0:03b5121a232e 8560 xmlWarningMsg(ctxt, XML_WAR_SPACE_VALUE,
pcercuei 0:03b5121a232e 8561 "Invalid value \"%s\" for xml:space : \"default\" or \"preserve\" expected\n",
pcercuei 0:03b5121a232e 8562 val, NULL);
pcercuei 0:03b5121a232e 8563 }
pcercuei 0:03b5121a232e 8564 }
pcercuei 0:03b5121a232e 8565
pcercuei 0:03b5121a232e 8566 *value = val;
pcercuei 0:03b5121a232e 8567 return(name);
pcercuei 0:03b5121a232e 8568 }
pcercuei 0:03b5121a232e 8569
pcercuei 0:03b5121a232e 8570 /**
pcercuei 0:03b5121a232e 8571 * xmlParseStartTag:
pcercuei 0:03b5121a232e 8572 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 8573 *
pcercuei 0:03b5121a232e 8574 * parse a start of tag either for rule element or
pcercuei 0:03b5121a232e 8575 * EmptyElement. In both case we don't parse the tag closing chars.
pcercuei 0:03b5121a232e 8576 *
pcercuei 0:03b5121a232e 8577 * [40] STag ::= '<' Name (S Attribute)* S? '>'
pcercuei 0:03b5121a232e 8578 *
pcercuei 0:03b5121a232e 8579 * [ WFC: Unique Att Spec ]
pcercuei 0:03b5121a232e 8580 * No attribute name may appear more than once in the same start-tag or
pcercuei 0:03b5121a232e 8581 * empty-element tag.
pcercuei 0:03b5121a232e 8582 *
pcercuei 0:03b5121a232e 8583 * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
pcercuei 0:03b5121a232e 8584 *
pcercuei 0:03b5121a232e 8585 * [ WFC: Unique Att Spec ]
pcercuei 0:03b5121a232e 8586 * No attribute name may appear more than once in the same start-tag or
pcercuei 0:03b5121a232e 8587 * empty-element tag.
pcercuei 0:03b5121a232e 8588 *
pcercuei 0:03b5121a232e 8589 * With namespace:
pcercuei 0:03b5121a232e 8590 *
pcercuei 0:03b5121a232e 8591 * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
pcercuei 0:03b5121a232e 8592 *
pcercuei 0:03b5121a232e 8593 * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
pcercuei 0:03b5121a232e 8594 *
pcercuei 0:03b5121a232e 8595 * Returns the element name parsed
pcercuei 0:03b5121a232e 8596 */
pcercuei 0:03b5121a232e 8597
pcercuei 0:03b5121a232e 8598 const xmlChar *
pcercuei 0:03b5121a232e 8599 xmlParseStartTag(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 8600 const xmlChar *name;
pcercuei 0:03b5121a232e 8601 const xmlChar *attname;
pcercuei 0:03b5121a232e 8602 xmlChar *attvalue;
pcercuei 0:03b5121a232e 8603 const xmlChar **atts = ctxt->atts;
pcercuei 0:03b5121a232e 8604 int nbatts = 0;
pcercuei 0:03b5121a232e 8605 int maxatts = ctxt->maxatts;
pcercuei 0:03b5121a232e 8606 int i;
pcercuei 0:03b5121a232e 8607
pcercuei 0:03b5121a232e 8608 if (RAW != '<') return(NULL);
pcercuei 0:03b5121a232e 8609 NEXT1;
pcercuei 0:03b5121a232e 8610
pcercuei 0:03b5121a232e 8611 name = xmlParseName(ctxt);
pcercuei 0:03b5121a232e 8612 if (name == NULL) {
pcercuei 0:03b5121a232e 8613 xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
pcercuei 0:03b5121a232e 8614 "xmlParseStartTag: invalid element name\n");
pcercuei 0:03b5121a232e 8615 return(NULL);
pcercuei 0:03b5121a232e 8616 }
pcercuei 0:03b5121a232e 8617
pcercuei 0:03b5121a232e 8618 /*
pcercuei 0:03b5121a232e 8619 * Now parse the attributes, it ends up with the ending
pcercuei 0:03b5121a232e 8620 *
pcercuei 0:03b5121a232e 8621 * (S Attribute)* S?
pcercuei 0:03b5121a232e 8622 */
pcercuei 0:03b5121a232e 8623 SKIP_BLANKS;
pcercuei 0:03b5121a232e 8624 GROW;
pcercuei 0:03b5121a232e 8625
pcercuei 0:03b5121a232e 8626 while (((RAW != '>') &&
pcercuei 0:03b5121a232e 8627 ((RAW != '/') || (NXT(1) != '>')) &&
pcercuei 0:03b5121a232e 8628 (IS_BYTE_CHAR(RAW))) && (ctxt->instate != XML_PARSER_EOF)) {
pcercuei 0:03b5121a232e 8629 const xmlChar *q = CUR_PTR;
pcercuei 0:03b5121a232e 8630 unsigned int cons = ctxt->input->consumed;
pcercuei 0:03b5121a232e 8631
pcercuei 0:03b5121a232e 8632 attname = xmlParseAttribute(ctxt, &attvalue);
pcercuei 0:03b5121a232e 8633 if ((attname != NULL) && (attvalue != NULL)) {
pcercuei 0:03b5121a232e 8634 /*
pcercuei 0:03b5121a232e 8635 * [ WFC: Unique Att Spec ]
pcercuei 0:03b5121a232e 8636 * No attribute name may appear more than once in the same
pcercuei 0:03b5121a232e 8637 * start-tag or empty-element tag.
pcercuei 0:03b5121a232e 8638 */
pcercuei 0:03b5121a232e 8639 for (i = 0; i < nbatts;i += 2) {
pcercuei 0:03b5121a232e 8640 if (xmlStrEqual(atts[i], attname)) {
pcercuei 0:03b5121a232e 8641 xmlErrAttributeDup(ctxt, NULL, attname);
pcercuei 0:03b5121a232e 8642 xmlFree(attvalue);
pcercuei 0:03b5121a232e 8643 goto failed;
pcercuei 0:03b5121a232e 8644 }
pcercuei 0:03b5121a232e 8645 }
pcercuei 0:03b5121a232e 8646 /*
pcercuei 0:03b5121a232e 8647 * Add the pair to atts
pcercuei 0:03b5121a232e 8648 */
pcercuei 0:03b5121a232e 8649 if (atts == NULL) {
pcercuei 0:03b5121a232e 8650 maxatts = 22; /* allow for 10 attrs by default */
pcercuei 0:03b5121a232e 8651 atts = (const xmlChar **)
pcercuei 0:03b5121a232e 8652 xmlMalloc(maxatts * sizeof(xmlChar *));
pcercuei 0:03b5121a232e 8653 if (atts == NULL) {
pcercuei 0:03b5121a232e 8654 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 8655 if (attvalue != NULL)
pcercuei 0:03b5121a232e 8656 xmlFree(attvalue);
pcercuei 0:03b5121a232e 8657 goto failed;
pcercuei 0:03b5121a232e 8658 }
pcercuei 0:03b5121a232e 8659 ctxt->atts = atts;
pcercuei 0:03b5121a232e 8660 ctxt->maxatts = maxatts;
pcercuei 0:03b5121a232e 8661 } else if (nbatts + 4 > maxatts) {
pcercuei 0:03b5121a232e 8662 const xmlChar **n;
pcercuei 0:03b5121a232e 8663
pcercuei 0:03b5121a232e 8664 maxatts *= 2;
pcercuei 0:03b5121a232e 8665 n = (const xmlChar **) xmlRealloc((void *) atts,
pcercuei 0:03b5121a232e 8666 maxatts * sizeof(const xmlChar *));
pcercuei 0:03b5121a232e 8667 if (n == NULL) {
pcercuei 0:03b5121a232e 8668 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 8669 if (attvalue != NULL)
pcercuei 0:03b5121a232e 8670 xmlFree(attvalue);
pcercuei 0:03b5121a232e 8671 goto failed;
pcercuei 0:03b5121a232e 8672 }
pcercuei 0:03b5121a232e 8673 atts = n;
pcercuei 0:03b5121a232e 8674 ctxt->atts = atts;
pcercuei 0:03b5121a232e 8675 ctxt->maxatts = maxatts;
pcercuei 0:03b5121a232e 8676 }
pcercuei 0:03b5121a232e 8677 atts[nbatts++] = attname;
pcercuei 0:03b5121a232e 8678 atts[nbatts++] = attvalue;
pcercuei 0:03b5121a232e 8679 atts[nbatts] = NULL;
pcercuei 0:03b5121a232e 8680 atts[nbatts + 1] = NULL;
pcercuei 0:03b5121a232e 8681 } else {
pcercuei 0:03b5121a232e 8682 if (attvalue != NULL)
pcercuei 0:03b5121a232e 8683 xmlFree(attvalue);
pcercuei 0:03b5121a232e 8684 }
pcercuei 0:03b5121a232e 8685
pcercuei 0:03b5121a232e 8686 failed:
pcercuei 0:03b5121a232e 8687
pcercuei 0:03b5121a232e 8688 GROW
pcercuei 0:03b5121a232e 8689 if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
pcercuei 0:03b5121a232e 8690 break;
pcercuei 0:03b5121a232e 8691 if (!IS_BLANK_CH(RAW)) {
pcercuei 0:03b5121a232e 8692 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
pcercuei 0:03b5121a232e 8693 "attributes construct error\n");
pcercuei 0:03b5121a232e 8694 }
pcercuei 0:03b5121a232e 8695 SKIP_BLANKS;
pcercuei 0:03b5121a232e 8696 if ((cons == ctxt->input->consumed) && (q == CUR_PTR) &&
pcercuei 0:03b5121a232e 8697 (attname == NULL) && (attvalue == NULL)) {
pcercuei 0:03b5121a232e 8698 xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
pcercuei 0:03b5121a232e 8699 "xmlParseStartTag: problem parsing attributes\n");
pcercuei 0:03b5121a232e 8700 break;
pcercuei 0:03b5121a232e 8701 }
pcercuei 0:03b5121a232e 8702 SHRINK;
pcercuei 0:03b5121a232e 8703 GROW;
pcercuei 0:03b5121a232e 8704 }
pcercuei 0:03b5121a232e 8705
pcercuei 0:03b5121a232e 8706 /*
pcercuei 0:03b5121a232e 8707 * SAX: Start of Element !
pcercuei 0:03b5121a232e 8708 */
pcercuei 0:03b5121a232e 8709 if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL) &&
pcercuei 0:03b5121a232e 8710 (!ctxt->disableSAX)) {
pcercuei 0:03b5121a232e 8711 if (nbatts > 0)
pcercuei 0:03b5121a232e 8712 ctxt->sax->startElement(ctxt->userData, name, atts);
pcercuei 0:03b5121a232e 8713 else
pcercuei 0:03b5121a232e 8714 ctxt->sax->startElement(ctxt->userData, name, NULL);
pcercuei 0:03b5121a232e 8715 }
pcercuei 0:03b5121a232e 8716
pcercuei 0:03b5121a232e 8717 if (atts != NULL) {
pcercuei 0:03b5121a232e 8718 /* Free only the content strings */
pcercuei 0:03b5121a232e 8719 for (i = 1;i < nbatts;i+=2)
pcercuei 0:03b5121a232e 8720 if (atts[i] != NULL)
pcercuei 0:03b5121a232e 8721 xmlFree((xmlChar *) atts[i]);
pcercuei 0:03b5121a232e 8722 }
pcercuei 0:03b5121a232e 8723 return(name);
pcercuei 0:03b5121a232e 8724 }
pcercuei 0:03b5121a232e 8725
pcercuei 0:03b5121a232e 8726 /**
pcercuei 0:03b5121a232e 8727 * xmlParseEndTag1:
pcercuei 0:03b5121a232e 8728 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 8729 * @line: line of the start tag
pcercuei 0:03b5121a232e 8730 * @nsNr: number of namespaces on the start tag
pcercuei 0:03b5121a232e 8731 *
pcercuei 0:03b5121a232e 8732 * parse an end of tag
pcercuei 0:03b5121a232e 8733 *
pcercuei 0:03b5121a232e 8734 * [42] ETag ::= '</' Name S? '>'
pcercuei 0:03b5121a232e 8735 *
pcercuei 0:03b5121a232e 8736 * With namespace
pcercuei 0:03b5121a232e 8737 *
pcercuei 0:03b5121a232e 8738 * [NS 9] ETag ::= '</' QName S? '>'
pcercuei 0:03b5121a232e 8739 */
pcercuei 0:03b5121a232e 8740
pcercuei 0:03b5121a232e 8741 static void
pcercuei 0:03b5121a232e 8742 xmlParseEndTag1(xmlParserCtxtPtr ctxt, int line) {
pcercuei 0:03b5121a232e 8743 const xmlChar *name;
pcercuei 0:03b5121a232e 8744
pcercuei 0:03b5121a232e 8745 GROW;
pcercuei 0:03b5121a232e 8746 if ((RAW != '<') || (NXT(1) != '/')) {
pcercuei 0:03b5121a232e 8747 xmlFatalErrMsg(ctxt, XML_ERR_LTSLASH_REQUIRED,
pcercuei 0:03b5121a232e 8748 "xmlParseEndTag: '</' not found\n");
pcercuei 0:03b5121a232e 8749 return;
pcercuei 0:03b5121a232e 8750 }
pcercuei 0:03b5121a232e 8751 SKIP(2);
pcercuei 0:03b5121a232e 8752
pcercuei 0:03b5121a232e 8753 name = xmlParseNameAndCompare(ctxt,ctxt->name);
pcercuei 0:03b5121a232e 8754
pcercuei 0:03b5121a232e 8755 /*
pcercuei 0:03b5121a232e 8756 * We should definitely be at the ending "S? '>'" part
pcercuei 0:03b5121a232e 8757 */
pcercuei 0:03b5121a232e 8758 GROW;
pcercuei 0:03b5121a232e 8759 SKIP_BLANKS;
pcercuei 0:03b5121a232e 8760 if ((!IS_BYTE_CHAR(RAW)) || (RAW != '>')) {
pcercuei 0:03b5121a232e 8761 xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
pcercuei 0:03b5121a232e 8762 } else
pcercuei 0:03b5121a232e 8763 NEXT1;
pcercuei 0:03b5121a232e 8764
pcercuei 0:03b5121a232e 8765 /*
pcercuei 0:03b5121a232e 8766 * [ WFC: Element Type Match ]
pcercuei 0:03b5121a232e 8767 * The Name in an element's end-tag must match the element type in the
pcercuei 0:03b5121a232e 8768 * start-tag.
pcercuei 0:03b5121a232e 8769 *
pcercuei 0:03b5121a232e 8770 */
pcercuei 0:03b5121a232e 8771 if (name != (xmlChar*)1) {
pcercuei 0:03b5121a232e 8772 if (name == NULL) name = BAD_CAST "unparseable";
pcercuei 0:03b5121a232e 8773 xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
pcercuei 0:03b5121a232e 8774 "Opening and ending tag mismatch: %s line %d and %s\n",
pcercuei 0:03b5121a232e 8775 ctxt->name, line, name);
pcercuei 0:03b5121a232e 8776 }
pcercuei 0:03b5121a232e 8777
pcercuei 0:03b5121a232e 8778 /*
pcercuei 0:03b5121a232e 8779 * SAX: End of Tag
pcercuei 0:03b5121a232e 8780 */
pcercuei 0:03b5121a232e 8781 if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
pcercuei 0:03b5121a232e 8782 (!ctxt->disableSAX))
pcercuei 0:03b5121a232e 8783 ctxt->sax->endElement(ctxt->userData, ctxt->name);
pcercuei 0:03b5121a232e 8784
pcercuei 0:03b5121a232e 8785 namePop(ctxt);
pcercuei 0:03b5121a232e 8786 spacePop(ctxt);
pcercuei 0:03b5121a232e 8787 return;
pcercuei 0:03b5121a232e 8788 }
pcercuei 0:03b5121a232e 8789
pcercuei 0:03b5121a232e 8790 /**
pcercuei 0:03b5121a232e 8791 * xmlParseEndTag:
pcercuei 0:03b5121a232e 8792 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 8793 *
pcercuei 0:03b5121a232e 8794 * parse an end of tag
pcercuei 0:03b5121a232e 8795 *
pcercuei 0:03b5121a232e 8796 * [42] ETag ::= '</' Name S? '>'
pcercuei 0:03b5121a232e 8797 *
pcercuei 0:03b5121a232e 8798 * With namespace
pcercuei 0:03b5121a232e 8799 *
pcercuei 0:03b5121a232e 8800 * [NS 9] ETag ::= '</' QName S? '>'
pcercuei 0:03b5121a232e 8801 */
pcercuei 0:03b5121a232e 8802
pcercuei 0:03b5121a232e 8803 void
pcercuei 0:03b5121a232e 8804 xmlParseEndTag(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 8805 xmlParseEndTag1(ctxt, 0);
pcercuei 0:03b5121a232e 8806 }
pcercuei 0:03b5121a232e 8807 #endif /* LIBXML_SAX1_ENABLED */
pcercuei 0:03b5121a232e 8808
pcercuei 0:03b5121a232e 8809 /************************************************************************
pcercuei 0:03b5121a232e 8810 * *
pcercuei 0:03b5121a232e 8811 * SAX 2 specific operations *
pcercuei 0:03b5121a232e 8812 * *
pcercuei 0:03b5121a232e 8813 ************************************************************************/
pcercuei 0:03b5121a232e 8814
pcercuei 0:03b5121a232e 8815 /*
pcercuei 0:03b5121a232e 8816 * xmlGetNamespace:
pcercuei 0:03b5121a232e 8817 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 8818 * @prefix: the prefix to lookup
pcercuei 0:03b5121a232e 8819 *
pcercuei 0:03b5121a232e 8820 * Lookup the namespace name for the @prefix (which ca be NULL)
pcercuei 0:03b5121a232e 8821 * The prefix must come from the @ctxt->dict dictionnary
pcercuei 0:03b5121a232e 8822 *
pcercuei 0:03b5121a232e 8823 * Returns the namespace name or NULL if not bound
pcercuei 0:03b5121a232e 8824 */
pcercuei 0:03b5121a232e 8825 static const xmlChar *
pcercuei 0:03b5121a232e 8826 xmlGetNamespace(xmlParserCtxtPtr ctxt, const xmlChar *prefix) {
pcercuei 0:03b5121a232e 8827 int i;
pcercuei 0:03b5121a232e 8828
pcercuei 0:03b5121a232e 8829 if (prefix == ctxt->str_xml) return(ctxt->str_xml_ns);
pcercuei 0:03b5121a232e 8830 for (i = ctxt->nsNr - 2;i >= 0;i-=2)
pcercuei 0:03b5121a232e 8831 if (ctxt->nsTab[i] == prefix) {
pcercuei 0:03b5121a232e 8832 if ((prefix == NULL) && (*ctxt->nsTab[i + 1] == 0))
pcercuei 0:03b5121a232e 8833 return(NULL);
pcercuei 0:03b5121a232e 8834 return(ctxt->nsTab[i + 1]);
pcercuei 0:03b5121a232e 8835 }
pcercuei 0:03b5121a232e 8836 return(NULL);
pcercuei 0:03b5121a232e 8837 }
pcercuei 0:03b5121a232e 8838
pcercuei 0:03b5121a232e 8839 /**
pcercuei 0:03b5121a232e 8840 * xmlParseQName:
pcercuei 0:03b5121a232e 8841 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 8842 * @prefix: pointer to store the prefix part
pcercuei 0:03b5121a232e 8843 *
pcercuei 0:03b5121a232e 8844 * parse an XML Namespace QName
pcercuei 0:03b5121a232e 8845 *
pcercuei 0:03b5121a232e 8846 * [6] QName ::= (Prefix ':')? LocalPart
pcercuei 0:03b5121a232e 8847 * [7] Prefix ::= NCName
pcercuei 0:03b5121a232e 8848 * [8] LocalPart ::= NCName
pcercuei 0:03b5121a232e 8849 *
pcercuei 0:03b5121a232e 8850 * Returns the Name parsed or NULL
pcercuei 0:03b5121a232e 8851 */
pcercuei 0:03b5121a232e 8852
pcercuei 0:03b5121a232e 8853 static const xmlChar *
pcercuei 0:03b5121a232e 8854 xmlParseQName(xmlParserCtxtPtr ctxt, const xmlChar **prefix) {
pcercuei 0:03b5121a232e 8855 const xmlChar *l, *p;
pcercuei 0:03b5121a232e 8856
pcercuei 0:03b5121a232e 8857 GROW;
pcercuei 0:03b5121a232e 8858
pcercuei 0:03b5121a232e 8859 l = xmlParseNCName(ctxt);
pcercuei 0:03b5121a232e 8860 if (l == NULL) {
pcercuei 0:03b5121a232e 8861 if (CUR == ':') {
pcercuei 0:03b5121a232e 8862 l = xmlParseName(ctxt);
pcercuei 0:03b5121a232e 8863 if (l != NULL) {
pcercuei 0:03b5121a232e 8864 xmlNsErr(ctxt, XML_NS_ERR_QNAME,
pcercuei 0:03b5121a232e 8865 "Failed to parse QName '%s'\n", l, NULL, NULL);
pcercuei 0:03b5121a232e 8866 *prefix = NULL;
pcercuei 0:03b5121a232e 8867 return(l);
pcercuei 0:03b5121a232e 8868 }
pcercuei 0:03b5121a232e 8869 }
pcercuei 0:03b5121a232e 8870 return(NULL);
pcercuei 0:03b5121a232e 8871 }
pcercuei 0:03b5121a232e 8872 if (CUR == ':') {
pcercuei 0:03b5121a232e 8873 NEXT;
pcercuei 0:03b5121a232e 8874 p = l;
pcercuei 0:03b5121a232e 8875 l = xmlParseNCName(ctxt);
pcercuei 0:03b5121a232e 8876 if (l == NULL) {
pcercuei 0:03b5121a232e 8877 xmlChar *tmp;
pcercuei 0:03b5121a232e 8878
pcercuei 0:03b5121a232e 8879 xmlNsErr(ctxt, XML_NS_ERR_QNAME,
pcercuei 0:03b5121a232e 8880 "Failed to parse QName '%s:'\n", p, NULL, NULL);
pcercuei 0:03b5121a232e 8881 l = xmlParseNmtoken(ctxt);
pcercuei 0:03b5121a232e 8882 if (l == NULL)
pcercuei 0:03b5121a232e 8883 tmp = xmlBuildQName(BAD_CAST "", p, NULL, 0);
pcercuei 0:03b5121a232e 8884 else {
pcercuei 0:03b5121a232e 8885 tmp = xmlBuildQName(l, p, NULL, 0);
pcercuei 0:03b5121a232e 8886 xmlFree((char *)l);
pcercuei 0:03b5121a232e 8887 }
pcercuei 0:03b5121a232e 8888 p = xmlDictLookup(ctxt->dict, tmp, -1);
pcercuei 0:03b5121a232e 8889 if (tmp != NULL) xmlFree(tmp);
pcercuei 0:03b5121a232e 8890 *prefix = NULL;
pcercuei 0:03b5121a232e 8891 return(p);
pcercuei 0:03b5121a232e 8892 }
pcercuei 0:03b5121a232e 8893 if (CUR == ':') {
pcercuei 0:03b5121a232e 8894 xmlChar *tmp;
pcercuei 0:03b5121a232e 8895
pcercuei 0:03b5121a232e 8896 xmlNsErr(ctxt, XML_NS_ERR_QNAME,
pcercuei 0:03b5121a232e 8897 "Failed to parse QName '%s:%s:'\n", p, l, NULL);
pcercuei 0:03b5121a232e 8898 NEXT;
pcercuei 0:03b5121a232e 8899 tmp = (xmlChar *) xmlParseName(ctxt);
pcercuei 0:03b5121a232e 8900 if (tmp != NULL) {
pcercuei 0:03b5121a232e 8901 tmp = xmlBuildQName(tmp, l, NULL, 0);
pcercuei 0:03b5121a232e 8902 l = xmlDictLookup(ctxt->dict, tmp, -1);
pcercuei 0:03b5121a232e 8903 if (tmp != NULL) xmlFree(tmp);
pcercuei 0:03b5121a232e 8904 *prefix = p;
pcercuei 0:03b5121a232e 8905 return(l);
pcercuei 0:03b5121a232e 8906 }
pcercuei 0:03b5121a232e 8907 tmp = xmlBuildQName(BAD_CAST "", l, NULL, 0);
pcercuei 0:03b5121a232e 8908 l = xmlDictLookup(ctxt->dict, tmp, -1);
pcercuei 0:03b5121a232e 8909 if (tmp != NULL) xmlFree(tmp);
pcercuei 0:03b5121a232e 8910 *prefix = p;
pcercuei 0:03b5121a232e 8911 return(l);
pcercuei 0:03b5121a232e 8912 }
pcercuei 0:03b5121a232e 8913 *prefix = p;
pcercuei 0:03b5121a232e 8914 } else
pcercuei 0:03b5121a232e 8915 *prefix = NULL;
pcercuei 0:03b5121a232e 8916 return(l);
pcercuei 0:03b5121a232e 8917 }
pcercuei 0:03b5121a232e 8918
pcercuei 0:03b5121a232e 8919 /**
pcercuei 0:03b5121a232e 8920 * xmlParseQNameAndCompare:
pcercuei 0:03b5121a232e 8921 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 8922 * @name: the localname
pcercuei 0:03b5121a232e 8923 * @prefix: the prefix, if any.
pcercuei 0:03b5121a232e 8924 *
pcercuei 0:03b5121a232e 8925 * parse an XML name and compares for match
pcercuei 0:03b5121a232e 8926 * (specialized for endtag parsing)
pcercuei 0:03b5121a232e 8927 *
pcercuei 0:03b5121a232e 8928 * Returns NULL for an illegal name, (xmlChar*) 1 for success
pcercuei 0:03b5121a232e 8929 * and the name for mismatch
pcercuei 0:03b5121a232e 8930 */
pcercuei 0:03b5121a232e 8931
pcercuei 0:03b5121a232e 8932 static const xmlChar *
pcercuei 0:03b5121a232e 8933 xmlParseQNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *name,
pcercuei 0:03b5121a232e 8934 xmlChar const *prefix) {
pcercuei 0:03b5121a232e 8935 const xmlChar *cmp;
pcercuei 0:03b5121a232e 8936 const xmlChar *in;
pcercuei 0:03b5121a232e 8937 const xmlChar *ret;
pcercuei 0:03b5121a232e 8938 const xmlChar *prefix2;
pcercuei 0:03b5121a232e 8939
pcercuei 0:03b5121a232e 8940 if (prefix == NULL) return(xmlParseNameAndCompare(ctxt, name));
pcercuei 0:03b5121a232e 8941
pcercuei 0:03b5121a232e 8942 GROW;
pcercuei 0:03b5121a232e 8943 in = ctxt->input->cur;
pcercuei 0:03b5121a232e 8944
pcercuei 0:03b5121a232e 8945 cmp = prefix;
pcercuei 0:03b5121a232e 8946 while (*in != 0 && *in == *cmp) {
pcercuei 0:03b5121a232e 8947 ++in;
pcercuei 0:03b5121a232e 8948 ++cmp;
pcercuei 0:03b5121a232e 8949 }
pcercuei 0:03b5121a232e 8950 if ((*cmp == 0) && (*in == ':')) {
pcercuei 0:03b5121a232e 8951 in++;
pcercuei 0:03b5121a232e 8952 cmp = name;
pcercuei 0:03b5121a232e 8953 while (*in != 0 && *in == *cmp) {
pcercuei 0:03b5121a232e 8954 ++in;
pcercuei 0:03b5121a232e 8955 ++cmp;
pcercuei 0:03b5121a232e 8956 }
pcercuei 0:03b5121a232e 8957 if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) {
pcercuei 0:03b5121a232e 8958 /* success */
pcercuei 0:03b5121a232e 8959 ctxt->input->cur = in;
pcercuei 0:03b5121a232e 8960 return((const xmlChar*) 1);
pcercuei 0:03b5121a232e 8961 }
pcercuei 0:03b5121a232e 8962 }
pcercuei 0:03b5121a232e 8963 /*
pcercuei 0:03b5121a232e 8964 * all strings coms from the dictionary, equality can be done directly
pcercuei 0:03b5121a232e 8965 */
pcercuei 0:03b5121a232e 8966 ret = xmlParseQName (ctxt, &prefix2);
pcercuei 0:03b5121a232e 8967 if ((ret == name) && (prefix == prefix2))
pcercuei 0:03b5121a232e 8968 return((const xmlChar*) 1);
pcercuei 0:03b5121a232e 8969 return ret;
pcercuei 0:03b5121a232e 8970 }
pcercuei 0:03b5121a232e 8971
pcercuei 0:03b5121a232e 8972 /**
pcercuei 0:03b5121a232e 8973 * xmlParseAttValueInternal:
pcercuei 0:03b5121a232e 8974 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 8975 * @len: attribute len result
pcercuei 0:03b5121a232e 8976 * @alloc: whether the attribute was reallocated as a new string
pcercuei 0:03b5121a232e 8977 * @normalize: if 1 then further non-CDATA normalization must be done
pcercuei 0:03b5121a232e 8978 *
pcercuei 0:03b5121a232e 8979 * parse a value for an attribute.
pcercuei 0:03b5121a232e 8980 * NOTE: if no normalization is needed, the routine will return pointers
pcercuei 0:03b5121a232e 8981 * directly from the data buffer.
pcercuei 0:03b5121a232e 8982 *
pcercuei 0:03b5121a232e 8983 * 3.3.3 Attribute-Value Normalization:
pcercuei 0:03b5121a232e 8984 * Before the value of an attribute is passed to the application or
pcercuei 0:03b5121a232e 8985 * checked for validity, the XML processor must normalize it as follows:
pcercuei 0:03b5121a232e 8986 * - a character reference is processed by appending the referenced
pcercuei 0:03b5121a232e 8987 * character to the attribute value
pcercuei 0:03b5121a232e 8988 * - an entity reference is processed by recursively processing the
pcercuei 0:03b5121a232e 8989 * replacement text of the entity
pcercuei 0:03b5121a232e 8990 * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
pcercuei 0:03b5121a232e 8991 * appending #x20 to the normalized value, except that only a single
pcercuei 0:03b5121a232e 8992 * #x20 is appended for a "#xD#xA" sequence that is part of an external
pcercuei 0:03b5121a232e 8993 * parsed entity or the literal entity value of an internal parsed entity
pcercuei 0:03b5121a232e 8994 * - other characters are processed by appending them to the normalized value
pcercuei 0:03b5121a232e 8995 * If the declared value is not CDATA, then the XML processor must further
pcercuei 0:03b5121a232e 8996 * process the normalized attribute value by discarding any leading and
pcercuei 0:03b5121a232e 8997 * trailing space (#x20) characters, and by replacing sequences of space
pcercuei 0:03b5121a232e 8998 * (#x20) characters by a single space (#x20) character.
pcercuei 0:03b5121a232e 8999 * All attributes for which no declaration has been read should be treated
pcercuei 0:03b5121a232e 9000 * by a non-validating parser as if declared CDATA.
pcercuei 0:03b5121a232e 9001 *
pcercuei 0:03b5121a232e 9002 * Returns the AttValue parsed or NULL. The value has to be freed by the
pcercuei 0:03b5121a232e 9003 * caller if it was copied, this can be detected by val[*len] == 0.
pcercuei 0:03b5121a232e 9004 */
pcercuei 0:03b5121a232e 9005
pcercuei 0:03b5121a232e 9006 static xmlChar *
pcercuei 0:03b5121a232e 9007 xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
pcercuei 0:03b5121a232e 9008 int normalize)
pcercuei 0:03b5121a232e 9009 {
pcercuei 0:03b5121a232e 9010 xmlChar limit = 0;
pcercuei 0:03b5121a232e 9011 const xmlChar *in = NULL, *start, *end, *last;
pcercuei 0:03b5121a232e 9012 xmlChar *ret = NULL;
pcercuei 0:03b5121a232e 9013 int line, col;
pcercuei 0:03b5121a232e 9014
pcercuei 0:03b5121a232e 9015 GROW;
pcercuei 0:03b5121a232e 9016 in = (xmlChar *) CUR_PTR;
pcercuei 0:03b5121a232e 9017 line = ctxt->input->line;
pcercuei 0:03b5121a232e 9018 col = ctxt->input->col;
pcercuei 0:03b5121a232e 9019 if (*in != '"' && *in != '\'') {
pcercuei 0:03b5121a232e 9020 xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
pcercuei 0:03b5121a232e 9021 return (NULL);
pcercuei 0:03b5121a232e 9022 }
pcercuei 0:03b5121a232e 9023 ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
pcercuei 0:03b5121a232e 9024
pcercuei 0:03b5121a232e 9025 /*
pcercuei 0:03b5121a232e 9026 * try to handle in this routine the most common case where no
pcercuei 0:03b5121a232e 9027 * allocation of a new string is required and where content is
pcercuei 0:03b5121a232e 9028 * pure ASCII.
pcercuei 0:03b5121a232e 9029 */
pcercuei 0:03b5121a232e 9030 limit = *in++;
pcercuei 0:03b5121a232e 9031 col++;
pcercuei 0:03b5121a232e 9032 end = ctxt->input->end;
pcercuei 0:03b5121a232e 9033 start = in;
pcercuei 0:03b5121a232e 9034 if (in >= end) {
pcercuei 0:03b5121a232e 9035 const xmlChar *oldbase = ctxt->input->base;
pcercuei 0:03b5121a232e 9036 GROW;
pcercuei 0:03b5121a232e 9037 if (oldbase != ctxt->input->base) {
pcercuei 0:03b5121a232e 9038 long delta = ctxt->input->base - oldbase;
pcercuei 0:03b5121a232e 9039 start = start + delta;
pcercuei 0:03b5121a232e 9040 in = in + delta;
pcercuei 0:03b5121a232e 9041 }
pcercuei 0:03b5121a232e 9042 end = ctxt->input->end;
pcercuei 0:03b5121a232e 9043 }
pcercuei 0:03b5121a232e 9044 if (normalize) {
pcercuei 0:03b5121a232e 9045 /*
pcercuei 0:03b5121a232e 9046 * Skip any leading spaces
pcercuei 0:03b5121a232e 9047 */
pcercuei 0:03b5121a232e 9048 while ((in < end) && (*in != limit) &&
pcercuei 0:03b5121a232e 9049 ((*in == 0x20) || (*in == 0x9) ||
pcercuei 0:03b5121a232e 9050 (*in == 0xA) || (*in == 0xD))) {
pcercuei 0:03b5121a232e 9051 if (*in == 0xA) {
pcercuei 0:03b5121a232e 9052 line++; col = 1;
pcercuei 0:03b5121a232e 9053 } else {
pcercuei 0:03b5121a232e 9054 col++;
pcercuei 0:03b5121a232e 9055 }
pcercuei 0:03b5121a232e 9056 in++;
pcercuei 0:03b5121a232e 9057 start = in;
pcercuei 0:03b5121a232e 9058 if (in >= end) {
pcercuei 0:03b5121a232e 9059 const xmlChar *oldbase = ctxt->input->base;
pcercuei 0:03b5121a232e 9060 GROW;
pcercuei 0:03b5121a232e 9061 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 9062 return(NULL);
pcercuei 0:03b5121a232e 9063 if (oldbase != ctxt->input->base) {
pcercuei 0:03b5121a232e 9064 long delta = ctxt->input->base - oldbase;
pcercuei 0:03b5121a232e 9065 start = start + delta;
pcercuei 0:03b5121a232e 9066 in = in + delta;
pcercuei 0:03b5121a232e 9067 }
pcercuei 0:03b5121a232e 9068 end = ctxt->input->end;
pcercuei 0:03b5121a232e 9069 if (((in - start) > XML_MAX_TEXT_LENGTH) &&
pcercuei 0:03b5121a232e 9070 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
pcercuei 0:03b5121a232e 9071 xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
pcercuei 0:03b5121a232e 9072 "AttValue length too long\n");
pcercuei 0:03b5121a232e 9073 return(NULL);
pcercuei 0:03b5121a232e 9074 }
pcercuei 0:03b5121a232e 9075 }
pcercuei 0:03b5121a232e 9076 }
pcercuei 0:03b5121a232e 9077 while ((in < end) && (*in != limit) && (*in >= 0x20) &&
pcercuei 0:03b5121a232e 9078 (*in <= 0x7f) && (*in != '&') && (*in != '<')) {
pcercuei 0:03b5121a232e 9079 col++;
pcercuei 0:03b5121a232e 9080 if ((*in++ == 0x20) && (*in == 0x20)) break;
pcercuei 0:03b5121a232e 9081 if (in >= end) {
pcercuei 0:03b5121a232e 9082 const xmlChar *oldbase = ctxt->input->base;
pcercuei 0:03b5121a232e 9083 GROW;
pcercuei 0:03b5121a232e 9084 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 9085 return(NULL);
pcercuei 0:03b5121a232e 9086 if (oldbase != ctxt->input->base) {
pcercuei 0:03b5121a232e 9087 long delta = ctxt->input->base - oldbase;
pcercuei 0:03b5121a232e 9088 start = start + delta;
pcercuei 0:03b5121a232e 9089 in = in + delta;
pcercuei 0:03b5121a232e 9090 }
pcercuei 0:03b5121a232e 9091 end = ctxt->input->end;
pcercuei 0:03b5121a232e 9092 if (((in - start) > XML_MAX_TEXT_LENGTH) &&
pcercuei 0:03b5121a232e 9093 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
pcercuei 0:03b5121a232e 9094 xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
pcercuei 0:03b5121a232e 9095 "AttValue length too long\n");
pcercuei 0:03b5121a232e 9096 return(NULL);
pcercuei 0:03b5121a232e 9097 }
pcercuei 0:03b5121a232e 9098 }
pcercuei 0:03b5121a232e 9099 }
pcercuei 0:03b5121a232e 9100 last = in;
pcercuei 0:03b5121a232e 9101 /*
pcercuei 0:03b5121a232e 9102 * skip the trailing blanks
pcercuei 0:03b5121a232e 9103 */
pcercuei 0:03b5121a232e 9104 while ((last[-1] == 0x20) && (last > start)) last--;
pcercuei 0:03b5121a232e 9105 while ((in < end) && (*in != limit) &&
pcercuei 0:03b5121a232e 9106 ((*in == 0x20) || (*in == 0x9) ||
pcercuei 0:03b5121a232e 9107 (*in == 0xA) || (*in == 0xD))) {
pcercuei 0:03b5121a232e 9108 if (*in == 0xA) {
pcercuei 0:03b5121a232e 9109 line++, col = 1;
pcercuei 0:03b5121a232e 9110 } else {
pcercuei 0:03b5121a232e 9111 col++;
pcercuei 0:03b5121a232e 9112 }
pcercuei 0:03b5121a232e 9113 in++;
pcercuei 0:03b5121a232e 9114 if (in >= end) {
pcercuei 0:03b5121a232e 9115 const xmlChar *oldbase = ctxt->input->base;
pcercuei 0:03b5121a232e 9116 GROW;
pcercuei 0:03b5121a232e 9117 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 9118 return(NULL);
pcercuei 0:03b5121a232e 9119 if (oldbase != ctxt->input->base) {
pcercuei 0:03b5121a232e 9120 long delta = ctxt->input->base - oldbase;
pcercuei 0:03b5121a232e 9121 start = start + delta;
pcercuei 0:03b5121a232e 9122 in = in + delta;
pcercuei 0:03b5121a232e 9123 last = last + delta;
pcercuei 0:03b5121a232e 9124 }
pcercuei 0:03b5121a232e 9125 end = ctxt->input->end;
pcercuei 0:03b5121a232e 9126 if (((in - start) > XML_MAX_TEXT_LENGTH) &&
pcercuei 0:03b5121a232e 9127 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
pcercuei 0:03b5121a232e 9128 xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
pcercuei 0:03b5121a232e 9129 "AttValue length too long\n");
pcercuei 0:03b5121a232e 9130 return(NULL);
pcercuei 0:03b5121a232e 9131 }
pcercuei 0:03b5121a232e 9132 }
pcercuei 0:03b5121a232e 9133 }
pcercuei 0:03b5121a232e 9134 if (((in - start) > XML_MAX_TEXT_LENGTH) &&
pcercuei 0:03b5121a232e 9135 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
pcercuei 0:03b5121a232e 9136 xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
pcercuei 0:03b5121a232e 9137 "AttValue length too long\n");
pcercuei 0:03b5121a232e 9138 return(NULL);
pcercuei 0:03b5121a232e 9139 }
pcercuei 0:03b5121a232e 9140 if (*in != limit) goto need_complex;
pcercuei 0:03b5121a232e 9141 } else {
pcercuei 0:03b5121a232e 9142 while ((in < end) && (*in != limit) && (*in >= 0x20) &&
pcercuei 0:03b5121a232e 9143 (*in <= 0x7f) && (*in != '&') && (*in != '<')) {
pcercuei 0:03b5121a232e 9144 in++;
pcercuei 0:03b5121a232e 9145 col++;
pcercuei 0:03b5121a232e 9146 if (in >= end) {
pcercuei 0:03b5121a232e 9147 const xmlChar *oldbase = ctxt->input->base;
pcercuei 0:03b5121a232e 9148 GROW;
pcercuei 0:03b5121a232e 9149 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 9150 return(NULL);
pcercuei 0:03b5121a232e 9151 if (oldbase != ctxt->input->base) {
pcercuei 0:03b5121a232e 9152 long delta = ctxt->input->base - oldbase;
pcercuei 0:03b5121a232e 9153 start = start + delta;
pcercuei 0:03b5121a232e 9154 in = in + delta;
pcercuei 0:03b5121a232e 9155 }
pcercuei 0:03b5121a232e 9156 end = ctxt->input->end;
pcercuei 0:03b5121a232e 9157 if (((in - start) > XML_MAX_TEXT_LENGTH) &&
pcercuei 0:03b5121a232e 9158 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
pcercuei 0:03b5121a232e 9159 xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
pcercuei 0:03b5121a232e 9160 "AttValue length too long\n");
pcercuei 0:03b5121a232e 9161 return(NULL);
pcercuei 0:03b5121a232e 9162 }
pcercuei 0:03b5121a232e 9163 }
pcercuei 0:03b5121a232e 9164 }
pcercuei 0:03b5121a232e 9165 last = in;
pcercuei 0:03b5121a232e 9166 if (((in - start) > XML_MAX_TEXT_LENGTH) &&
pcercuei 0:03b5121a232e 9167 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
pcercuei 0:03b5121a232e 9168 xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
pcercuei 0:03b5121a232e 9169 "AttValue length too long\n");
pcercuei 0:03b5121a232e 9170 return(NULL);
pcercuei 0:03b5121a232e 9171 }
pcercuei 0:03b5121a232e 9172 if (*in != limit) goto need_complex;
pcercuei 0:03b5121a232e 9173 }
pcercuei 0:03b5121a232e 9174 in++;
pcercuei 0:03b5121a232e 9175 col++;
pcercuei 0:03b5121a232e 9176 if (len != NULL) {
pcercuei 0:03b5121a232e 9177 *len = last - start;
pcercuei 0:03b5121a232e 9178 ret = (xmlChar *) start;
pcercuei 0:03b5121a232e 9179 } else {
pcercuei 0:03b5121a232e 9180 if (alloc) *alloc = 1;
pcercuei 0:03b5121a232e 9181 ret = xmlStrndup(start, last - start);
pcercuei 0:03b5121a232e 9182 }
pcercuei 0:03b5121a232e 9183 CUR_PTR = in;
pcercuei 0:03b5121a232e 9184 ctxt->input->line = line;
pcercuei 0:03b5121a232e 9185 ctxt->input->col = col;
pcercuei 0:03b5121a232e 9186 if (alloc) *alloc = 0;
pcercuei 0:03b5121a232e 9187 return ret;
pcercuei 0:03b5121a232e 9188 need_complex:
pcercuei 0:03b5121a232e 9189 if (alloc) *alloc = 1;
pcercuei 0:03b5121a232e 9190 return xmlParseAttValueComplex(ctxt, len, normalize);
pcercuei 0:03b5121a232e 9191 }
pcercuei 0:03b5121a232e 9192
pcercuei 0:03b5121a232e 9193 /**
pcercuei 0:03b5121a232e 9194 * xmlParseAttribute2:
pcercuei 0:03b5121a232e 9195 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 9196 * @pref: the element prefix
pcercuei 0:03b5121a232e 9197 * @elem: the element name
pcercuei 0:03b5121a232e 9198 * @prefix: a xmlChar ** used to store the value of the attribute prefix
pcercuei 0:03b5121a232e 9199 * @value: a xmlChar ** used to store the value of the attribute
pcercuei 0:03b5121a232e 9200 * @len: an int * to save the length of the attribute
pcercuei 0:03b5121a232e 9201 * @alloc: an int * to indicate if the attribute was allocated
pcercuei 0:03b5121a232e 9202 *
pcercuei 0:03b5121a232e 9203 * parse an attribute in the new SAX2 framework.
pcercuei 0:03b5121a232e 9204 *
pcercuei 0:03b5121a232e 9205 * Returns the attribute name, and the value in *value, .
pcercuei 0:03b5121a232e 9206 */
pcercuei 0:03b5121a232e 9207
pcercuei 0:03b5121a232e 9208 static const xmlChar *
pcercuei 0:03b5121a232e 9209 xmlParseAttribute2(xmlParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 9210 const xmlChar * pref, const xmlChar * elem,
pcercuei 0:03b5121a232e 9211 const xmlChar ** prefix, xmlChar ** value,
pcercuei 0:03b5121a232e 9212 int *len, int *alloc)
pcercuei 0:03b5121a232e 9213 {
pcercuei 0:03b5121a232e 9214 const xmlChar *name;
pcercuei 0:03b5121a232e 9215 xmlChar *val, *internal_val = NULL;
pcercuei 0:03b5121a232e 9216 int normalize = 0;
pcercuei 0:03b5121a232e 9217
pcercuei 0:03b5121a232e 9218 *value = NULL;
pcercuei 0:03b5121a232e 9219 GROW;
pcercuei 0:03b5121a232e 9220 name = xmlParseQName(ctxt, prefix);
pcercuei 0:03b5121a232e 9221 if (name == NULL) {
pcercuei 0:03b5121a232e 9222 xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
pcercuei 0:03b5121a232e 9223 "error parsing attribute name\n");
pcercuei 0:03b5121a232e 9224 return (NULL);
pcercuei 0:03b5121a232e 9225 }
pcercuei 0:03b5121a232e 9226
pcercuei 0:03b5121a232e 9227 /*
pcercuei 0:03b5121a232e 9228 * get the type if needed
pcercuei 0:03b5121a232e 9229 */
pcercuei 0:03b5121a232e 9230 if (ctxt->attsSpecial != NULL) {
pcercuei 0:03b5121a232e 9231 int type;
pcercuei 0:03b5121a232e 9232
pcercuei 0:03b5121a232e 9233 type = (int) (long) xmlHashQLookup2(ctxt->attsSpecial,
pcercuei 0:03b5121a232e 9234 pref, elem, *prefix, name);
pcercuei 0:03b5121a232e 9235 if (type != 0)
pcercuei 0:03b5121a232e 9236 normalize = 1;
pcercuei 0:03b5121a232e 9237 }
pcercuei 0:03b5121a232e 9238
pcercuei 0:03b5121a232e 9239 /*
pcercuei 0:03b5121a232e 9240 * read the value
pcercuei 0:03b5121a232e 9241 */
pcercuei 0:03b5121a232e 9242 SKIP_BLANKS;
pcercuei 0:03b5121a232e 9243 if (RAW == '=') {
pcercuei 0:03b5121a232e 9244 NEXT;
pcercuei 0:03b5121a232e 9245 SKIP_BLANKS;
pcercuei 0:03b5121a232e 9246 val = xmlParseAttValueInternal(ctxt, len, alloc, normalize);
pcercuei 0:03b5121a232e 9247 if (normalize) {
pcercuei 0:03b5121a232e 9248 /*
pcercuei 0:03b5121a232e 9249 * Sometimes a second normalisation pass for spaces is needed
pcercuei 0:03b5121a232e 9250 * but that only happens if charrefs or entities refernces
pcercuei 0:03b5121a232e 9251 * have been used in the attribute value, i.e. the attribute
pcercuei 0:03b5121a232e 9252 * value have been extracted in an allocated string already.
pcercuei 0:03b5121a232e 9253 */
pcercuei 0:03b5121a232e 9254 if (*alloc) {
pcercuei 0:03b5121a232e 9255 const xmlChar *val2;
pcercuei 0:03b5121a232e 9256
pcercuei 0:03b5121a232e 9257 val2 = xmlAttrNormalizeSpace2(ctxt, val, len);
pcercuei 0:03b5121a232e 9258 if ((val2 != NULL) && (val2 != val)) {
pcercuei 0:03b5121a232e 9259 xmlFree(val);
pcercuei 0:03b5121a232e 9260 val = (xmlChar *) val2;
pcercuei 0:03b5121a232e 9261 }
pcercuei 0:03b5121a232e 9262 }
pcercuei 0:03b5121a232e 9263 }
pcercuei 0:03b5121a232e 9264 ctxt->instate = XML_PARSER_CONTENT;
pcercuei 0:03b5121a232e 9265 } else {
pcercuei 0:03b5121a232e 9266 xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
pcercuei 0:03b5121a232e 9267 "Specification mandate value for attribute %s\n",
pcercuei 0:03b5121a232e 9268 name);
pcercuei 0:03b5121a232e 9269 return (NULL);
pcercuei 0:03b5121a232e 9270 }
pcercuei 0:03b5121a232e 9271
pcercuei 0:03b5121a232e 9272 if (*prefix == ctxt->str_xml) {
pcercuei 0:03b5121a232e 9273 /*
pcercuei 0:03b5121a232e 9274 * Check that xml:lang conforms to the specification
pcercuei 0:03b5121a232e 9275 * No more registered as an error, just generate a warning now
pcercuei 0:03b5121a232e 9276 * since this was deprecated in XML second edition
pcercuei 0:03b5121a232e 9277 */
pcercuei 0:03b5121a232e 9278 if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "lang"))) {
pcercuei 0:03b5121a232e 9279 internal_val = xmlStrndup(val, *len);
pcercuei 0:03b5121a232e 9280 if (!xmlCheckLanguageID(internal_val)) {
pcercuei 0:03b5121a232e 9281 xmlWarningMsg(ctxt, XML_WAR_LANG_VALUE,
pcercuei 0:03b5121a232e 9282 "Malformed value for xml:lang : %s\n",
pcercuei 0:03b5121a232e 9283 internal_val, NULL);
pcercuei 0:03b5121a232e 9284 }
pcercuei 0:03b5121a232e 9285 }
pcercuei 0:03b5121a232e 9286
pcercuei 0:03b5121a232e 9287 /*
pcercuei 0:03b5121a232e 9288 * Check that xml:space conforms to the specification
pcercuei 0:03b5121a232e 9289 */
pcercuei 0:03b5121a232e 9290 if (xmlStrEqual(name, BAD_CAST "space")) {
pcercuei 0:03b5121a232e 9291 internal_val = xmlStrndup(val, *len);
pcercuei 0:03b5121a232e 9292 if (xmlStrEqual(internal_val, BAD_CAST "default"))
pcercuei 0:03b5121a232e 9293 *(ctxt->space) = 0;
pcercuei 0:03b5121a232e 9294 else if (xmlStrEqual(internal_val, BAD_CAST "preserve"))
pcercuei 0:03b5121a232e 9295 *(ctxt->space) = 1;
pcercuei 0:03b5121a232e 9296 else {
pcercuei 0:03b5121a232e 9297 xmlWarningMsg(ctxt, XML_WAR_SPACE_VALUE,
pcercuei 0:03b5121a232e 9298 "Invalid value \"%s\" for xml:space : \"default\" or \"preserve\" expected\n",
pcercuei 0:03b5121a232e 9299 internal_val, NULL);
pcercuei 0:03b5121a232e 9300 }
pcercuei 0:03b5121a232e 9301 }
pcercuei 0:03b5121a232e 9302 if (internal_val) {
pcercuei 0:03b5121a232e 9303 xmlFree(internal_val);
pcercuei 0:03b5121a232e 9304 }
pcercuei 0:03b5121a232e 9305 }
pcercuei 0:03b5121a232e 9306
pcercuei 0:03b5121a232e 9307 *value = val;
pcercuei 0:03b5121a232e 9308 return (name);
pcercuei 0:03b5121a232e 9309 }
pcercuei 0:03b5121a232e 9310 /**
pcercuei 0:03b5121a232e 9311 * xmlParseStartTag2:
pcercuei 0:03b5121a232e 9312 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 9313 *
pcercuei 0:03b5121a232e 9314 * parse a start of tag either for rule element or
pcercuei 0:03b5121a232e 9315 * EmptyElement. In both case we don't parse the tag closing chars.
pcercuei 0:03b5121a232e 9316 * This routine is called when running SAX2 parsing
pcercuei 0:03b5121a232e 9317 *
pcercuei 0:03b5121a232e 9318 * [40] STag ::= '<' Name (S Attribute)* S? '>'
pcercuei 0:03b5121a232e 9319 *
pcercuei 0:03b5121a232e 9320 * [ WFC: Unique Att Spec ]
pcercuei 0:03b5121a232e 9321 * No attribute name may appear more than once in the same start-tag or
pcercuei 0:03b5121a232e 9322 * empty-element tag.
pcercuei 0:03b5121a232e 9323 *
pcercuei 0:03b5121a232e 9324 * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
pcercuei 0:03b5121a232e 9325 *
pcercuei 0:03b5121a232e 9326 * [ WFC: Unique Att Spec ]
pcercuei 0:03b5121a232e 9327 * No attribute name may appear more than once in the same start-tag or
pcercuei 0:03b5121a232e 9328 * empty-element tag.
pcercuei 0:03b5121a232e 9329 *
pcercuei 0:03b5121a232e 9330 * With namespace:
pcercuei 0:03b5121a232e 9331 *
pcercuei 0:03b5121a232e 9332 * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
pcercuei 0:03b5121a232e 9333 *
pcercuei 0:03b5121a232e 9334 * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
pcercuei 0:03b5121a232e 9335 *
pcercuei 0:03b5121a232e 9336 * Returns the element name parsed
pcercuei 0:03b5121a232e 9337 */
pcercuei 0:03b5121a232e 9338
pcercuei 0:03b5121a232e 9339 static const xmlChar *
pcercuei 0:03b5121a232e 9340 xmlParseStartTag2(xmlParserCtxtPtr ctxt, const xmlChar **pref,
pcercuei 0:03b5121a232e 9341 const xmlChar **URI, int *tlen) {
pcercuei 0:03b5121a232e 9342 const xmlChar *localname;
pcercuei 0:03b5121a232e 9343 const xmlChar *prefix;
pcercuei 0:03b5121a232e 9344 const xmlChar *attname;
pcercuei 0:03b5121a232e 9345 const xmlChar *aprefix;
pcercuei 0:03b5121a232e 9346 const xmlChar *nsname;
pcercuei 0:03b5121a232e 9347 xmlChar *attvalue;
pcercuei 0:03b5121a232e 9348 const xmlChar **atts = ctxt->atts;
pcercuei 0:03b5121a232e 9349 int maxatts = ctxt->maxatts;
pcercuei 0:03b5121a232e 9350 int nratts, nbatts, nbdef;
pcercuei 0:03b5121a232e 9351 int i, j, nbNs, attval, oldline, oldcol, inputNr;
pcercuei 0:03b5121a232e 9352 const xmlChar *base;
pcercuei 0:03b5121a232e 9353 unsigned long cur;
pcercuei 0:03b5121a232e 9354 int nsNr = ctxt->nsNr;
pcercuei 0:03b5121a232e 9355
pcercuei 0:03b5121a232e 9356 if (RAW != '<') return(NULL);
pcercuei 0:03b5121a232e 9357 NEXT1;
pcercuei 0:03b5121a232e 9358
pcercuei 0:03b5121a232e 9359 /*
pcercuei 0:03b5121a232e 9360 * NOTE: it is crucial with the SAX2 API to never call SHRINK beyond that
pcercuei 0:03b5121a232e 9361 * point since the attribute values may be stored as pointers to
pcercuei 0:03b5121a232e 9362 * the buffer and calling SHRINK would destroy them !
pcercuei 0:03b5121a232e 9363 * The Shrinking is only possible once the full set of attribute
pcercuei 0:03b5121a232e 9364 * callbacks have been done.
pcercuei 0:03b5121a232e 9365 */
pcercuei 0:03b5121a232e 9366 reparse:
pcercuei 0:03b5121a232e 9367 SHRINK;
pcercuei 0:03b5121a232e 9368 base = ctxt->input->base;
pcercuei 0:03b5121a232e 9369 cur = ctxt->input->cur - ctxt->input->base;
pcercuei 0:03b5121a232e 9370 inputNr = ctxt->inputNr;
pcercuei 0:03b5121a232e 9371 oldline = ctxt->input->line;
pcercuei 0:03b5121a232e 9372 oldcol = ctxt->input->col;
pcercuei 0:03b5121a232e 9373 nbatts = 0;
pcercuei 0:03b5121a232e 9374 nratts = 0;
pcercuei 0:03b5121a232e 9375 nbdef = 0;
pcercuei 0:03b5121a232e 9376 nbNs = 0;
pcercuei 0:03b5121a232e 9377 attval = 0;
pcercuei 0:03b5121a232e 9378 /* Forget any namespaces added during an earlier parse of this element. */
pcercuei 0:03b5121a232e 9379 ctxt->nsNr = nsNr;
pcercuei 0:03b5121a232e 9380
pcercuei 0:03b5121a232e 9381 localname = xmlParseQName(ctxt, &prefix);
pcercuei 0:03b5121a232e 9382 if (localname == NULL) {
pcercuei 0:03b5121a232e 9383 xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
pcercuei 0:03b5121a232e 9384 "StartTag: invalid element name\n");
pcercuei 0:03b5121a232e 9385 return(NULL);
pcercuei 0:03b5121a232e 9386 }
pcercuei 0:03b5121a232e 9387 *tlen = ctxt->input->cur - ctxt->input->base - cur;
pcercuei 0:03b5121a232e 9388
pcercuei 0:03b5121a232e 9389 /*
pcercuei 0:03b5121a232e 9390 * Now parse the attributes, it ends up with the ending
pcercuei 0:03b5121a232e 9391 *
pcercuei 0:03b5121a232e 9392 * (S Attribute)* S?
pcercuei 0:03b5121a232e 9393 */
pcercuei 0:03b5121a232e 9394 SKIP_BLANKS;
pcercuei 0:03b5121a232e 9395 GROW;
pcercuei 0:03b5121a232e 9396 if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr))
pcercuei 0:03b5121a232e 9397 goto base_changed;
pcercuei 0:03b5121a232e 9398
pcercuei 0:03b5121a232e 9399 while (((RAW != '>') &&
pcercuei 0:03b5121a232e 9400 ((RAW != '/') || (NXT(1) != '>')) &&
pcercuei 0:03b5121a232e 9401 (IS_BYTE_CHAR(RAW))) && (ctxt->instate != XML_PARSER_EOF)) {
pcercuei 0:03b5121a232e 9402 const xmlChar *q = CUR_PTR;
pcercuei 0:03b5121a232e 9403 unsigned int cons = ctxt->input->consumed;
pcercuei 0:03b5121a232e 9404 int len = -1, alloc = 0;
pcercuei 0:03b5121a232e 9405
pcercuei 0:03b5121a232e 9406 attname = xmlParseAttribute2(ctxt, prefix, localname,
pcercuei 0:03b5121a232e 9407 &aprefix, &attvalue, &len, &alloc);
pcercuei 0:03b5121a232e 9408 if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr)) {
pcercuei 0:03b5121a232e 9409 if ((attvalue != NULL) && (alloc != 0))
pcercuei 0:03b5121a232e 9410 xmlFree(attvalue);
pcercuei 0:03b5121a232e 9411 attvalue = NULL;
pcercuei 0:03b5121a232e 9412 goto base_changed;
pcercuei 0:03b5121a232e 9413 }
pcercuei 0:03b5121a232e 9414 if ((attname != NULL) && (attvalue != NULL)) {
pcercuei 0:03b5121a232e 9415 if (len < 0) len = xmlStrlen(attvalue);
pcercuei 0:03b5121a232e 9416 if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
pcercuei 0:03b5121a232e 9417 const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
pcercuei 0:03b5121a232e 9418 xmlURIPtr uri;
pcercuei 0:03b5121a232e 9419
pcercuei 0:03b5121a232e 9420 if (URL == NULL) {
pcercuei 0:03b5121a232e 9421 xmlErrMemory(ctxt, "dictionary allocation failure");
pcercuei 0:03b5121a232e 9422 if ((attvalue != NULL) && (alloc != 0))
pcercuei 0:03b5121a232e 9423 xmlFree(attvalue);
pcercuei 0:03b5121a232e 9424 return(NULL);
pcercuei 0:03b5121a232e 9425 }
pcercuei 0:03b5121a232e 9426 if (*URL != 0) {
pcercuei 0:03b5121a232e 9427 uri = xmlParseURI((const char *) URL);
pcercuei 0:03b5121a232e 9428 if (uri == NULL) {
pcercuei 0:03b5121a232e 9429 xmlNsErr(ctxt, XML_WAR_NS_URI,
pcercuei 0:03b5121a232e 9430 "xmlns: '%s' is not a valid URI\n",
pcercuei 0:03b5121a232e 9431 URL, NULL, NULL);
pcercuei 0:03b5121a232e 9432 } else {
pcercuei 0:03b5121a232e 9433 if (uri->scheme == NULL) {
pcercuei 0:03b5121a232e 9434 xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
pcercuei 0:03b5121a232e 9435 "xmlns: URI %s is not absolute\n",
pcercuei 0:03b5121a232e 9436 URL, NULL, NULL);
pcercuei 0:03b5121a232e 9437 }
pcercuei 0:03b5121a232e 9438 xmlFreeURI(uri);
pcercuei 0:03b5121a232e 9439 }
pcercuei 0:03b5121a232e 9440 if (URL == ctxt->str_xml_ns) {
pcercuei 0:03b5121a232e 9441 if (attname != ctxt->str_xml) {
pcercuei 0:03b5121a232e 9442 xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
pcercuei 0:03b5121a232e 9443 "xml namespace URI cannot be the default namespace\n",
pcercuei 0:03b5121a232e 9444 NULL, NULL, NULL);
pcercuei 0:03b5121a232e 9445 }
pcercuei 0:03b5121a232e 9446 goto skip_default_ns;
pcercuei 0:03b5121a232e 9447 }
pcercuei 0:03b5121a232e 9448 if ((len == 29) &&
pcercuei 0:03b5121a232e 9449 (xmlStrEqual(URL,
pcercuei 0:03b5121a232e 9450 BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
pcercuei 0:03b5121a232e 9451 xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
pcercuei 0:03b5121a232e 9452 "reuse of the xmlns namespace name is forbidden\n",
pcercuei 0:03b5121a232e 9453 NULL, NULL, NULL);
pcercuei 0:03b5121a232e 9454 goto skip_default_ns;
pcercuei 0:03b5121a232e 9455 }
pcercuei 0:03b5121a232e 9456 }
pcercuei 0:03b5121a232e 9457 /*
pcercuei 0:03b5121a232e 9458 * check that it's not a defined namespace
pcercuei 0:03b5121a232e 9459 */
pcercuei 0:03b5121a232e 9460 for (j = 1;j <= nbNs;j++)
pcercuei 0:03b5121a232e 9461 if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
pcercuei 0:03b5121a232e 9462 break;
pcercuei 0:03b5121a232e 9463 if (j <= nbNs)
pcercuei 0:03b5121a232e 9464 xmlErrAttributeDup(ctxt, NULL, attname);
pcercuei 0:03b5121a232e 9465 else
pcercuei 0:03b5121a232e 9466 if (nsPush(ctxt, NULL, URL) > 0) nbNs++;
pcercuei 0:03b5121a232e 9467 skip_default_ns:
pcercuei 0:03b5121a232e 9468 if (alloc != 0) xmlFree(attvalue);
pcercuei 0:03b5121a232e 9469 if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
pcercuei 0:03b5121a232e 9470 break;
pcercuei 0:03b5121a232e 9471 if (!IS_BLANK_CH(RAW)) {
pcercuei 0:03b5121a232e 9472 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
pcercuei 0:03b5121a232e 9473 "attributes construct error\n");
pcercuei 0:03b5121a232e 9474 break;
pcercuei 0:03b5121a232e 9475 }
pcercuei 0:03b5121a232e 9476 SKIP_BLANKS;
pcercuei 0:03b5121a232e 9477 continue;
pcercuei 0:03b5121a232e 9478 }
pcercuei 0:03b5121a232e 9479 if (aprefix == ctxt->str_xmlns) {
pcercuei 0:03b5121a232e 9480 const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
pcercuei 0:03b5121a232e 9481 xmlURIPtr uri;
pcercuei 0:03b5121a232e 9482
pcercuei 0:03b5121a232e 9483 if (attname == ctxt->str_xml) {
pcercuei 0:03b5121a232e 9484 if (URL != ctxt->str_xml_ns) {
pcercuei 0:03b5121a232e 9485 xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
pcercuei 0:03b5121a232e 9486 "xml namespace prefix mapped to wrong URI\n",
pcercuei 0:03b5121a232e 9487 NULL, NULL, NULL);
pcercuei 0:03b5121a232e 9488 }
pcercuei 0:03b5121a232e 9489 /*
pcercuei 0:03b5121a232e 9490 * Do not keep a namespace definition node
pcercuei 0:03b5121a232e 9491 */
pcercuei 0:03b5121a232e 9492 goto skip_ns;
pcercuei 0:03b5121a232e 9493 }
pcercuei 0:03b5121a232e 9494 if (URL == ctxt->str_xml_ns) {
pcercuei 0:03b5121a232e 9495 if (attname != ctxt->str_xml) {
pcercuei 0:03b5121a232e 9496 xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
pcercuei 0:03b5121a232e 9497 "xml namespace URI mapped to wrong prefix\n",
pcercuei 0:03b5121a232e 9498 NULL, NULL, NULL);
pcercuei 0:03b5121a232e 9499 }
pcercuei 0:03b5121a232e 9500 goto skip_ns;
pcercuei 0:03b5121a232e 9501 }
pcercuei 0:03b5121a232e 9502 if (attname == ctxt->str_xmlns) {
pcercuei 0:03b5121a232e 9503 xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
pcercuei 0:03b5121a232e 9504 "redefinition of the xmlns prefix is forbidden\n",
pcercuei 0:03b5121a232e 9505 NULL, NULL, NULL);
pcercuei 0:03b5121a232e 9506 goto skip_ns;
pcercuei 0:03b5121a232e 9507 }
pcercuei 0:03b5121a232e 9508 if ((len == 29) &&
pcercuei 0:03b5121a232e 9509 (xmlStrEqual(URL,
pcercuei 0:03b5121a232e 9510 BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
pcercuei 0:03b5121a232e 9511 xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
pcercuei 0:03b5121a232e 9512 "reuse of the xmlns namespace name is forbidden\n",
pcercuei 0:03b5121a232e 9513 NULL, NULL, NULL);
pcercuei 0:03b5121a232e 9514 goto skip_ns;
pcercuei 0:03b5121a232e 9515 }
pcercuei 0:03b5121a232e 9516 if ((URL == NULL) || (URL[0] == 0)) {
pcercuei 0:03b5121a232e 9517 xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
pcercuei 0:03b5121a232e 9518 "xmlns:%s: Empty XML namespace is not allowed\n",
pcercuei 0:03b5121a232e 9519 attname, NULL, NULL);
pcercuei 0:03b5121a232e 9520 goto skip_ns;
pcercuei 0:03b5121a232e 9521 } else {
pcercuei 0:03b5121a232e 9522 uri = xmlParseURI((const char *) URL);
pcercuei 0:03b5121a232e 9523 if (uri == NULL) {
pcercuei 0:03b5121a232e 9524 xmlNsErr(ctxt, XML_WAR_NS_URI,
pcercuei 0:03b5121a232e 9525 "xmlns:%s: '%s' is not a valid URI\n",
pcercuei 0:03b5121a232e 9526 attname, URL, NULL);
pcercuei 0:03b5121a232e 9527 } else {
pcercuei 0:03b5121a232e 9528 if ((ctxt->pedantic) && (uri->scheme == NULL)) {
pcercuei 0:03b5121a232e 9529 xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
pcercuei 0:03b5121a232e 9530 "xmlns:%s: URI %s is not absolute\n",
pcercuei 0:03b5121a232e 9531 attname, URL, NULL);
pcercuei 0:03b5121a232e 9532 }
pcercuei 0:03b5121a232e 9533 xmlFreeURI(uri);
pcercuei 0:03b5121a232e 9534 }
pcercuei 0:03b5121a232e 9535 }
pcercuei 0:03b5121a232e 9536
pcercuei 0:03b5121a232e 9537 /*
pcercuei 0:03b5121a232e 9538 * check that it's not a defined namespace
pcercuei 0:03b5121a232e 9539 */
pcercuei 0:03b5121a232e 9540 for (j = 1;j <= nbNs;j++)
pcercuei 0:03b5121a232e 9541 if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
pcercuei 0:03b5121a232e 9542 break;
pcercuei 0:03b5121a232e 9543 if (j <= nbNs)
pcercuei 0:03b5121a232e 9544 xmlErrAttributeDup(ctxt, aprefix, attname);
pcercuei 0:03b5121a232e 9545 else
pcercuei 0:03b5121a232e 9546 if (nsPush(ctxt, attname, URL) > 0) nbNs++;
pcercuei 0:03b5121a232e 9547 skip_ns:
pcercuei 0:03b5121a232e 9548 if (alloc != 0) xmlFree(attvalue);
pcercuei 0:03b5121a232e 9549 if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
pcercuei 0:03b5121a232e 9550 break;
pcercuei 0:03b5121a232e 9551 if (!IS_BLANK_CH(RAW)) {
pcercuei 0:03b5121a232e 9552 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
pcercuei 0:03b5121a232e 9553 "attributes construct error\n");
pcercuei 0:03b5121a232e 9554 break;
pcercuei 0:03b5121a232e 9555 }
pcercuei 0:03b5121a232e 9556 SKIP_BLANKS;
pcercuei 0:03b5121a232e 9557 if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr))
pcercuei 0:03b5121a232e 9558 goto base_changed;
pcercuei 0:03b5121a232e 9559 continue;
pcercuei 0:03b5121a232e 9560 }
pcercuei 0:03b5121a232e 9561
pcercuei 0:03b5121a232e 9562 /*
pcercuei 0:03b5121a232e 9563 * Add the pair to atts
pcercuei 0:03b5121a232e 9564 */
pcercuei 0:03b5121a232e 9565 if ((atts == NULL) || (nbatts + 5 > maxatts)) {
pcercuei 0:03b5121a232e 9566 if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
pcercuei 0:03b5121a232e 9567 if (attvalue[len] == 0)
pcercuei 0:03b5121a232e 9568 xmlFree(attvalue);
pcercuei 0:03b5121a232e 9569 goto failed;
pcercuei 0:03b5121a232e 9570 }
pcercuei 0:03b5121a232e 9571 maxatts = ctxt->maxatts;
pcercuei 0:03b5121a232e 9572 atts = ctxt->atts;
pcercuei 0:03b5121a232e 9573 }
pcercuei 0:03b5121a232e 9574 ctxt->attallocs[nratts++] = alloc;
pcercuei 0:03b5121a232e 9575 atts[nbatts++] = attname;
pcercuei 0:03b5121a232e 9576 atts[nbatts++] = aprefix;
pcercuei 0:03b5121a232e 9577 atts[nbatts++] = NULL; /* the URI will be fetched later */
pcercuei 0:03b5121a232e 9578 atts[nbatts++] = attvalue;
pcercuei 0:03b5121a232e 9579 attvalue += len;
pcercuei 0:03b5121a232e 9580 atts[nbatts++] = attvalue;
pcercuei 0:03b5121a232e 9581 /*
pcercuei 0:03b5121a232e 9582 * tag if some deallocation is needed
pcercuei 0:03b5121a232e 9583 */
pcercuei 0:03b5121a232e 9584 if (alloc != 0) attval = 1;
pcercuei 0:03b5121a232e 9585 } else {
pcercuei 0:03b5121a232e 9586 if ((attvalue != NULL) && (attvalue[len] == 0))
pcercuei 0:03b5121a232e 9587 xmlFree(attvalue);
pcercuei 0:03b5121a232e 9588 }
pcercuei 0:03b5121a232e 9589
pcercuei 0:03b5121a232e 9590 failed:
pcercuei 0:03b5121a232e 9591
pcercuei 0:03b5121a232e 9592 GROW
pcercuei 0:03b5121a232e 9593 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 9594 break;
pcercuei 0:03b5121a232e 9595 if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr))
pcercuei 0:03b5121a232e 9596 goto base_changed;
pcercuei 0:03b5121a232e 9597 if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
pcercuei 0:03b5121a232e 9598 break;
pcercuei 0:03b5121a232e 9599 if (!IS_BLANK_CH(RAW)) {
pcercuei 0:03b5121a232e 9600 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
pcercuei 0:03b5121a232e 9601 "attributes construct error\n");
pcercuei 0:03b5121a232e 9602 break;
pcercuei 0:03b5121a232e 9603 }
pcercuei 0:03b5121a232e 9604 SKIP_BLANKS;
pcercuei 0:03b5121a232e 9605 if ((cons == ctxt->input->consumed) && (q == CUR_PTR) &&
pcercuei 0:03b5121a232e 9606 (attname == NULL) && (attvalue == NULL)) {
pcercuei 0:03b5121a232e 9607 xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
pcercuei 0:03b5121a232e 9608 "xmlParseStartTag: problem parsing attributes\n");
pcercuei 0:03b5121a232e 9609 break;
pcercuei 0:03b5121a232e 9610 }
pcercuei 0:03b5121a232e 9611 GROW;
pcercuei 0:03b5121a232e 9612 if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr))
pcercuei 0:03b5121a232e 9613 goto base_changed;
pcercuei 0:03b5121a232e 9614 }
pcercuei 0:03b5121a232e 9615
pcercuei 0:03b5121a232e 9616 /*
pcercuei 0:03b5121a232e 9617 * The attributes defaulting
pcercuei 0:03b5121a232e 9618 */
pcercuei 0:03b5121a232e 9619 if (ctxt->attsDefault != NULL) {
pcercuei 0:03b5121a232e 9620 xmlDefAttrsPtr defaults;
pcercuei 0:03b5121a232e 9621
pcercuei 0:03b5121a232e 9622 defaults = xmlHashLookup2(ctxt->attsDefault, localname, prefix);
pcercuei 0:03b5121a232e 9623 if (defaults != NULL) {
pcercuei 0:03b5121a232e 9624 for (i = 0;i < defaults->nbAttrs;i++) {
pcercuei 0:03b5121a232e 9625 attname = defaults->values[5 * i];
pcercuei 0:03b5121a232e 9626 aprefix = defaults->values[5 * i + 1];
pcercuei 0:03b5121a232e 9627
pcercuei 0:03b5121a232e 9628 /*
pcercuei 0:03b5121a232e 9629 * special work for namespaces defaulted defs
pcercuei 0:03b5121a232e 9630 */
pcercuei 0:03b5121a232e 9631 if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
pcercuei 0:03b5121a232e 9632 /*
pcercuei 0:03b5121a232e 9633 * check that it's not a defined namespace
pcercuei 0:03b5121a232e 9634 */
pcercuei 0:03b5121a232e 9635 for (j = 1;j <= nbNs;j++)
pcercuei 0:03b5121a232e 9636 if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
pcercuei 0:03b5121a232e 9637 break;
pcercuei 0:03b5121a232e 9638 if (j <= nbNs) continue;
pcercuei 0:03b5121a232e 9639
pcercuei 0:03b5121a232e 9640 nsname = xmlGetNamespace(ctxt, NULL);
pcercuei 0:03b5121a232e 9641 if (nsname != defaults->values[5 * i + 2]) {
pcercuei 0:03b5121a232e 9642 if (nsPush(ctxt, NULL,
pcercuei 0:03b5121a232e 9643 defaults->values[5 * i + 2]) > 0)
pcercuei 0:03b5121a232e 9644 nbNs++;
pcercuei 0:03b5121a232e 9645 }
pcercuei 0:03b5121a232e 9646 } else if (aprefix == ctxt->str_xmlns) {
pcercuei 0:03b5121a232e 9647 /*
pcercuei 0:03b5121a232e 9648 * check that it's not a defined namespace
pcercuei 0:03b5121a232e 9649 */
pcercuei 0:03b5121a232e 9650 for (j = 1;j <= nbNs;j++)
pcercuei 0:03b5121a232e 9651 if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
pcercuei 0:03b5121a232e 9652 break;
pcercuei 0:03b5121a232e 9653 if (j <= nbNs) continue;
pcercuei 0:03b5121a232e 9654
pcercuei 0:03b5121a232e 9655 nsname = xmlGetNamespace(ctxt, attname);
pcercuei 0:03b5121a232e 9656 if (nsname != defaults->values[2]) {
pcercuei 0:03b5121a232e 9657 if (nsPush(ctxt, attname,
pcercuei 0:03b5121a232e 9658 defaults->values[5 * i + 2]) > 0)
pcercuei 0:03b5121a232e 9659 nbNs++;
pcercuei 0:03b5121a232e 9660 }
pcercuei 0:03b5121a232e 9661 } else {
pcercuei 0:03b5121a232e 9662 /*
pcercuei 0:03b5121a232e 9663 * check that it's not a defined attribute
pcercuei 0:03b5121a232e 9664 */
pcercuei 0:03b5121a232e 9665 for (j = 0;j < nbatts;j+=5) {
pcercuei 0:03b5121a232e 9666 if ((attname == atts[j]) && (aprefix == atts[j+1]))
pcercuei 0:03b5121a232e 9667 break;
pcercuei 0:03b5121a232e 9668 }
pcercuei 0:03b5121a232e 9669 if (j < nbatts) continue;
pcercuei 0:03b5121a232e 9670
pcercuei 0:03b5121a232e 9671 if ((atts == NULL) || (nbatts + 5 > maxatts)) {
pcercuei 0:03b5121a232e 9672 if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
pcercuei 0:03b5121a232e 9673 return(NULL);
pcercuei 0:03b5121a232e 9674 }
pcercuei 0:03b5121a232e 9675 maxatts = ctxt->maxatts;
pcercuei 0:03b5121a232e 9676 atts = ctxt->atts;
pcercuei 0:03b5121a232e 9677 }
pcercuei 0:03b5121a232e 9678 atts[nbatts++] = attname;
pcercuei 0:03b5121a232e 9679 atts[nbatts++] = aprefix;
pcercuei 0:03b5121a232e 9680 if (aprefix == NULL)
pcercuei 0:03b5121a232e 9681 atts[nbatts++] = NULL;
pcercuei 0:03b5121a232e 9682 else
pcercuei 0:03b5121a232e 9683 atts[nbatts++] = xmlGetNamespace(ctxt, aprefix);
pcercuei 0:03b5121a232e 9684 atts[nbatts++] = defaults->values[5 * i + 2];
pcercuei 0:03b5121a232e 9685 atts[nbatts++] = defaults->values[5 * i + 3];
pcercuei 0:03b5121a232e 9686 if ((ctxt->standalone == 1) &&
pcercuei 0:03b5121a232e 9687 (defaults->values[5 * i + 4] != NULL)) {
pcercuei 0:03b5121a232e 9688 xmlValidityError(ctxt, XML_DTD_STANDALONE_DEFAULTED,
pcercuei 0:03b5121a232e 9689 "standalone: attribute %s on %s defaulted from external subset\n",
pcercuei 0:03b5121a232e 9690 attname, localname);
pcercuei 0:03b5121a232e 9691 }
pcercuei 0:03b5121a232e 9692 nbdef++;
pcercuei 0:03b5121a232e 9693 }
pcercuei 0:03b5121a232e 9694 }
pcercuei 0:03b5121a232e 9695 }
pcercuei 0:03b5121a232e 9696 }
pcercuei 0:03b5121a232e 9697
pcercuei 0:03b5121a232e 9698 /*
pcercuei 0:03b5121a232e 9699 * The attributes checkings
pcercuei 0:03b5121a232e 9700 */
pcercuei 0:03b5121a232e 9701 for (i = 0; i < nbatts;i += 5) {
pcercuei 0:03b5121a232e 9702 /*
pcercuei 0:03b5121a232e 9703 * The default namespace does not apply to attribute names.
pcercuei 0:03b5121a232e 9704 */
pcercuei 0:03b5121a232e 9705 if (atts[i + 1] != NULL) {
pcercuei 0:03b5121a232e 9706 nsname = xmlGetNamespace(ctxt, atts[i + 1]);
pcercuei 0:03b5121a232e 9707 if (nsname == NULL) {
pcercuei 0:03b5121a232e 9708 xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
pcercuei 0:03b5121a232e 9709 "Namespace prefix %s for %s on %s is not defined\n",
pcercuei 0:03b5121a232e 9710 atts[i + 1], atts[i], localname);
pcercuei 0:03b5121a232e 9711 }
pcercuei 0:03b5121a232e 9712 atts[i + 2] = nsname;
pcercuei 0:03b5121a232e 9713 } else
pcercuei 0:03b5121a232e 9714 nsname = NULL;
pcercuei 0:03b5121a232e 9715 /*
pcercuei 0:03b5121a232e 9716 * [ WFC: Unique Att Spec ]
pcercuei 0:03b5121a232e 9717 * No attribute name may appear more than once in the same
pcercuei 0:03b5121a232e 9718 * start-tag or empty-element tag.
pcercuei 0:03b5121a232e 9719 * As extended by the Namespace in XML REC.
pcercuei 0:03b5121a232e 9720 */
pcercuei 0:03b5121a232e 9721 for (j = 0; j < i;j += 5) {
pcercuei 0:03b5121a232e 9722 if (atts[i] == atts[j]) {
pcercuei 0:03b5121a232e 9723 if (atts[i+1] == atts[j+1]) {
pcercuei 0:03b5121a232e 9724 xmlErrAttributeDup(ctxt, atts[i+1], atts[i]);
pcercuei 0:03b5121a232e 9725 break;
pcercuei 0:03b5121a232e 9726 }
pcercuei 0:03b5121a232e 9727 if ((nsname != NULL) && (atts[j + 2] == nsname)) {
pcercuei 0:03b5121a232e 9728 xmlNsErr(ctxt, XML_NS_ERR_ATTRIBUTE_REDEFINED,
pcercuei 0:03b5121a232e 9729 "Namespaced Attribute %s in '%s' redefined\n",
pcercuei 0:03b5121a232e 9730 atts[i], nsname, NULL);
pcercuei 0:03b5121a232e 9731 break;
pcercuei 0:03b5121a232e 9732 }
pcercuei 0:03b5121a232e 9733 }
pcercuei 0:03b5121a232e 9734 }
pcercuei 0:03b5121a232e 9735 }
pcercuei 0:03b5121a232e 9736
pcercuei 0:03b5121a232e 9737 nsname = xmlGetNamespace(ctxt, prefix);
pcercuei 0:03b5121a232e 9738 if ((prefix != NULL) && (nsname == NULL)) {
pcercuei 0:03b5121a232e 9739 xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
pcercuei 0:03b5121a232e 9740 "Namespace prefix %s on %s is not defined\n",
pcercuei 0:03b5121a232e 9741 prefix, localname, NULL);
pcercuei 0:03b5121a232e 9742 }
pcercuei 0:03b5121a232e 9743 *pref = prefix;
pcercuei 0:03b5121a232e 9744 *URI = nsname;
pcercuei 0:03b5121a232e 9745
pcercuei 0:03b5121a232e 9746 /*
pcercuei 0:03b5121a232e 9747 * SAX: Start of Element !
pcercuei 0:03b5121a232e 9748 */
pcercuei 0:03b5121a232e 9749 if ((ctxt->sax != NULL) && (ctxt->sax->startElementNs != NULL) &&
pcercuei 0:03b5121a232e 9750 (!ctxt->disableSAX)) {
pcercuei 0:03b5121a232e 9751 if (nbNs > 0)
pcercuei 0:03b5121a232e 9752 ctxt->sax->startElementNs(ctxt->userData, localname, prefix,
pcercuei 0:03b5121a232e 9753 nsname, nbNs, &ctxt->nsTab[ctxt->nsNr - 2 * nbNs],
pcercuei 0:03b5121a232e 9754 nbatts / 5, nbdef, atts);
pcercuei 0:03b5121a232e 9755 else
pcercuei 0:03b5121a232e 9756 ctxt->sax->startElementNs(ctxt->userData, localname, prefix,
pcercuei 0:03b5121a232e 9757 nsname, 0, NULL, nbatts / 5, nbdef, atts);
pcercuei 0:03b5121a232e 9758 }
pcercuei 0:03b5121a232e 9759
pcercuei 0:03b5121a232e 9760 /*
pcercuei 0:03b5121a232e 9761 * Free up attribute allocated strings if needed
pcercuei 0:03b5121a232e 9762 */
pcercuei 0:03b5121a232e 9763 if (attval != 0) {
pcercuei 0:03b5121a232e 9764 for (i = 3,j = 0; j < nratts;i += 5,j++)
pcercuei 0:03b5121a232e 9765 if ((ctxt->attallocs[j] != 0) && (atts[i] != NULL))
pcercuei 0:03b5121a232e 9766 xmlFree((xmlChar *) atts[i]);
pcercuei 0:03b5121a232e 9767 }
pcercuei 0:03b5121a232e 9768
pcercuei 0:03b5121a232e 9769 return(localname);
pcercuei 0:03b5121a232e 9770
pcercuei 0:03b5121a232e 9771 base_changed:
pcercuei 0:03b5121a232e 9772 /*
pcercuei 0:03b5121a232e 9773 * the attribute strings are valid iif the base didn't changed
pcercuei 0:03b5121a232e 9774 */
pcercuei 0:03b5121a232e 9775 if (attval != 0) {
pcercuei 0:03b5121a232e 9776 for (i = 3,j = 0; j < nratts;i += 5,j++)
pcercuei 0:03b5121a232e 9777 if ((ctxt->attallocs[j] != 0) && (atts[i] != NULL))
pcercuei 0:03b5121a232e 9778 xmlFree((xmlChar *) atts[i]);
pcercuei 0:03b5121a232e 9779 }
pcercuei 0:03b5121a232e 9780
pcercuei 0:03b5121a232e 9781 /*
pcercuei 0:03b5121a232e 9782 * We can't switch from one entity to another in the middle
pcercuei 0:03b5121a232e 9783 * of a start tag
pcercuei 0:03b5121a232e 9784 */
pcercuei 0:03b5121a232e 9785 if (inputNr != ctxt->inputNr) {
pcercuei 0:03b5121a232e 9786 xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
pcercuei 0:03b5121a232e 9787 "Start tag doesn't start and stop in the same entity\n");
pcercuei 0:03b5121a232e 9788 return(NULL);
pcercuei 0:03b5121a232e 9789 }
pcercuei 0:03b5121a232e 9790
pcercuei 0:03b5121a232e 9791 ctxt->input->cur = ctxt->input->base + cur;
pcercuei 0:03b5121a232e 9792 ctxt->input->line = oldline;
pcercuei 0:03b5121a232e 9793 ctxt->input->col = oldcol;
pcercuei 0:03b5121a232e 9794 if (ctxt->wellFormed == 1) {
pcercuei 0:03b5121a232e 9795 goto reparse;
pcercuei 0:03b5121a232e 9796 }
pcercuei 0:03b5121a232e 9797 return(NULL);
pcercuei 0:03b5121a232e 9798 }
pcercuei 0:03b5121a232e 9799
pcercuei 0:03b5121a232e 9800 /**
pcercuei 0:03b5121a232e 9801 * xmlParseEndTag2:
pcercuei 0:03b5121a232e 9802 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 9803 * @line: line of the start tag
pcercuei 0:03b5121a232e 9804 * @nsNr: number of namespaces on the start tag
pcercuei 0:03b5121a232e 9805 *
pcercuei 0:03b5121a232e 9806 * parse an end of tag
pcercuei 0:03b5121a232e 9807 *
pcercuei 0:03b5121a232e 9808 * [42] ETag ::= '</' Name S? '>'
pcercuei 0:03b5121a232e 9809 *
pcercuei 0:03b5121a232e 9810 * With namespace
pcercuei 0:03b5121a232e 9811 *
pcercuei 0:03b5121a232e 9812 * [NS 9] ETag ::= '</' QName S? '>'
pcercuei 0:03b5121a232e 9813 */
pcercuei 0:03b5121a232e 9814
pcercuei 0:03b5121a232e 9815 static void
pcercuei 0:03b5121a232e 9816 xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlChar *prefix,
pcercuei 0:03b5121a232e 9817 const xmlChar *URI, int line, int nsNr, int tlen) {
pcercuei 0:03b5121a232e 9818 const xmlChar *name;
pcercuei 0:03b5121a232e 9819
pcercuei 0:03b5121a232e 9820 GROW;
pcercuei 0:03b5121a232e 9821 if ((RAW != '<') || (NXT(1) != '/')) {
pcercuei 0:03b5121a232e 9822 xmlFatalErr(ctxt, XML_ERR_LTSLASH_REQUIRED, NULL);
pcercuei 0:03b5121a232e 9823 return;
pcercuei 0:03b5121a232e 9824 }
pcercuei 0:03b5121a232e 9825 SKIP(2);
pcercuei 0:03b5121a232e 9826
pcercuei 0:03b5121a232e 9827 if ((tlen > 0) && (xmlStrncmp(ctxt->input->cur, ctxt->name, tlen) == 0)) {
pcercuei 0:03b5121a232e 9828 if (ctxt->input->cur[tlen] == '>') {
pcercuei 0:03b5121a232e 9829 ctxt->input->cur += tlen + 1;
pcercuei 0:03b5121a232e 9830 ctxt->input->col += tlen + 1;
pcercuei 0:03b5121a232e 9831 goto done;
pcercuei 0:03b5121a232e 9832 }
pcercuei 0:03b5121a232e 9833 ctxt->input->cur += tlen;
pcercuei 0:03b5121a232e 9834 ctxt->input->col += tlen;
pcercuei 0:03b5121a232e 9835 name = (xmlChar*)1;
pcercuei 0:03b5121a232e 9836 } else {
pcercuei 0:03b5121a232e 9837 if (prefix == NULL)
pcercuei 0:03b5121a232e 9838 name = xmlParseNameAndCompare(ctxt, ctxt->name);
pcercuei 0:03b5121a232e 9839 else
pcercuei 0:03b5121a232e 9840 name = xmlParseQNameAndCompare(ctxt, ctxt->name, prefix);
pcercuei 0:03b5121a232e 9841 }
pcercuei 0:03b5121a232e 9842
pcercuei 0:03b5121a232e 9843 /*
pcercuei 0:03b5121a232e 9844 * We should definitely be at the ending "S? '>'" part
pcercuei 0:03b5121a232e 9845 */
pcercuei 0:03b5121a232e 9846 GROW;
pcercuei 0:03b5121a232e 9847 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 9848 return;
pcercuei 0:03b5121a232e 9849 SKIP_BLANKS;
pcercuei 0:03b5121a232e 9850 if ((!IS_BYTE_CHAR(RAW)) || (RAW != '>')) {
pcercuei 0:03b5121a232e 9851 xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
pcercuei 0:03b5121a232e 9852 } else
pcercuei 0:03b5121a232e 9853 NEXT1;
pcercuei 0:03b5121a232e 9854
pcercuei 0:03b5121a232e 9855 /*
pcercuei 0:03b5121a232e 9856 * [ WFC: Element Type Match ]
pcercuei 0:03b5121a232e 9857 * The Name in an element's end-tag must match the element type in the
pcercuei 0:03b5121a232e 9858 * start-tag.
pcercuei 0:03b5121a232e 9859 *
pcercuei 0:03b5121a232e 9860 */
pcercuei 0:03b5121a232e 9861 if (name != (xmlChar*)1) {
pcercuei 0:03b5121a232e 9862 if (name == NULL) name = BAD_CAST "unparseable";
pcercuei 0:03b5121a232e 9863 if ((line == 0) && (ctxt->node != NULL))
pcercuei 0:03b5121a232e 9864 line = ctxt->node->line;
pcercuei 0:03b5121a232e 9865 xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
pcercuei 0:03b5121a232e 9866 "Opening and ending tag mismatch: %s line %d and %s\n",
pcercuei 0:03b5121a232e 9867 ctxt->name, line, name);
pcercuei 0:03b5121a232e 9868 }
pcercuei 0:03b5121a232e 9869
pcercuei 0:03b5121a232e 9870 /*
pcercuei 0:03b5121a232e 9871 * SAX: End of Tag
pcercuei 0:03b5121a232e 9872 */
pcercuei 0:03b5121a232e 9873 done:
pcercuei 0:03b5121a232e 9874 if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) &&
pcercuei 0:03b5121a232e 9875 (!ctxt->disableSAX))
pcercuei 0:03b5121a232e 9876 ctxt->sax->endElementNs(ctxt->userData, ctxt->name, prefix, URI);
pcercuei 0:03b5121a232e 9877
pcercuei 0:03b5121a232e 9878 spacePop(ctxt);
pcercuei 0:03b5121a232e 9879 if (nsNr != 0)
pcercuei 0:03b5121a232e 9880 nsPop(ctxt, nsNr);
pcercuei 0:03b5121a232e 9881 return;
pcercuei 0:03b5121a232e 9882 }
pcercuei 0:03b5121a232e 9883
pcercuei 0:03b5121a232e 9884 /**
pcercuei 0:03b5121a232e 9885 * xmlParseCDSect:
pcercuei 0:03b5121a232e 9886 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 9887 *
pcercuei 0:03b5121a232e 9888 * Parse escaped pure raw content.
pcercuei 0:03b5121a232e 9889 *
pcercuei 0:03b5121a232e 9890 * [18] CDSect ::= CDStart CData CDEnd
pcercuei 0:03b5121a232e 9891 *
pcercuei 0:03b5121a232e 9892 * [19] CDStart ::= '<![CDATA['
pcercuei 0:03b5121a232e 9893 *
pcercuei 0:03b5121a232e 9894 * [20] Data ::= (Char* - (Char* ']]>' Char*))
pcercuei 0:03b5121a232e 9895 *
pcercuei 0:03b5121a232e 9896 * [21] CDEnd ::= ']]>'
pcercuei 0:03b5121a232e 9897 */
pcercuei 0:03b5121a232e 9898 void
pcercuei 0:03b5121a232e 9899 xmlParseCDSect(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 9900 xmlChar *buf = NULL;
pcercuei 0:03b5121a232e 9901 int len = 0;
pcercuei 0:03b5121a232e 9902 int size = XML_PARSER_BUFFER_SIZE;
pcercuei 0:03b5121a232e 9903 int r, rl;
pcercuei 0:03b5121a232e 9904 int s, sl;
pcercuei 0:03b5121a232e 9905 int cur, l;
pcercuei 0:03b5121a232e 9906 int count = 0;
pcercuei 0:03b5121a232e 9907
pcercuei 0:03b5121a232e 9908 /* Check 2.6.0 was NXT(0) not RAW */
pcercuei 0:03b5121a232e 9909 if (CMP9(CUR_PTR, '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[')) {
pcercuei 0:03b5121a232e 9910 SKIP(9);
pcercuei 0:03b5121a232e 9911 } else
pcercuei 0:03b5121a232e 9912 return;
pcercuei 0:03b5121a232e 9913
pcercuei 0:03b5121a232e 9914 ctxt->instate = XML_PARSER_CDATA_SECTION;
pcercuei 0:03b5121a232e 9915 r = CUR_CHAR(rl);
pcercuei 0:03b5121a232e 9916 if (!IS_CHAR(r)) {
pcercuei 0:03b5121a232e 9917 xmlFatalErr(ctxt, XML_ERR_CDATA_NOT_FINISHED, NULL);
pcercuei 0:03b5121a232e 9918 ctxt->instate = XML_PARSER_CONTENT;
pcercuei 0:03b5121a232e 9919 return;
pcercuei 0:03b5121a232e 9920 }
pcercuei 0:03b5121a232e 9921 NEXTL(rl);
pcercuei 0:03b5121a232e 9922 s = CUR_CHAR(sl);
pcercuei 0:03b5121a232e 9923 if (!IS_CHAR(s)) {
pcercuei 0:03b5121a232e 9924 xmlFatalErr(ctxt, XML_ERR_CDATA_NOT_FINISHED, NULL);
pcercuei 0:03b5121a232e 9925 ctxt->instate = XML_PARSER_CONTENT;
pcercuei 0:03b5121a232e 9926 return;
pcercuei 0:03b5121a232e 9927 }
pcercuei 0:03b5121a232e 9928 NEXTL(sl);
pcercuei 0:03b5121a232e 9929 cur = CUR_CHAR(l);
pcercuei 0:03b5121a232e 9930 buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
pcercuei 0:03b5121a232e 9931 if (buf == NULL) {
pcercuei 0:03b5121a232e 9932 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 9933 return;
pcercuei 0:03b5121a232e 9934 }
pcercuei 0:03b5121a232e 9935 while (IS_CHAR(cur) &&
pcercuei 0:03b5121a232e 9936 ((r != ']') || (s != ']') || (cur != '>'))) {
pcercuei 0:03b5121a232e 9937 if (len + 5 >= size) {
pcercuei 0:03b5121a232e 9938 xmlChar *tmp;
pcercuei 0:03b5121a232e 9939
pcercuei 0:03b5121a232e 9940 if ((size > XML_MAX_TEXT_LENGTH) &&
pcercuei 0:03b5121a232e 9941 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
pcercuei 0:03b5121a232e 9942 xmlFatalErrMsgStr(ctxt, XML_ERR_CDATA_NOT_FINISHED,
pcercuei 0:03b5121a232e 9943 "CData section too big found", NULL);
pcercuei 0:03b5121a232e 9944 xmlFree (buf);
pcercuei 0:03b5121a232e 9945 return;
pcercuei 0:03b5121a232e 9946 }
pcercuei 0:03b5121a232e 9947 tmp = (xmlChar *) xmlRealloc(buf, size * 2 * sizeof(xmlChar));
pcercuei 0:03b5121a232e 9948 if (tmp == NULL) {
pcercuei 0:03b5121a232e 9949 xmlFree(buf);
pcercuei 0:03b5121a232e 9950 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 9951 return;
pcercuei 0:03b5121a232e 9952 }
pcercuei 0:03b5121a232e 9953 buf = tmp;
pcercuei 0:03b5121a232e 9954 size *= 2;
pcercuei 0:03b5121a232e 9955 }
pcercuei 0:03b5121a232e 9956 COPY_BUF(rl,buf,len,r);
pcercuei 0:03b5121a232e 9957 r = s;
pcercuei 0:03b5121a232e 9958 rl = sl;
pcercuei 0:03b5121a232e 9959 s = cur;
pcercuei 0:03b5121a232e 9960 sl = l;
pcercuei 0:03b5121a232e 9961 count++;
pcercuei 0:03b5121a232e 9962 if (count > 50) {
pcercuei 0:03b5121a232e 9963 GROW;
pcercuei 0:03b5121a232e 9964 if (ctxt->instate == XML_PARSER_EOF) {
pcercuei 0:03b5121a232e 9965 xmlFree(buf);
pcercuei 0:03b5121a232e 9966 return;
pcercuei 0:03b5121a232e 9967 }
pcercuei 0:03b5121a232e 9968 count = 0;
pcercuei 0:03b5121a232e 9969 }
pcercuei 0:03b5121a232e 9970 NEXTL(l);
pcercuei 0:03b5121a232e 9971 cur = CUR_CHAR(l);
pcercuei 0:03b5121a232e 9972 }
pcercuei 0:03b5121a232e 9973 buf[len] = 0;
pcercuei 0:03b5121a232e 9974 ctxt->instate = XML_PARSER_CONTENT;
pcercuei 0:03b5121a232e 9975 if (cur != '>') {
pcercuei 0:03b5121a232e 9976 xmlFatalErrMsgStr(ctxt, XML_ERR_CDATA_NOT_FINISHED,
pcercuei 0:03b5121a232e 9977 "CData section not finished\n%.50s\n", buf);
pcercuei 0:03b5121a232e 9978 xmlFree(buf);
pcercuei 0:03b5121a232e 9979 return;
pcercuei 0:03b5121a232e 9980 }
pcercuei 0:03b5121a232e 9981 NEXTL(l);
pcercuei 0:03b5121a232e 9982
pcercuei 0:03b5121a232e 9983 /*
pcercuei 0:03b5121a232e 9984 * OK the buffer is to be consumed as cdata.
pcercuei 0:03b5121a232e 9985 */
pcercuei 0:03b5121a232e 9986 if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
pcercuei 0:03b5121a232e 9987 if (ctxt->sax->cdataBlock != NULL)
pcercuei 0:03b5121a232e 9988 ctxt->sax->cdataBlock(ctxt->userData, buf, len);
pcercuei 0:03b5121a232e 9989 else if (ctxt->sax->characters != NULL)
pcercuei 0:03b5121a232e 9990 ctxt->sax->characters(ctxt->userData, buf, len);
pcercuei 0:03b5121a232e 9991 }
pcercuei 0:03b5121a232e 9992 xmlFree(buf);
pcercuei 0:03b5121a232e 9993 }
pcercuei 0:03b5121a232e 9994
pcercuei 0:03b5121a232e 9995 /**
pcercuei 0:03b5121a232e 9996 * xmlParseContent:
pcercuei 0:03b5121a232e 9997 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 9998 *
pcercuei 0:03b5121a232e 9999 * Parse a content:
pcercuei 0:03b5121a232e 10000 *
pcercuei 0:03b5121a232e 10001 * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
pcercuei 0:03b5121a232e 10002 */
pcercuei 0:03b5121a232e 10003
pcercuei 0:03b5121a232e 10004 void
pcercuei 0:03b5121a232e 10005 xmlParseContent(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 10006 GROW;
pcercuei 0:03b5121a232e 10007 while ((RAW != 0) &&
pcercuei 0:03b5121a232e 10008 ((RAW != '<') || (NXT(1) != '/')) &&
pcercuei 0:03b5121a232e 10009 (ctxt->instate != XML_PARSER_EOF)) {
pcercuei 0:03b5121a232e 10010 const xmlChar *test = CUR_PTR;
pcercuei 0:03b5121a232e 10011 unsigned int cons = ctxt->input->consumed;
pcercuei 0:03b5121a232e 10012 const xmlChar *cur = ctxt->input->cur;
pcercuei 0:03b5121a232e 10013
pcercuei 0:03b5121a232e 10014 /*
pcercuei 0:03b5121a232e 10015 * First case : a Processing Instruction.
pcercuei 0:03b5121a232e 10016 */
pcercuei 0:03b5121a232e 10017 if ((*cur == '<') && (cur[1] == '?')) {
pcercuei 0:03b5121a232e 10018 xmlParsePI(ctxt);
pcercuei 0:03b5121a232e 10019 }
pcercuei 0:03b5121a232e 10020
pcercuei 0:03b5121a232e 10021 /*
pcercuei 0:03b5121a232e 10022 * Second case : a CDSection
pcercuei 0:03b5121a232e 10023 */
pcercuei 0:03b5121a232e 10024 /* 2.6.0 test was *cur not RAW */
pcercuei 0:03b5121a232e 10025 else if (CMP9(CUR_PTR, '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[')) {
pcercuei 0:03b5121a232e 10026 xmlParseCDSect(ctxt);
pcercuei 0:03b5121a232e 10027 }
pcercuei 0:03b5121a232e 10028
pcercuei 0:03b5121a232e 10029 /*
pcercuei 0:03b5121a232e 10030 * Third case : a comment
pcercuei 0:03b5121a232e 10031 */
pcercuei 0:03b5121a232e 10032 else if ((*cur == '<') && (NXT(1) == '!') &&
pcercuei 0:03b5121a232e 10033 (NXT(2) == '-') && (NXT(3) == '-')) {
pcercuei 0:03b5121a232e 10034 xmlParseComment(ctxt);
pcercuei 0:03b5121a232e 10035 ctxt->instate = XML_PARSER_CONTENT;
pcercuei 0:03b5121a232e 10036 }
pcercuei 0:03b5121a232e 10037
pcercuei 0:03b5121a232e 10038 /*
pcercuei 0:03b5121a232e 10039 * Fourth case : a sub-element.
pcercuei 0:03b5121a232e 10040 */
pcercuei 0:03b5121a232e 10041 else if (*cur == '<') {
pcercuei 0:03b5121a232e 10042 xmlParseElement(ctxt);
pcercuei 0:03b5121a232e 10043 }
pcercuei 0:03b5121a232e 10044
pcercuei 0:03b5121a232e 10045 /*
pcercuei 0:03b5121a232e 10046 * Fifth case : a reference. If if has not been resolved,
pcercuei 0:03b5121a232e 10047 * parsing returns it's Name, create the node
pcercuei 0:03b5121a232e 10048 */
pcercuei 0:03b5121a232e 10049
pcercuei 0:03b5121a232e 10050 else if (*cur == '&') {
pcercuei 0:03b5121a232e 10051 xmlParseReference(ctxt);
pcercuei 0:03b5121a232e 10052 }
pcercuei 0:03b5121a232e 10053
pcercuei 0:03b5121a232e 10054 /*
pcercuei 0:03b5121a232e 10055 * Last case, text. Note that References are handled directly.
pcercuei 0:03b5121a232e 10056 */
pcercuei 0:03b5121a232e 10057 else {
pcercuei 0:03b5121a232e 10058 xmlParseCharData(ctxt, 0);
pcercuei 0:03b5121a232e 10059 }
pcercuei 0:03b5121a232e 10060
pcercuei 0:03b5121a232e 10061 GROW;
pcercuei 0:03b5121a232e 10062 /*
pcercuei 0:03b5121a232e 10063 * Pop-up of finished entities.
pcercuei 0:03b5121a232e 10064 */
pcercuei 0:03b5121a232e 10065 while ((RAW == 0) && (ctxt->inputNr > 1))
pcercuei 0:03b5121a232e 10066 xmlPopInput(ctxt);
pcercuei 0:03b5121a232e 10067 SHRINK;
pcercuei 0:03b5121a232e 10068
pcercuei 0:03b5121a232e 10069 if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
pcercuei 0:03b5121a232e 10070 xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
pcercuei 0:03b5121a232e 10071 "detected an error in element content\n");
pcercuei 0:03b5121a232e 10072 xmlHaltParser(ctxt);
pcercuei 0:03b5121a232e 10073 break;
pcercuei 0:03b5121a232e 10074 }
pcercuei 0:03b5121a232e 10075 }
pcercuei 0:03b5121a232e 10076 }
pcercuei 0:03b5121a232e 10077
pcercuei 0:03b5121a232e 10078 /**
pcercuei 0:03b5121a232e 10079 * xmlParseElement:
pcercuei 0:03b5121a232e 10080 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 10081 *
pcercuei 0:03b5121a232e 10082 * parse an XML element, this is highly recursive
pcercuei 0:03b5121a232e 10083 *
pcercuei 0:03b5121a232e 10084 * [39] element ::= EmptyElemTag | STag content ETag
pcercuei 0:03b5121a232e 10085 *
pcercuei 0:03b5121a232e 10086 * [ WFC: Element Type Match ]
pcercuei 0:03b5121a232e 10087 * The Name in an element's end-tag must match the element type in the
pcercuei 0:03b5121a232e 10088 * start-tag.
pcercuei 0:03b5121a232e 10089 *
pcercuei 0:03b5121a232e 10090 */
pcercuei 0:03b5121a232e 10091
pcercuei 0:03b5121a232e 10092 void
pcercuei 0:03b5121a232e 10093 xmlParseElement(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 10094 const xmlChar *name;
pcercuei 0:03b5121a232e 10095 const xmlChar *prefix = NULL;
pcercuei 0:03b5121a232e 10096 const xmlChar *URI = NULL;
pcercuei 0:03b5121a232e 10097 xmlParserNodeInfo node_info;
pcercuei 0:03b5121a232e 10098 int line, tlen = 0;
pcercuei 0:03b5121a232e 10099 xmlNodePtr ret;
pcercuei 0:03b5121a232e 10100 int nsNr = ctxt->nsNr;
pcercuei 0:03b5121a232e 10101
pcercuei 0:03b5121a232e 10102 if (((unsigned int) ctxt->nameNr > xmlParserMaxDepth) &&
pcercuei 0:03b5121a232e 10103 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
pcercuei 0:03b5121a232e 10104 xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
pcercuei 0:03b5121a232e 10105 "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
pcercuei 0:03b5121a232e 10106 xmlParserMaxDepth);
pcercuei 0:03b5121a232e 10107 xmlHaltParser(ctxt);
pcercuei 0:03b5121a232e 10108 return;
pcercuei 0:03b5121a232e 10109 }
pcercuei 0:03b5121a232e 10110
pcercuei 0:03b5121a232e 10111 /* Capture start position */
pcercuei 0:03b5121a232e 10112 if (ctxt->record_info) {
pcercuei 0:03b5121a232e 10113 node_info.begin_pos = ctxt->input->consumed +
pcercuei 0:03b5121a232e 10114 (CUR_PTR - ctxt->input->base);
pcercuei 0:03b5121a232e 10115 node_info.begin_line = ctxt->input->line;
pcercuei 0:03b5121a232e 10116 }
pcercuei 0:03b5121a232e 10117
pcercuei 0:03b5121a232e 10118 if (ctxt->spaceNr == 0)
pcercuei 0:03b5121a232e 10119 spacePush(ctxt, -1);
pcercuei 0:03b5121a232e 10120 else if (*ctxt->space == -2)
pcercuei 0:03b5121a232e 10121 spacePush(ctxt, -1);
pcercuei 0:03b5121a232e 10122 else
pcercuei 0:03b5121a232e 10123 spacePush(ctxt, *ctxt->space);
pcercuei 0:03b5121a232e 10124
pcercuei 0:03b5121a232e 10125 line = ctxt->input->line;
pcercuei 0:03b5121a232e 10126 #ifdef LIBXML_SAX1_ENABLED
pcercuei 0:03b5121a232e 10127 if (ctxt->sax2)
pcercuei 0:03b5121a232e 10128 #endif /* LIBXML_SAX1_ENABLED */
pcercuei 0:03b5121a232e 10129 name = xmlParseStartTag2(ctxt, &prefix, &URI, &tlen);
pcercuei 0:03b5121a232e 10130 #ifdef LIBXML_SAX1_ENABLED
pcercuei 0:03b5121a232e 10131 else
pcercuei 0:03b5121a232e 10132 name = xmlParseStartTag(ctxt);
pcercuei 0:03b5121a232e 10133 #endif /* LIBXML_SAX1_ENABLED */
pcercuei 0:03b5121a232e 10134 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 10135 return;
pcercuei 0:03b5121a232e 10136 if (name == NULL) {
pcercuei 0:03b5121a232e 10137 spacePop(ctxt);
pcercuei 0:03b5121a232e 10138 return;
pcercuei 0:03b5121a232e 10139 }
pcercuei 0:03b5121a232e 10140 namePush(ctxt, name);
pcercuei 0:03b5121a232e 10141 ret = ctxt->node;
pcercuei 0:03b5121a232e 10142
pcercuei 0:03b5121a232e 10143 #ifdef LIBXML_VALID_ENABLED
pcercuei 0:03b5121a232e 10144 /*
pcercuei 0:03b5121a232e 10145 * [ VC: Root Element Type ]
pcercuei 0:03b5121a232e 10146 * The Name in the document type declaration must match the element
pcercuei 0:03b5121a232e 10147 * type of the root element.
pcercuei 0:03b5121a232e 10148 */
pcercuei 0:03b5121a232e 10149 if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
pcercuei 0:03b5121a232e 10150 ctxt->node && (ctxt->node == ctxt->myDoc->children))
pcercuei 0:03b5121a232e 10151 ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
pcercuei 0:03b5121a232e 10152 #endif /* LIBXML_VALID_ENABLED */
pcercuei 0:03b5121a232e 10153
pcercuei 0:03b5121a232e 10154 /*
pcercuei 0:03b5121a232e 10155 * Check for an Empty Element.
pcercuei 0:03b5121a232e 10156 */
pcercuei 0:03b5121a232e 10157 if ((RAW == '/') && (NXT(1) == '>')) {
pcercuei 0:03b5121a232e 10158 SKIP(2);
pcercuei 0:03b5121a232e 10159 if (ctxt->sax2) {
pcercuei 0:03b5121a232e 10160 if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) &&
pcercuei 0:03b5121a232e 10161 (!ctxt->disableSAX))
pcercuei 0:03b5121a232e 10162 ctxt->sax->endElementNs(ctxt->userData, name, prefix, URI);
pcercuei 0:03b5121a232e 10163 #ifdef LIBXML_SAX1_ENABLED
pcercuei 0:03b5121a232e 10164 } else {
pcercuei 0:03b5121a232e 10165 if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
pcercuei 0:03b5121a232e 10166 (!ctxt->disableSAX))
pcercuei 0:03b5121a232e 10167 ctxt->sax->endElement(ctxt->userData, name);
pcercuei 0:03b5121a232e 10168 #endif /* LIBXML_SAX1_ENABLED */
pcercuei 0:03b5121a232e 10169 }
pcercuei 0:03b5121a232e 10170 namePop(ctxt);
pcercuei 0:03b5121a232e 10171 spacePop(ctxt);
pcercuei 0:03b5121a232e 10172 if (nsNr != ctxt->nsNr)
pcercuei 0:03b5121a232e 10173 nsPop(ctxt, ctxt->nsNr - nsNr);
pcercuei 0:03b5121a232e 10174 if ( ret != NULL && ctxt->record_info ) {
pcercuei 0:03b5121a232e 10175 node_info.end_pos = ctxt->input->consumed +
pcercuei 0:03b5121a232e 10176 (CUR_PTR - ctxt->input->base);
pcercuei 0:03b5121a232e 10177 node_info.end_line = ctxt->input->line;
pcercuei 0:03b5121a232e 10178 node_info.node = ret;
pcercuei 0:03b5121a232e 10179 xmlParserAddNodeInfo(ctxt, &node_info);
pcercuei 0:03b5121a232e 10180 }
pcercuei 0:03b5121a232e 10181 return;
pcercuei 0:03b5121a232e 10182 }
pcercuei 0:03b5121a232e 10183 if (RAW == '>') {
pcercuei 0:03b5121a232e 10184 NEXT1;
pcercuei 0:03b5121a232e 10185 } else {
pcercuei 0:03b5121a232e 10186 xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_GT_REQUIRED,
pcercuei 0:03b5121a232e 10187 "Couldn't find end of Start Tag %s line %d\n",
pcercuei 0:03b5121a232e 10188 name, line, NULL);
pcercuei 0:03b5121a232e 10189
pcercuei 0:03b5121a232e 10190 /*
pcercuei 0:03b5121a232e 10191 * end of parsing of this node.
pcercuei 0:03b5121a232e 10192 */
pcercuei 0:03b5121a232e 10193 nodePop(ctxt);
pcercuei 0:03b5121a232e 10194 namePop(ctxt);
pcercuei 0:03b5121a232e 10195 spacePop(ctxt);
pcercuei 0:03b5121a232e 10196 if (nsNr != ctxt->nsNr)
pcercuei 0:03b5121a232e 10197 nsPop(ctxt, ctxt->nsNr - nsNr);
pcercuei 0:03b5121a232e 10198
pcercuei 0:03b5121a232e 10199 /*
pcercuei 0:03b5121a232e 10200 * Capture end position and add node
pcercuei 0:03b5121a232e 10201 */
pcercuei 0:03b5121a232e 10202 if ( ret != NULL && ctxt->record_info ) {
pcercuei 0:03b5121a232e 10203 node_info.end_pos = ctxt->input->consumed +
pcercuei 0:03b5121a232e 10204 (CUR_PTR - ctxt->input->base);
pcercuei 0:03b5121a232e 10205 node_info.end_line = ctxt->input->line;
pcercuei 0:03b5121a232e 10206 node_info.node = ret;
pcercuei 0:03b5121a232e 10207 xmlParserAddNodeInfo(ctxt, &node_info);
pcercuei 0:03b5121a232e 10208 }
pcercuei 0:03b5121a232e 10209 return;
pcercuei 0:03b5121a232e 10210 }
pcercuei 0:03b5121a232e 10211
pcercuei 0:03b5121a232e 10212 /*
pcercuei 0:03b5121a232e 10213 * Parse the content of the element:
pcercuei 0:03b5121a232e 10214 */
pcercuei 0:03b5121a232e 10215 xmlParseContent(ctxt);
pcercuei 0:03b5121a232e 10216 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 10217 return;
pcercuei 0:03b5121a232e 10218 if (!IS_BYTE_CHAR(RAW)) {
pcercuei 0:03b5121a232e 10219 xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
pcercuei 0:03b5121a232e 10220 "Premature end of data in tag %s line %d\n",
pcercuei 0:03b5121a232e 10221 name, line, NULL);
pcercuei 0:03b5121a232e 10222
pcercuei 0:03b5121a232e 10223 /*
pcercuei 0:03b5121a232e 10224 * end of parsing of this node.
pcercuei 0:03b5121a232e 10225 */
pcercuei 0:03b5121a232e 10226 nodePop(ctxt);
pcercuei 0:03b5121a232e 10227 namePop(ctxt);
pcercuei 0:03b5121a232e 10228 spacePop(ctxt);
pcercuei 0:03b5121a232e 10229 if (nsNr != ctxt->nsNr)
pcercuei 0:03b5121a232e 10230 nsPop(ctxt, ctxt->nsNr - nsNr);
pcercuei 0:03b5121a232e 10231 return;
pcercuei 0:03b5121a232e 10232 }
pcercuei 0:03b5121a232e 10233
pcercuei 0:03b5121a232e 10234 /*
pcercuei 0:03b5121a232e 10235 * parse the end of tag: '</' should be here.
pcercuei 0:03b5121a232e 10236 */
pcercuei 0:03b5121a232e 10237 if (ctxt->sax2) {
pcercuei 0:03b5121a232e 10238 xmlParseEndTag2(ctxt, prefix, URI, line, ctxt->nsNr - nsNr, tlen);
pcercuei 0:03b5121a232e 10239 namePop(ctxt);
pcercuei 0:03b5121a232e 10240 }
pcercuei 0:03b5121a232e 10241 #ifdef LIBXML_SAX1_ENABLED
pcercuei 0:03b5121a232e 10242 else
pcercuei 0:03b5121a232e 10243 xmlParseEndTag1(ctxt, line);
pcercuei 0:03b5121a232e 10244 #endif /* LIBXML_SAX1_ENABLED */
pcercuei 0:03b5121a232e 10245
pcercuei 0:03b5121a232e 10246 /*
pcercuei 0:03b5121a232e 10247 * Capture end position and add node
pcercuei 0:03b5121a232e 10248 */
pcercuei 0:03b5121a232e 10249 if ( ret != NULL && ctxt->record_info ) {
pcercuei 0:03b5121a232e 10250 node_info.end_pos = ctxt->input->consumed +
pcercuei 0:03b5121a232e 10251 (CUR_PTR - ctxt->input->base);
pcercuei 0:03b5121a232e 10252 node_info.end_line = ctxt->input->line;
pcercuei 0:03b5121a232e 10253 node_info.node = ret;
pcercuei 0:03b5121a232e 10254 xmlParserAddNodeInfo(ctxt, &node_info);
pcercuei 0:03b5121a232e 10255 }
pcercuei 0:03b5121a232e 10256 }
pcercuei 0:03b5121a232e 10257
pcercuei 0:03b5121a232e 10258 /**
pcercuei 0:03b5121a232e 10259 * xmlParseVersionNum:
pcercuei 0:03b5121a232e 10260 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 10261 *
pcercuei 0:03b5121a232e 10262 * parse the XML version value.
pcercuei 0:03b5121a232e 10263 *
pcercuei 0:03b5121a232e 10264 * [26] VersionNum ::= '1.' [0-9]+
pcercuei 0:03b5121a232e 10265 *
pcercuei 0:03b5121a232e 10266 * In practice allow [0-9].[0-9]+ at that level
pcercuei 0:03b5121a232e 10267 *
pcercuei 0:03b5121a232e 10268 * Returns the string giving the XML version number, or NULL
pcercuei 0:03b5121a232e 10269 */
pcercuei 0:03b5121a232e 10270 xmlChar *
pcercuei 0:03b5121a232e 10271 xmlParseVersionNum(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 10272 xmlChar *buf = NULL;
pcercuei 0:03b5121a232e 10273 int len = 0;
pcercuei 0:03b5121a232e 10274 int size = 10;
pcercuei 0:03b5121a232e 10275 xmlChar cur;
pcercuei 0:03b5121a232e 10276
pcercuei 0:03b5121a232e 10277 buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
pcercuei 0:03b5121a232e 10278 if (buf == NULL) {
pcercuei 0:03b5121a232e 10279 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 10280 return(NULL);
pcercuei 0:03b5121a232e 10281 }
pcercuei 0:03b5121a232e 10282 cur = CUR;
pcercuei 0:03b5121a232e 10283 if (!((cur >= '0') && (cur <= '9'))) {
pcercuei 0:03b5121a232e 10284 xmlFree(buf);
pcercuei 0:03b5121a232e 10285 return(NULL);
pcercuei 0:03b5121a232e 10286 }
pcercuei 0:03b5121a232e 10287 buf[len++] = cur;
pcercuei 0:03b5121a232e 10288 NEXT;
pcercuei 0:03b5121a232e 10289 cur=CUR;
pcercuei 0:03b5121a232e 10290 if (cur != '.') {
pcercuei 0:03b5121a232e 10291 xmlFree(buf);
pcercuei 0:03b5121a232e 10292 return(NULL);
pcercuei 0:03b5121a232e 10293 }
pcercuei 0:03b5121a232e 10294 buf[len++] = cur;
pcercuei 0:03b5121a232e 10295 NEXT;
pcercuei 0:03b5121a232e 10296 cur=CUR;
pcercuei 0:03b5121a232e 10297 while ((cur >= '0') && (cur <= '9')) {
pcercuei 0:03b5121a232e 10298 if (len + 1 >= size) {
pcercuei 0:03b5121a232e 10299 xmlChar *tmp;
pcercuei 0:03b5121a232e 10300
pcercuei 0:03b5121a232e 10301 size *= 2;
pcercuei 0:03b5121a232e 10302 tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
pcercuei 0:03b5121a232e 10303 if (tmp == NULL) {
pcercuei 0:03b5121a232e 10304 xmlFree(buf);
pcercuei 0:03b5121a232e 10305 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 10306 return(NULL);
pcercuei 0:03b5121a232e 10307 }
pcercuei 0:03b5121a232e 10308 buf = tmp;
pcercuei 0:03b5121a232e 10309 }
pcercuei 0:03b5121a232e 10310 buf[len++] = cur;
pcercuei 0:03b5121a232e 10311 NEXT;
pcercuei 0:03b5121a232e 10312 cur=CUR;
pcercuei 0:03b5121a232e 10313 }
pcercuei 0:03b5121a232e 10314 buf[len] = 0;
pcercuei 0:03b5121a232e 10315 return(buf);
pcercuei 0:03b5121a232e 10316 }
pcercuei 0:03b5121a232e 10317
pcercuei 0:03b5121a232e 10318 /**
pcercuei 0:03b5121a232e 10319 * xmlParseVersionInfo:
pcercuei 0:03b5121a232e 10320 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 10321 *
pcercuei 0:03b5121a232e 10322 * parse the XML version.
pcercuei 0:03b5121a232e 10323 *
pcercuei 0:03b5121a232e 10324 * [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
pcercuei 0:03b5121a232e 10325 *
pcercuei 0:03b5121a232e 10326 * [25] Eq ::= S? '=' S?
pcercuei 0:03b5121a232e 10327 *
pcercuei 0:03b5121a232e 10328 * Returns the version string, e.g. "1.0"
pcercuei 0:03b5121a232e 10329 */
pcercuei 0:03b5121a232e 10330
pcercuei 0:03b5121a232e 10331 xmlChar *
pcercuei 0:03b5121a232e 10332 xmlParseVersionInfo(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 10333 xmlChar *version = NULL;
pcercuei 0:03b5121a232e 10334
pcercuei 0:03b5121a232e 10335 if (CMP7(CUR_PTR, 'v', 'e', 'r', 's', 'i', 'o', 'n')) {
pcercuei 0:03b5121a232e 10336 SKIP(7);
pcercuei 0:03b5121a232e 10337 SKIP_BLANKS;
pcercuei 0:03b5121a232e 10338 if (RAW != '=') {
pcercuei 0:03b5121a232e 10339 xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
pcercuei 0:03b5121a232e 10340 return(NULL);
pcercuei 0:03b5121a232e 10341 }
pcercuei 0:03b5121a232e 10342 NEXT;
pcercuei 0:03b5121a232e 10343 SKIP_BLANKS;
pcercuei 0:03b5121a232e 10344 if (RAW == '"') {
pcercuei 0:03b5121a232e 10345 NEXT;
pcercuei 0:03b5121a232e 10346 version = xmlParseVersionNum(ctxt);
pcercuei 0:03b5121a232e 10347 if (RAW != '"') {
pcercuei 0:03b5121a232e 10348 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
pcercuei 0:03b5121a232e 10349 } else
pcercuei 0:03b5121a232e 10350 NEXT;
pcercuei 0:03b5121a232e 10351 } else if (RAW == '\''){
pcercuei 0:03b5121a232e 10352 NEXT;
pcercuei 0:03b5121a232e 10353 version = xmlParseVersionNum(ctxt);
pcercuei 0:03b5121a232e 10354 if (RAW != '\'') {
pcercuei 0:03b5121a232e 10355 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
pcercuei 0:03b5121a232e 10356 } else
pcercuei 0:03b5121a232e 10357 NEXT;
pcercuei 0:03b5121a232e 10358 } else {
pcercuei 0:03b5121a232e 10359 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
pcercuei 0:03b5121a232e 10360 }
pcercuei 0:03b5121a232e 10361 }
pcercuei 0:03b5121a232e 10362 return(version);
pcercuei 0:03b5121a232e 10363 }
pcercuei 0:03b5121a232e 10364
pcercuei 0:03b5121a232e 10365 /**
pcercuei 0:03b5121a232e 10366 * xmlParseEncName:
pcercuei 0:03b5121a232e 10367 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 10368 *
pcercuei 0:03b5121a232e 10369 * parse the XML encoding name
pcercuei 0:03b5121a232e 10370 *
pcercuei 0:03b5121a232e 10371 * [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
pcercuei 0:03b5121a232e 10372 *
pcercuei 0:03b5121a232e 10373 * Returns the encoding name value or NULL
pcercuei 0:03b5121a232e 10374 */
pcercuei 0:03b5121a232e 10375 xmlChar *
pcercuei 0:03b5121a232e 10376 xmlParseEncName(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 10377 xmlChar *buf = NULL;
pcercuei 0:03b5121a232e 10378 int len = 0;
pcercuei 0:03b5121a232e 10379 int size = 10;
pcercuei 0:03b5121a232e 10380 xmlChar cur;
pcercuei 0:03b5121a232e 10381
pcercuei 0:03b5121a232e 10382 cur = CUR;
pcercuei 0:03b5121a232e 10383 if (((cur >= 'a') && (cur <= 'z')) ||
pcercuei 0:03b5121a232e 10384 ((cur >= 'A') && (cur <= 'Z'))) {
pcercuei 0:03b5121a232e 10385 buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
pcercuei 0:03b5121a232e 10386 if (buf == NULL) {
pcercuei 0:03b5121a232e 10387 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 10388 return(NULL);
pcercuei 0:03b5121a232e 10389 }
pcercuei 0:03b5121a232e 10390
pcercuei 0:03b5121a232e 10391 buf[len++] = cur;
pcercuei 0:03b5121a232e 10392 NEXT;
pcercuei 0:03b5121a232e 10393 cur = CUR;
pcercuei 0:03b5121a232e 10394 while (((cur >= 'a') && (cur <= 'z')) ||
pcercuei 0:03b5121a232e 10395 ((cur >= 'A') && (cur <= 'Z')) ||
pcercuei 0:03b5121a232e 10396 ((cur >= '0') && (cur <= '9')) ||
pcercuei 0:03b5121a232e 10397 (cur == '.') || (cur == '_') ||
pcercuei 0:03b5121a232e 10398 (cur == '-')) {
pcercuei 0:03b5121a232e 10399 if (len + 1 >= size) {
pcercuei 0:03b5121a232e 10400 xmlChar *tmp;
pcercuei 0:03b5121a232e 10401
pcercuei 0:03b5121a232e 10402 size *= 2;
pcercuei 0:03b5121a232e 10403 tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
pcercuei 0:03b5121a232e 10404 if (tmp == NULL) {
pcercuei 0:03b5121a232e 10405 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 10406 xmlFree(buf);
pcercuei 0:03b5121a232e 10407 return(NULL);
pcercuei 0:03b5121a232e 10408 }
pcercuei 0:03b5121a232e 10409 buf = tmp;
pcercuei 0:03b5121a232e 10410 }
pcercuei 0:03b5121a232e 10411 buf[len++] = cur;
pcercuei 0:03b5121a232e 10412 NEXT;
pcercuei 0:03b5121a232e 10413 cur = CUR;
pcercuei 0:03b5121a232e 10414 if (cur == 0) {
pcercuei 0:03b5121a232e 10415 SHRINK;
pcercuei 0:03b5121a232e 10416 GROW;
pcercuei 0:03b5121a232e 10417 cur = CUR;
pcercuei 0:03b5121a232e 10418 }
pcercuei 0:03b5121a232e 10419 }
pcercuei 0:03b5121a232e 10420 buf[len] = 0;
pcercuei 0:03b5121a232e 10421 } else {
pcercuei 0:03b5121a232e 10422 xmlFatalErr(ctxt, XML_ERR_ENCODING_NAME, NULL);
pcercuei 0:03b5121a232e 10423 }
pcercuei 0:03b5121a232e 10424 return(buf);
pcercuei 0:03b5121a232e 10425 }
pcercuei 0:03b5121a232e 10426
pcercuei 0:03b5121a232e 10427 /**
pcercuei 0:03b5121a232e 10428 * xmlParseEncodingDecl:
pcercuei 0:03b5121a232e 10429 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 10430 *
pcercuei 0:03b5121a232e 10431 * parse the XML encoding declaration
pcercuei 0:03b5121a232e 10432 *
pcercuei 0:03b5121a232e 10433 * [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' | "'" EncName "'")
pcercuei 0:03b5121a232e 10434 *
pcercuei 0:03b5121a232e 10435 * this setups the conversion filters.
pcercuei 0:03b5121a232e 10436 *
pcercuei 0:03b5121a232e 10437 * Returns the encoding value or NULL
pcercuei 0:03b5121a232e 10438 */
pcercuei 0:03b5121a232e 10439
pcercuei 0:03b5121a232e 10440 const xmlChar *
pcercuei 0:03b5121a232e 10441 xmlParseEncodingDecl(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 10442 xmlChar *encoding = NULL;
pcercuei 0:03b5121a232e 10443
pcercuei 0:03b5121a232e 10444 SKIP_BLANKS;
pcercuei 0:03b5121a232e 10445 if (CMP8(CUR_PTR, 'e', 'n', 'c', 'o', 'd', 'i', 'n', 'g')) {
pcercuei 0:03b5121a232e 10446 SKIP(8);
pcercuei 0:03b5121a232e 10447 SKIP_BLANKS;
pcercuei 0:03b5121a232e 10448 if (RAW != '=') {
pcercuei 0:03b5121a232e 10449 xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
pcercuei 0:03b5121a232e 10450 return(NULL);
pcercuei 0:03b5121a232e 10451 }
pcercuei 0:03b5121a232e 10452 NEXT;
pcercuei 0:03b5121a232e 10453 SKIP_BLANKS;
pcercuei 0:03b5121a232e 10454 if (RAW == '"') {
pcercuei 0:03b5121a232e 10455 NEXT;
pcercuei 0:03b5121a232e 10456 encoding = xmlParseEncName(ctxt);
pcercuei 0:03b5121a232e 10457 if (RAW != '"') {
pcercuei 0:03b5121a232e 10458 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
pcercuei 0:03b5121a232e 10459 xmlFree((xmlChar *) encoding);
pcercuei 0:03b5121a232e 10460 return(NULL);
pcercuei 0:03b5121a232e 10461 } else
pcercuei 0:03b5121a232e 10462 NEXT;
pcercuei 0:03b5121a232e 10463 } else if (RAW == '\''){
pcercuei 0:03b5121a232e 10464 NEXT;
pcercuei 0:03b5121a232e 10465 encoding = xmlParseEncName(ctxt);
pcercuei 0:03b5121a232e 10466 if (RAW != '\'') {
pcercuei 0:03b5121a232e 10467 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
pcercuei 0:03b5121a232e 10468 xmlFree((xmlChar *) encoding);
pcercuei 0:03b5121a232e 10469 return(NULL);
pcercuei 0:03b5121a232e 10470 } else
pcercuei 0:03b5121a232e 10471 NEXT;
pcercuei 0:03b5121a232e 10472 } else {
pcercuei 0:03b5121a232e 10473 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
pcercuei 0:03b5121a232e 10474 }
pcercuei 0:03b5121a232e 10475
pcercuei 0:03b5121a232e 10476 /*
pcercuei 0:03b5121a232e 10477 * Non standard parsing, allowing the user to ignore encoding
pcercuei 0:03b5121a232e 10478 */
pcercuei 0:03b5121a232e 10479 if (ctxt->options & XML_PARSE_IGNORE_ENC) {
pcercuei 0:03b5121a232e 10480 xmlFree((xmlChar *) encoding);
pcercuei 0:03b5121a232e 10481 return(NULL);
pcercuei 0:03b5121a232e 10482 }
pcercuei 0:03b5121a232e 10483
pcercuei 0:03b5121a232e 10484 /*
pcercuei 0:03b5121a232e 10485 * UTF-16 encoding stwich has already taken place at this stage,
pcercuei 0:03b5121a232e 10486 * more over the little-endian/big-endian selection is already done
pcercuei 0:03b5121a232e 10487 */
pcercuei 0:03b5121a232e 10488 if ((encoding != NULL) &&
pcercuei 0:03b5121a232e 10489 ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-16")) ||
pcercuei 0:03b5121a232e 10490 (!xmlStrcasecmp(encoding, BAD_CAST "UTF16")))) {
pcercuei 0:03b5121a232e 10491 /*
pcercuei 0:03b5121a232e 10492 * If no encoding was passed to the parser, that we are
pcercuei 0:03b5121a232e 10493 * using UTF-16 and no decoder is present i.e. the
pcercuei 0:03b5121a232e 10494 * document is apparently UTF-8 compatible, then raise an
pcercuei 0:03b5121a232e 10495 * encoding mismatch fatal error
pcercuei 0:03b5121a232e 10496 */
pcercuei 0:03b5121a232e 10497 if ((ctxt->encoding == NULL) &&
pcercuei 0:03b5121a232e 10498 (ctxt->input->buf != NULL) &&
pcercuei 0:03b5121a232e 10499 (ctxt->input->buf->encoder == NULL)) {
pcercuei 0:03b5121a232e 10500 xmlFatalErrMsg(ctxt, XML_ERR_INVALID_ENCODING,
pcercuei 0:03b5121a232e 10501 "Document labelled UTF-16 but has UTF-8 content\n");
pcercuei 0:03b5121a232e 10502 }
pcercuei 0:03b5121a232e 10503 if (ctxt->encoding != NULL)
pcercuei 0:03b5121a232e 10504 xmlFree((xmlChar *) ctxt->encoding);
pcercuei 0:03b5121a232e 10505 ctxt->encoding = encoding;
pcercuei 0:03b5121a232e 10506 }
pcercuei 0:03b5121a232e 10507 /*
pcercuei 0:03b5121a232e 10508 * UTF-8 encoding is handled natively
pcercuei 0:03b5121a232e 10509 */
pcercuei 0:03b5121a232e 10510 else if ((encoding != NULL) &&
pcercuei 0:03b5121a232e 10511 ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-8")) ||
pcercuei 0:03b5121a232e 10512 (!xmlStrcasecmp(encoding, BAD_CAST "UTF8")))) {
pcercuei 0:03b5121a232e 10513 if (ctxt->encoding != NULL)
pcercuei 0:03b5121a232e 10514 xmlFree((xmlChar *) ctxt->encoding);
pcercuei 0:03b5121a232e 10515 ctxt->encoding = encoding;
pcercuei 0:03b5121a232e 10516 }
pcercuei 0:03b5121a232e 10517 else if (encoding != NULL) {
pcercuei 0:03b5121a232e 10518 xmlCharEncodingHandlerPtr handler;
pcercuei 0:03b5121a232e 10519
pcercuei 0:03b5121a232e 10520 if (ctxt->input->encoding != NULL)
pcercuei 0:03b5121a232e 10521 xmlFree((xmlChar *) ctxt->input->encoding);
pcercuei 0:03b5121a232e 10522 ctxt->input->encoding = encoding;
pcercuei 0:03b5121a232e 10523
pcercuei 0:03b5121a232e 10524 handler = xmlFindCharEncodingHandler((const char *) encoding);
pcercuei 0:03b5121a232e 10525 if (handler != NULL) {
pcercuei 0:03b5121a232e 10526 if (xmlSwitchToEncoding(ctxt, handler) < 0) {
pcercuei 0:03b5121a232e 10527 /* failed to convert */
pcercuei 0:03b5121a232e 10528 ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
pcercuei 0:03b5121a232e 10529 return(NULL);
pcercuei 0:03b5121a232e 10530 }
pcercuei 0:03b5121a232e 10531 } else {
pcercuei 0:03b5121a232e 10532 xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
pcercuei 0:03b5121a232e 10533 "Unsupported encoding %s\n", encoding);
pcercuei 0:03b5121a232e 10534 return(NULL);
pcercuei 0:03b5121a232e 10535 }
pcercuei 0:03b5121a232e 10536 }
pcercuei 0:03b5121a232e 10537 }
pcercuei 0:03b5121a232e 10538 return(encoding);
pcercuei 0:03b5121a232e 10539 }
pcercuei 0:03b5121a232e 10540
pcercuei 0:03b5121a232e 10541 /**
pcercuei 0:03b5121a232e 10542 * xmlParseSDDecl:
pcercuei 0:03b5121a232e 10543 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 10544 *
pcercuei 0:03b5121a232e 10545 * parse the XML standalone declaration
pcercuei 0:03b5121a232e 10546 *
pcercuei 0:03b5121a232e 10547 * [32] SDDecl ::= S 'standalone' Eq
pcercuei 0:03b5121a232e 10548 * (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no')'"'))
pcercuei 0:03b5121a232e 10549 *
pcercuei 0:03b5121a232e 10550 * [ VC: Standalone Document Declaration ]
pcercuei 0:03b5121a232e 10551 * TODO The standalone document declaration must have the value "no"
pcercuei 0:03b5121a232e 10552 * if any external markup declarations contain declarations of:
pcercuei 0:03b5121a232e 10553 * - attributes with default values, if elements to which these
pcercuei 0:03b5121a232e 10554 * attributes apply appear in the document without specifications
pcercuei 0:03b5121a232e 10555 * of values for these attributes, or
pcercuei 0:03b5121a232e 10556 * - entities (other than amp, lt, gt, apos, quot), if references
pcercuei 0:03b5121a232e 10557 * to those entities appear in the document, or
pcercuei 0:03b5121a232e 10558 * - attributes with values subject to normalization, where the
pcercuei 0:03b5121a232e 10559 * attribute appears in the document with a value which will change
pcercuei 0:03b5121a232e 10560 * as a result of normalization, or
pcercuei 0:03b5121a232e 10561 * - element types with element content, if white space occurs directly
pcercuei 0:03b5121a232e 10562 * within any instance of those types.
pcercuei 0:03b5121a232e 10563 *
pcercuei 0:03b5121a232e 10564 * Returns:
pcercuei 0:03b5121a232e 10565 * 1 if standalone="yes"
pcercuei 0:03b5121a232e 10566 * 0 if standalone="no"
pcercuei 0:03b5121a232e 10567 * -2 if standalone attribute is missing or invalid
pcercuei 0:03b5121a232e 10568 * (A standalone value of -2 means that the XML declaration was found,
pcercuei 0:03b5121a232e 10569 * but no value was specified for the standalone attribute).
pcercuei 0:03b5121a232e 10570 */
pcercuei 0:03b5121a232e 10571
pcercuei 0:03b5121a232e 10572 int
pcercuei 0:03b5121a232e 10573 xmlParseSDDecl(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 10574 int standalone = -2;
pcercuei 0:03b5121a232e 10575
pcercuei 0:03b5121a232e 10576 SKIP_BLANKS;
pcercuei 0:03b5121a232e 10577 if (CMP10(CUR_PTR, 's', 't', 'a', 'n', 'd', 'a', 'l', 'o', 'n', 'e')) {
pcercuei 0:03b5121a232e 10578 SKIP(10);
pcercuei 0:03b5121a232e 10579 SKIP_BLANKS;
pcercuei 0:03b5121a232e 10580 if (RAW != '=') {
pcercuei 0:03b5121a232e 10581 xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
pcercuei 0:03b5121a232e 10582 return(standalone);
pcercuei 0:03b5121a232e 10583 }
pcercuei 0:03b5121a232e 10584 NEXT;
pcercuei 0:03b5121a232e 10585 SKIP_BLANKS;
pcercuei 0:03b5121a232e 10586 if (RAW == '\''){
pcercuei 0:03b5121a232e 10587 NEXT;
pcercuei 0:03b5121a232e 10588 if ((RAW == 'n') && (NXT(1) == 'o')) {
pcercuei 0:03b5121a232e 10589 standalone = 0;
pcercuei 0:03b5121a232e 10590 SKIP(2);
pcercuei 0:03b5121a232e 10591 } else if ((RAW == 'y') && (NXT(1) == 'e') &&
pcercuei 0:03b5121a232e 10592 (NXT(2) == 's')) {
pcercuei 0:03b5121a232e 10593 standalone = 1;
pcercuei 0:03b5121a232e 10594 SKIP(3);
pcercuei 0:03b5121a232e 10595 } else {
pcercuei 0:03b5121a232e 10596 xmlFatalErr(ctxt, XML_ERR_STANDALONE_VALUE, NULL);
pcercuei 0:03b5121a232e 10597 }
pcercuei 0:03b5121a232e 10598 if (RAW != '\'') {
pcercuei 0:03b5121a232e 10599 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
pcercuei 0:03b5121a232e 10600 } else
pcercuei 0:03b5121a232e 10601 NEXT;
pcercuei 0:03b5121a232e 10602 } else if (RAW == '"'){
pcercuei 0:03b5121a232e 10603 NEXT;
pcercuei 0:03b5121a232e 10604 if ((RAW == 'n') && (NXT(1) == 'o')) {
pcercuei 0:03b5121a232e 10605 standalone = 0;
pcercuei 0:03b5121a232e 10606 SKIP(2);
pcercuei 0:03b5121a232e 10607 } else if ((RAW == 'y') && (NXT(1) == 'e') &&
pcercuei 0:03b5121a232e 10608 (NXT(2) == 's')) {
pcercuei 0:03b5121a232e 10609 standalone = 1;
pcercuei 0:03b5121a232e 10610 SKIP(3);
pcercuei 0:03b5121a232e 10611 } else {
pcercuei 0:03b5121a232e 10612 xmlFatalErr(ctxt, XML_ERR_STANDALONE_VALUE, NULL);
pcercuei 0:03b5121a232e 10613 }
pcercuei 0:03b5121a232e 10614 if (RAW != '"') {
pcercuei 0:03b5121a232e 10615 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
pcercuei 0:03b5121a232e 10616 } else
pcercuei 0:03b5121a232e 10617 NEXT;
pcercuei 0:03b5121a232e 10618 } else {
pcercuei 0:03b5121a232e 10619 xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
pcercuei 0:03b5121a232e 10620 }
pcercuei 0:03b5121a232e 10621 }
pcercuei 0:03b5121a232e 10622 return(standalone);
pcercuei 0:03b5121a232e 10623 }
pcercuei 0:03b5121a232e 10624
pcercuei 0:03b5121a232e 10625 /**
pcercuei 0:03b5121a232e 10626 * xmlParseXMLDecl:
pcercuei 0:03b5121a232e 10627 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 10628 *
pcercuei 0:03b5121a232e 10629 * parse an XML declaration header
pcercuei 0:03b5121a232e 10630 *
pcercuei 0:03b5121a232e 10631 * [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
pcercuei 0:03b5121a232e 10632 */
pcercuei 0:03b5121a232e 10633
pcercuei 0:03b5121a232e 10634 void
pcercuei 0:03b5121a232e 10635 xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 10636 xmlChar *version;
pcercuei 0:03b5121a232e 10637
pcercuei 0:03b5121a232e 10638 /*
pcercuei 0:03b5121a232e 10639 * This value for standalone indicates that the document has an
pcercuei 0:03b5121a232e 10640 * XML declaration but it does not have a standalone attribute.
pcercuei 0:03b5121a232e 10641 * It will be overwritten later if a standalone attribute is found.
pcercuei 0:03b5121a232e 10642 */
pcercuei 0:03b5121a232e 10643 ctxt->input->standalone = -2;
pcercuei 0:03b5121a232e 10644
pcercuei 0:03b5121a232e 10645 /*
pcercuei 0:03b5121a232e 10646 * We know that '<?xml' is here.
pcercuei 0:03b5121a232e 10647 */
pcercuei 0:03b5121a232e 10648 SKIP(5);
pcercuei 0:03b5121a232e 10649
pcercuei 0:03b5121a232e 10650 if (!IS_BLANK_CH(RAW)) {
pcercuei 0:03b5121a232e 10651 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
pcercuei 0:03b5121a232e 10652 "Blank needed after '<?xml'\n");
pcercuei 0:03b5121a232e 10653 }
pcercuei 0:03b5121a232e 10654 SKIP_BLANKS;
pcercuei 0:03b5121a232e 10655
pcercuei 0:03b5121a232e 10656 /*
pcercuei 0:03b5121a232e 10657 * We must have the VersionInfo here.
pcercuei 0:03b5121a232e 10658 */
pcercuei 0:03b5121a232e 10659 version = xmlParseVersionInfo(ctxt);
pcercuei 0:03b5121a232e 10660 if (version == NULL) {
pcercuei 0:03b5121a232e 10661 xmlFatalErr(ctxt, XML_ERR_VERSION_MISSING, NULL);
pcercuei 0:03b5121a232e 10662 } else {
pcercuei 0:03b5121a232e 10663 if (!xmlStrEqual(version, (const xmlChar *) XML_DEFAULT_VERSION)) {
pcercuei 0:03b5121a232e 10664 /*
pcercuei 0:03b5121a232e 10665 * Changed here for XML-1.0 5th edition
pcercuei 0:03b5121a232e 10666 */
pcercuei 0:03b5121a232e 10667 if (ctxt->options & XML_PARSE_OLD10) {
pcercuei 0:03b5121a232e 10668 xmlFatalErrMsgStr(ctxt, XML_ERR_UNKNOWN_VERSION,
pcercuei 0:03b5121a232e 10669 "Unsupported version '%s'\n",
pcercuei 0:03b5121a232e 10670 version);
pcercuei 0:03b5121a232e 10671 } else {
pcercuei 0:03b5121a232e 10672 if ((version[0] == '1') && ((version[1] == '.'))) {
pcercuei 0:03b5121a232e 10673 xmlWarningMsg(ctxt, XML_WAR_UNKNOWN_VERSION,
pcercuei 0:03b5121a232e 10674 "Unsupported version '%s'\n",
pcercuei 0:03b5121a232e 10675 version, NULL);
pcercuei 0:03b5121a232e 10676 } else {
pcercuei 0:03b5121a232e 10677 xmlFatalErrMsgStr(ctxt, XML_ERR_UNKNOWN_VERSION,
pcercuei 0:03b5121a232e 10678 "Unsupported version '%s'\n",
pcercuei 0:03b5121a232e 10679 version);
pcercuei 0:03b5121a232e 10680 }
pcercuei 0:03b5121a232e 10681 }
pcercuei 0:03b5121a232e 10682 }
pcercuei 0:03b5121a232e 10683 if (ctxt->version != NULL)
pcercuei 0:03b5121a232e 10684 xmlFree((void *) ctxt->version);
pcercuei 0:03b5121a232e 10685 ctxt->version = version;
pcercuei 0:03b5121a232e 10686 }
pcercuei 0:03b5121a232e 10687
pcercuei 0:03b5121a232e 10688 /*
pcercuei 0:03b5121a232e 10689 * We may have the encoding declaration
pcercuei 0:03b5121a232e 10690 */
pcercuei 0:03b5121a232e 10691 if (!IS_BLANK_CH(RAW)) {
pcercuei 0:03b5121a232e 10692 if ((RAW == '?') && (NXT(1) == '>')) {
pcercuei 0:03b5121a232e 10693 SKIP(2);
pcercuei 0:03b5121a232e 10694 return;
pcercuei 0:03b5121a232e 10695 }
pcercuei 0:03b5121a232e 10696 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n");
pcercuei 0:03b5121a232e 10697 }
pcercuei 0:03b5121a232e 10698 xmlParseEncodingDecl(ctxt);
pcercuei 0:03b5121a232e 10699 if ((ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) ||
pcercuei 0:03b5121a232e 10700 (ctxt->instate == XML_PARSER_EOF)) {
pcercuei 0:03b5121a232e 10701 /*
pcercuei 0:03b5121a232e 10702 * The XML REC instructs us to stop parsing right here
pcercuei 0:03b5121a232e 10703 */
pcercuei 0:03b5121a232e 10704 return;
pcercuei 0:03b5121a232e 10705 }
pcercuei 0:03b5121a232e 10706
pcercuei 0:03b5121a232e 10707 /*
pcercuei 0:03b5121a232e 10708 * We may have the standalone status.
pcercuei 0:03b5121a232e 10709 */
pcercuei 0:03b5121a232e 10710 if ((ctxt->input->encoding != NULL) && (!IS_BLANK_CH(RAW))) {
pcercuei 0:03b5121a232e 10711 if ((RAW == '?') && (NXT(1) == '>')) {
pcercuei 0:03b5121a232e 10712 SKIP(2);
pcercuei 0:03b5121a232e 10713 return;
pcercuei 0:03b5121a232e 10714 }
pcercuei 0:03b5121a232e 10715 xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n");
pcercuei 0:03b5121a232e 10716 }
pcercuei 0:03b5121a232e 10717
pcercuei 0:03b5121a232e 10718 /*
pcercuei 0:03b5121a232e 10719 * We can grow the input buffer freely at that point
pcercuei 0:03b5121a232e 10720 */
pcercuei 0:03b5121a232e 10721 GROW;
pcercuei 0:03b5121a232e 10722
pcercuei 0:03b5121a232e 10723 SKIP_BLANKS;
pcercuei 0:03b5121a232e 10724 ctxt->input->standalone = xmlParseSDDecl(ctxt);
pcercuei 0:03b5121a232e 10725
pcercuei 0:03b5121a232e 10726 SKIP_BLANKS;
pcercuei 0:03b5121a232e 10727 if ((RAW == '?') && (NXT(1) == '>')) {
pcercuei 0:03b5121a232e 10728 SKIP(2);
pcercuei 0:03b5121a232e 10729 } else if (RAW == '>') {
pcercuei 0:03b5121a232e 10730 /* Deprecated old WD ... */
pcercuei 0:03b5121a232e 10731 xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
pcercuei 0:03b5121a232e 10732 NEXT;
pcercuei 0:03b5121a232e 10733 } else {
pcercuei 0:03b5121a232e 10734 xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
pcercuei 0:03b5121a232e 10735 MOVETO_ENDTAG(CUR_PTR);
pcercuei 0:03b5121a232e 10736 NEXT;
pcercuei 0:03b5121a232e 10737 }
pcercuei 0:03b5121a232e 10738 }
pcercuei 0:03b5121a232e 10739
pcercuei 0:03b5121a232e 10740 /**
pcercuei 0:03b5121a232e 10741 * xmlParseMisc:
pcercuei 0:03b5121a232e 10742 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 10743 *
pcercuei 0:03b5121a232e 10744 * parse an XML Misc* optional field.
pcercuei 0:03b5121a232e 10745 *
pcercuei 0:03b5121a232e 10746 * [27] Misc ::= Comment | PI | S
pcercuei 0:03b5121a232e 10747 */
pcercuei 0:03b5121a232e 10748
pcercuei 0:03b5121a232e 10749 void
pcercuei 0:03b5121a232e 10750 xmlParseMisc(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 10751 while ((ctxt->instate != XML_PARSER_EOF) &&
pcercuei 0:03b5121a232e 10752 (((RAW == '<') && (NXT(1) == '?')) ||
pcercuei 0:03b5121a232e 10753 (CMP4(CUR_PTR, '<', '!', '-', '-')) ||
pcercuei 0:03b5121a232e 10754 IS_BLANK_CH(CUR))) {
pcercuei 0:03b5121a232e 10755 if ((RAW == '<') && (NXT(1) == '?')) {
pcercuei 0:03b5121a232e 10756 xmlParsePI(ctxt);
pcercuei 0:03b5121a232e 10757 } else if (IS_BLANK_CH(CUR)) {
pcercuei 0:03b5121a232e 10758 NEXT;
pcercuei 0:03b5121a232e 10759 } else
pcercuei 0:03b5121a232e 10760 xmlParseComment(ctxt);
pcercuei 0:03b5121a232e 10761 }
pcercuei 0:03b5121a232e 10762 }
pcercuei 0:03b5121a232e 10763
pcercuei 0:03b5121a232e 10764 /**
pcercuei 0:03b5121a232e 10765 * xmlParseDocument:
pcercuei 0:03b5121a232e 10766 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 10767 *
pcercuei 0:03b5121a232e 10768 * parse an XML document (and build a tree if using the standard SAX
pcercuei 0:03b5121a232e 10769 * interface).
pcercuei 0:03b5121a232e 10770 *
pcercuei 0:03b5121a232e 10771 * [1] document ::= prolog element Misc*
pcercuei 0:03b5121a232e 10772 *
pcercuei 0:03b5121a232e 10773 * [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?
pcercuei 0:03b5121a232e 10774 *
pcercuei 0:03b5121a232e 10775 * Returns 0, -1 in case of error. the parser context is augmented
pcercuei 0:03b5121a232e 10776 * as a result of the parsing.
pcercuei 0:03b5121a232e 10777 */
pcercuei 0:03b5121a232e 10778
pcercuei 0:03b5121a232e 10779 int
pcercuei 0:03b5121a232e 10780 xmlParseDocument(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 10781 xmlChar start[4];
pcercuei 0:03b5121a232e 10782 xmlCharEncoding enc;
pcercuei 0:03b5121a232e 10783
pcercuei 0:03b5121a232e 10784 xmlInitParser();
pcercuei 0:03b5121a232e 10785
pcercuei 0:03b5121a232e 10786 if ((ctxt == NULL) || (ctxt->input == NULL))
pcercuei 0:03b5121a232e 10787 return(-1);
pcercuei 0:03b5121a232e 10788
pcercuei 0:03b5121a232e 10789 GROW;
pcercuei 0:03b5121a232e 10790
pcercuei 0:03b5121a232e 10791 /*
pcercuei 0:03b5121a232e 10792 * SAX: detecting the level.
pcercuei 0:03b5121a232e 10793 */
pcercuei 0:03b5121a232e 10794 xmlDetectSAX2(ctxt);
pcercuei 0:03b5121a232e 10795
pcercuei 0:03b5121a232e 10796 /*
pcercuei 0:03b5121a232e 10797 * SAX: beginning of the document processing.
pcercuei 0:03b5121a232e 10798 */
pcercuei 0:03b5121a232e 10799 if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
pcercuei 0:03b5121a232e 10800 ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
pcercuei 0:03b5121a232e 10801 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 10802 return(-1);
pcercuei 0:03b5121a232e 10803
pcercuei 0:03b5121a232e 10804 if ((ctxt->encoding == NULL) &&
pcercuei 0:03b5121a232e 10805 ((ctxt->input->end - ctxt->input->cur) >= 4)) {
pcercuei 0:03b5121a232e 10806 /*
pcercuei 0:03b5121a232e 10807 * Get the 4 first bytes and decode the charset
pcercuei 0:03b5121a232e 10808 * if enc != XML_CHAR_ENCODING_NONE
pcercuei 0:03b5121a232e 10809 * plug some encoding conversion routines.
pcercuei 0:03b5121a232e 10810 */
pcercuei 0:03b5121a232e 10811 start[0] = RAW;
pcercuei 0:03b5121a232e 10812 start[1] = NXT(1);
pcercuei 0:03b5121a232e 10813 start[2] = NXT(2);
pcercuei 0:03b5121a232e 10814 start[3] = NXT(3);
pcercuei 0:03b5121a232e 10815 enc = xmlDetectCharEncoding(&start[0], 4);
pcercuei 0:03b5121a232e 10816 if (enc != XML_CHAR_ENCODING_NONE) {
pcercuei 0:03b5121a232e 10817 xmlSwitchEncoding(ctxt, enc);
pcercuei 0:03b5121a232e 10818 }
pcercuei 0:03b5121a232e 10819 }
pcercuei 0:03b5121a232e 10820
pcercuei 0:03b5121a232e 10821
pcercuei 0:03b5121a232e 10822 if (CUR == 0) {
pcercuei 0:03b5121a232e 10823 xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
pcercuei 0:03b5121a232e 10824 return(-1);
pcercuei 0:03b5121a232e 10825 }
pcercuei 0:03b5121a232e 10826
pcercuei 0:03b5121a232e 10827 /*
pcercuei 0:03b5121a232e 10828 * Check for the XMLDecl in the Prolog.
pcercuei 0:03b5121a232e 10829 * do not GROW here to avoid the detected encoder to decode more
pcercuei 0:03b5121a232e 10830 * than just the first line, unless the amount of data is really
pcercuei 0:03b5121a232e 10831 * too small to hold "<?xml version="1.0" encoding="foo"
pcercuei 0:03b5121a232e 10832 */
pcercuei 0:03b5121a232e 10833 if ((ctxt->input->end - ctxt->input->cur) < 35) {
pcercuei 0:03b5121a232e 10834 GROW;
pcercuei 0:03b5121a232e 10835 }
pcercuei 0:03b5121a232e 10836 if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
pcercuei 0:03b5121a232e 10837
pcercuei 0:03b5121a232e 10838 /*
pcercuei 0:03b5121a232e 10839 * Note that we will switch encoding on the fly.
pcercuei 0:03b5121a232e 10840 */
pcercuei 0:03b5121a232e 10841 xmlParseXMLDecl(ctxt);
pcercuei 0:03b5121a232e 10842 if ((ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) ||
pcercuei 0:03b5121a232e 10843 (ctxt->instate == XML_PARSER_EOF)) {
pcercuei 0:03b5121a232e 10844 /*
pcercuei 0:03b5121a232e 10845 * The XML REC instructs us to stop parsing right here
pcercuei 0:03b5121a232e 10846 */
pcercuei 0:03b5121a232e 10847 return(-1);
pcercuei 0:03b5121a232e 10848 }
pcercuei 0:03b5121a232e 10849 ctxt->standalone = ctxt->input->standalone;
pcercuei 0:03b5121a232e 10850 SKIP_BLANKS;
pcercuei 0:03b5121a232e 10851 } else {
pcercuei 0:03b5121a232e 10852 ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
pcercuei 0:03b5121a232e 10853 }
pcercuei 0:03b5121a232e 10854 if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
pcercuei 0:03b5121a232e 10855 ctxt->sax->startDocument(ctxt->userData);
pcercuei 0:03b5121a232e 10856 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 10857 return(-1);
pcercuei 0:03b5121a232e 10858 if ((ctxt->myDoc != NULL) && (ctxt->input != NULL) &&
pcercuei 0:03b5121a232e 10859 (ctxt->input->buf != NULL) && (ctxt->input->buf->compressed >= 0)) {
pcercuei 0:03b5121a232e 10860 ctxt->myDoc->compression = ctxt->input->buf->compressed;
pcercuei 0:03b5121a232e 10861 }
pcercuei 0:03b5121a232e 10862
pcercuei 0:03b5121a232e 10863 /*
pcercuei 0:03b5121a232e 10864 * The Misc part of the Prolog
pcercuei 0:03b5121a232e 10865 */
pcercuei 0:03b5121a232e 10866 GROW;
pcercuei 0:03b5121a232e 10867 xmlParseMisc(ctxt);
pcercuei 0:03b5121a232e 10868
pcercuei 0:03b5121a232e 10869 /*
pcercuei 0:03b5121a232e 10870 * Then possibly doc type declaration(s) and more Misc
pcercuei 0:03b5121a232e 10871 * (doctypedecl Misc*)?
pcercuei 0:03b5121a232e 10872 */
pcercuei 0:03b5121a232e 10873 GROW;
pcercuei 0:03b5121a232e 10874 if (CMP9(CUR_PTR, '<', '!', 'D', 'O', 'C', 'T', 'Y', 'P', 'E')) {
pcercuei 0:03b5121a232e 10875
pcercuei 0:03b5121a232e 10876 ctxt->inSubset = 1;
pcercuei 0:03b5121a232e 10877 xmlParseDocTypeDecl(ctxt);
pcercuei 0:03b5121a232e 10878 if (RAW == '[') {
pcercuei 0:03b5121a232e 10879 ctxt->instate = XML_PARSER_DTD;
pcercuei 0:03b5121a232e 10880 xmlParseInternalSubset(ctxt);
pcercuei 0:03b5121a232e 10881 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 10882 return(-1);
pcercuei 0:03b5121a232e 10883 }
pcercuei 0:03b5121a232e 10884
pcercuei 0:03b5121a232e 10885 /*
pcercuei 0:03b5121a232e 10886 * Create and update the external subset.
pcercuei 0:03b5121a232e 10887 */
pcercuei 0:03b5121a232e 10888 ctxt->inSubset = 2;
pcercuei 0:03b5121a232e 10889 if ((ctxt->sax != NULL) && (ctxt->sax->externalSubset != NULL) &&
pcercuei 0:03b5121a232e 10890 (!ctxt->disableSAX))
pcercuei 0:03b5121a232e 10891 ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
pcercuei 0:03b5121a232e 10892 ctxt->extSubSystem, ctxt->extSubURI);
pcercuei 0:03b5121a232e 10893 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 10894 return(-1);
pcercuei 0:03b5121a232e 10895 ctxt->inSubset = 0;
pcercuei 0:03b5121a232e 10896
pcercuei 0:03b5121a232e 10897 xmlCleanSpecialAttr(ctxt);
pcercuei 0:03b5121a232e 10898
pcercuei 0:03b5121a232e 10899 ctxt->instate = XML_PARSER_PROLOG;
pcercuei 0:03b5121a232e 10900 xmlParseMisc(ctxt);
pcercuei 0:03b5121a232e 10901 }
pcercuei 0:03b5121a232e 10902
pcercuei 0:03b5121a232e 10903 /*
pcercuei 0:03b5121a232e 10904 * Time to start parsing the tree itself
pcercuei 0:03b5121a232e 10905 */
pcercuei 0:03b5121a232e 10906 GROW;
pcercuei 0:03b5121a232e 10907 if (RAW != '<') {
pcercuei 0:03b5121a232e 10908 xmlFatalErrMsg(ctxt, XML_ERR_DOCUMENT_EMPTY,
pcercuei 0:03b5121a232e 10909 "Start tag expected, '<' not found\n");
pcercuei 0:03b5121a232e 10910 } else {
pcercuei 0:03b5121a232e 10911 ctxt->instate = XML_PARSER_CONTENT;
pcercuei 0:03b5121a232e 10912 xmlParseElement(ctxt);
pcercuei 0:03b5121a232e 10913 ctxt->instate = XML_PARSER_EPILOG;
pcercuei 0:03b5121a232e 10914
pcercuei 0:03b5121a232e 10915
pcercuei 0:03b5121a232e 10916 /*
pcercuei 0:03b5121a232e 10917 * The Misc part at the end
pcercuei 0:03b5121a232e 10918 */
pcercuei 0:03b5121a232e 10919 xmlParseMisc(ctxt);
pcercuei 0:03b5121a232e 10920
pcercuei 0:03b5121a232e 10921 if (RAW != 0) {
pcercuei 0:03b5121a232e 10922 xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
pcercuei 0:03b5121a232e 10923 }
pcercuei 0:03b5121a232e 10924 ctxt->instate = XML_PARSER_EOF;
pcercuei 0:03b5121a232e 10925 }
pcercuei 0:03b5121a232e 10926
pcercuei 0:03b5121a232e 10927 /*
pcercuei 0:03b5121a232e 10928 * SAX: end of the document processing.
pcercuei 0:03b5121a232e 10929 */
pcercuei 0:03b5121a232e 10930 if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
pcercuei 0:03b5121a232e 10931 ctxt->sax->endDocument(ctxt->userData);
pcercuei 0:03b5121a232e 10932
pcercuei 0:03b5121a232e 10933 /*
pcercuei 0:03b5121a232e 10934 * Remove locally kept entity definitions if the tree was not built
pcercuei 0:03b5121a232e 10935 */
pcercuei 0:03b5121a232e 10936 if ((ctxt->myDoc != NULL) &&
pcercuei 0:03b5121a232e 10937 (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) {
pcercuei 0:03b5121a232e 10938 xmlFreeDoc(ctxt->myDoc);
pcercuei 0:03b5121a232e 10939 ctxt->myDoc = NULL;
pcercuei 0:03b5121a232e 10940 }
pcercuei 0:03b5121a232e 10941
pcercuei 0:03b5121a232e 10942 if ((ctxt->wellFormed) && (ctxt->myDoc != NULL)) {
pcercuei 0:03b5121a232e 10943 ctxt->myDoc->properties |= XML_DOC_WELLFORMED;
pcercuei 0:03b5121a232e 10944 if (ctxt->valid)
pcercuei 0:03b5121a232e 10945 ctxt->myDoc->properties |= XML_DOC_DTDVALID;
pcercuei 0:03b5121a232e 10946 if (ctxt->nsWellFormed)
pcercuei 0:03b5121a232e 10947 ctxt->myDoc->properties |= XML_DOC_NSVALID;
pcercuei 0:03b5121a232e 10948 if (ctxt->options & XML_PARSE_OLD10)
pcercuei 0:03b5121a232e 10949 ctxt->myDoc->properties |= XML_DOC_OLD10;
pcercuei 0:03b5121a232e 10950 }
pcercuei 0:03b5121a232e 10951 if (! ctxt->wellFormed) {
pcercuei 0:03b5121a232e 10952 ctxt->valid = 0;
pcercuei 0:03b5121a232e 10953 return(-1);
pcercuei 0:03b5121a232e 10954 }
pcercuei 0:03b5121a232e 10955 return(0);
pcercuei 0:03b5121a232e 10956 }
pcercuei 0:03b5121a232e 10957
pcercuei 0:03b5121a232e 10958 /**
pcercuei 0:03b5121a232e 10959 * xmlParseExtParsedEnt:
pcercuei 0:03b5121a232e 10960 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 10961 *
pcercuei 0:03b5121a232e 10962 * parse a general parsed entity
pcercuei 0:03b5121a232e 10963 * An external general parsed entity is well-formed if it matches the
pcercuei 0:03b5121a232e 10964 * production labeled extParsedEnt.
pcercuei 0:03b5121a232e 10965 *
pcercuei 0:03b5121a232e 10966 * [78] extParsedEnt ::= TextDecl? content
pcercuei 0:03b5121a232e 10967 *
pcercuei 0:03b5121a232e 10968 * Returns 0, -1 in case of error. the parser context is augmented
pcercuei 0:03b5121a232e 10969 * as a result of the parsing.
pcercuei 0:03b5121a232e 10970 */
pcercuei 0:03b5121a232e 10971
pcercuei 0:03b5121a232e 10972 int
pcercuei 0:03b5121a232e 10973 xmlParseExtParsedEnt(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 10974 xmlChar start[4];
pcercuei 0:03b5121a232e 10975 xmlCharEncoding enc;
pcercuei 0:03b5121a232e 10976
pcercuei 0:03b5121a232e 10977 if ((ctxt == NULL) || (ctxt->input == NULL))
pcercuei 0:03b5121a232e 10978 return(-1);
pcercuei 0:03b5121a232e 10979
pcercuei 0:03b5121a232e 10980 xmlDefaultSAXHandlerInit();
pcercuei 0:03b5121a232e 10981
pcercuei 0:03b5121a232e 10982 xmlDetectSAX2(ctxt);
pcercuei 0:03b5121a232e 10983
pcercuei 0:03b5121a232e 10984 GROW;
pcercuei 0:03b5121a232e 10985
pcercuei 0:03b5121a232e 10986 /*
pcercuei 0:03b5121a232e 10987 * SAX: beginning of the document processing.
pcercuei 0:03b5121a232e 10988 */
pcercuei 0:03b5121a232e 10989 if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
pcercuei 0:03b5121a232e 10990 ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
pcercuei 0:03b5121a232e 10991
pcercuei 0:03b5121a232e 10992 /*
pcercuei 0:03b5121a232e 10993 * Get the 4 first bytes and decode the charset
pcercuei 0:03b5121a232e 10994 * if enc != XML_CHAR_ENCODING_NONE
pcercuei 0:03b5121a232e 10995 * plug some encoding conversion routines.
pcercuei 0:03b5121a232e 10996 */
pcercuei 0:03b5121a232e 10997 if ((ctxt->input->end - ctxt->input->cur) >= 4) {
pcercuei 0:03b5121a232e 10998 start[0] = RAW;
pcercuei 0:03b5121a232e 10999 start[1] = NXT(1);
pcercuei 0:03b5121a232e 11000 start[2] = NXT(2);
pcercuei 0:03b5121a232e 11001 start[3] = NXT(3);
pcercuei 0:03b5121a232e 11002 enc = xmlDetectCharEncoding(start, 4);
pcercuei 0:03b5121a232e 11003 if (enc != XML_CHAR_ENCODING_NONE) {
pcercuei 0:03b5121a232e 11004 xmlSwitchEncoding(ctxt, enc);
pcercuei 0:03b5121a232e 11005 }
pcercuei 0:03b5121a232e 11006 }
pcercuei 0:03b5121a232e 11007
pcercuei 0:03b5121a232e 11008
pcercuei 0:03b5121a232e 11009 if (CUR == 0) {
pcercuei 0:03b5121a232e 11010 xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
pcercuei 0:03b5121a232e 11011 }
pcercuei 0:03b5121a232e 11012
pcercuei 0:03b5121a232e 11013 /*
pcercuei 0:03b5121a232e 11014 * Check for the XMLDecl in the Prolog.
pcercuei 0:03b5121a232e 11015 */
pcercuei 0:03b5121a232e 11016 GROW;
pcercuei 0:03b5121a232e 11017 if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
pcercuei 0:03b5121a232e 11018
pcercuei 0:03b5121a232e 11019 /*
pcercuei 0:03b5121a232e 11020 * Note that we will switch encoding on the fly.
pcercuei 0:03b5121a232e 11021 */
pcercuei 0:03b5121a232e 11022 xmlParseXMLDecl(ctxt);
pcercuei 0:03b5121a232e 11023 if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
pcercuei 0:03b5121a232e 11024 /*
pcercuei 0:03b5121a232e 11025 * The XML REC instructs us to stop parsing right here
pcercuei 0:03b5121a232e 11026 */
pcercuei 0:03b5121a232e 11027 return(-1);
pcercuei 0:03b5121a232e 11028 }
pcercuei 0:03b5121a232e 11029 SKIP_BLANKS;
pcercuei 0:03b5121a232e 11030 } else {
pcercuei 0:03b5121a232e 11031 ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
pcercuei 0:03b5121a232e 11032 }
pcercuei 0:03b5121a232e 11033 if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
pcercuei 0:03b5121a232e 11034 ctxt->sax->startDocument(ctxt->userData);
pcercuei 0:03b5121a232e 11035 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 11036 return(-1);
pcercuei 0:03b5121a232e 11037
pcercuei 0:03b5121a232e 11038 /*
pcercuei 0:03b5121a232e 11039 * Doing validity checking on chunk doesn't make sense
pcercuei 0:03b5121a232e 11040 */
pcercuei 0:03b5121a232e 11041 ctxt->instate = XML_PARSER_CONTENT;
pcercuei 0:03b5121a232e 11042 ctxt->validate = 0;
pcercuei 0:03b5121a232e 11043 ctxt->loadsubset = 0;
pcercuei 0:03b5121a232e 11044 ctxt->depth = 0;
pcercuei 0:03b5121a232e 11045
pcercuei 0:03b5121a232e 11046 xmlParseContent(ctxt);
pcercuei 0:03b5121a232e 11047 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 11048 return(-1);
pcercuei 0:03b5121a232e 11049
pcercuei 0:03b5121a232e 11050 if ((RAW == '<') && (NXT(1) == '/')) {
pcercuei 0:03b5121a232e 11051 xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
pcercuei 0:03b5121a232e 11052 } else if (RAW != 0) {
pcercuei 0:03b5121a232e 11053 xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
pcercuei 0:03b5121a232e 11054 }
pcercuei 0:03b5121a232e 11055
pcercuei 0:03b5121a232e 11056 /*
pcercuei 0:03b5121a232e 11057 * SAX: end of the document processing.
pcercuei 0:03b5121a232e 11058 */
pcercuei 0:03b5121a232e 11059 if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
pcercuei 0:03b5121a232e 11060 ctxt->sax->endDocument(ctxt->userData);
pcercuei 0:03b5121a232e 11061
pcercuei 0:03b5121a232e 11062 if (! ctxt->wellFormed) return(-1);
pcercuei 0:03b5121a232e 11063 return(0);
pcercuei 0:03b5121a232e 11064 }
pcercuei 0:03b5121a232e 11065
pcercuei 0:03b5121a232e 11066 #ifdef LIBXML_PUSH_ENABLED
pcercuei 0:03b5121a232e 11067 /************************************************************************
pcercuei 0:03b5121a232e 11068 * *
pcercuei 0:03b5121a232e 11069 * Progressive parsing interfaces *
pcercuei 0:03b5121a232e 11070 * *
pcercuei 0:03b5121a232e 11071 ************************************************************************/
pcercuei 0:03b5121a232e 11072
pcercuei 0:03b5121a232e 11073 /**
pcercuei 0:03b5121a232e 11074 * xmlParseLookupSequence:
pcercuei 0:03b5121a232e 11075 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 11076 * @first: the first char to lookup
pcercuei 0:03b5121a232e 11077 * @next: the next char to lookup or zero
pcercuei 0:03b5121a232e 11078 * @third: the next char to lookup or zero
pcercuei 0:03b5121a232e 11079 *
pcercuei 0:03b5121a232e 11080 * Try to find if a sequence (first, next, third) or just (first next) or
pcercuei 0:03b5121a232e 11081 * (first) is available in the input stream.
pcercuei 0:03b5121a232e 11082 * This function has a side effect of (possibly) incrementing ctxt->checkIndex
pcercuei 0:03b5121a232e 11083 * to avoid rescanning sequences of bytes, it DOES change the state of the
pcercuei 0:03b5121a232e 11084 * parser, do not use liberally.
pcercuei 0:03b5121a232e 11085 *
pcercuei 0:03b5121a232e 11086 * Returns the index to the current parsing point if the full sequence
pcercuei 0:03b5121a232e 11087 * is available, -1 otherwise.
pcercuei 0:03b5121a232e 11088 */
pcercuei 0:03b5121a232e 11089 static int
pcercuei 0:03b5121a232e 11090 xmlParseLookupSequence(xmlParserCtxtPtr ctxt, xmlChar first,
pcercuei 0:03b5121a232e 11091 xmlChar next, xmlChar third) {
pcercuei 0:03b5121a232e 11092 int base, len;
pcercuei 0:03b5121a232e 11093 xmlParserInputPtr in;
pcercuei 0:03b5121a232e 11094 const xmlChar *buf;
pcercuei 0:03b5121a232e 11095
pcercuei 0:03b5121a232e 11096 in = ctxt->input;
pcercuei 0:03b5121a232e 11097 if (in == NULL) return(-1);
pcercuei 0:03b5121a232e 11098 base = in->cur - in->base;
pcercuei 0:03b5121a232e 11099 if (base < 0) return(-1);
pcercuei 0:03b5121a232e 11100 if (ctxt->checkIndex > base)
pcercuei 0:03b5121a232e 11101 base = ctxt->checkIndex;
pcercuei 0:03b5121a232e 11102 if (in->buf == NULL) {
pcercuei 0:03b5121a232e 11103 buf = in->base;
pcercuei 0:03b5121a232e 11104 len = in->length;
pcercuei 0:03b5121a232e 11105 } else {
pcercuei 0:03b5121a232e 11106 buf = xmlBufContent(in->buf->buffer);
pcercuei 0:03b5121a232e 11107 len = xmlBufUse(in->buf->buffer);
pcercuei 0:03b5121a232e 11108 }
pcercuei 0:03b5121a232e 11109 /* take into account the sequence length */
pcercuei 0:03b5121a232e 11110 if (third) len -= 2;
pcercuei 0:03b5121a232e 11111 else if (next) len --;
pcercuei 0:03b5121a232e 11112 for (;base < len;base++) {
pcercuei 0:03b5121a232e 11113 if (buf[base] == first) {
pcercuei 0:03b5121a232e 11114 if (third != 0) {
pcercuei 0:03b5121a232e 11115 if ((buf[base + 1] != next) ||
pcercuei 0:03b5121a232e 11116 (buf[base + 2] != third)) continue;
pcercuei 0:03b5121a232e 11117 } else if (next != 0) {
pcercuei 0:03b5121a232e 11118 if (buf[base + 1] != next) continue;
pcercuei 0:03b5121a232e 11119 }
pcercuei 0:03b5121a232e 11120 ctxt->checkIndex = 0;
pcercuei 0:03b5121a232e 11121 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 11122 if (next == 0)
pcercuei 0:03b5121a232e 11123 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11124 "PP: lookup '%c' found at %d\n",
pcercuei 0:03b5121a232e 11125 first, base);
pcercuei 0:03b5121a232e 11126 else if (third == 0)
pcercuei 0:03b5121a232e 11127 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11128 "PP: lookup '%c%c' found at %d\n",
pcercuei 0:03b5121a232e 11129 first, next, base);
pcercuei 0:03b5121a232e 11130 else
pcercuei 0:03b5121a232e 11131 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11132 "PP: lookup '%c%c%c' found at %d\n",
pcercuei 0:03b5121a232e 11133 first, next, third, base);
pcercuei 0:03b5121a232e 11134 #endif
pcercuei 0:03b5121a232e 11135 return(base - (in->cur - in->base));
pcercuei 0:03b5121a232e 11136 }
pcercuei 0:03b5121a232e 11137 }
pcercuei 0:03b5121a232e 11138 ctxt->checkIndex = base;
pcercuei 0:03b5121a232e 11139 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 11140 if (next == 0)
pcercuei 0:03b5121a232e 11141 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11142 "PP: lookup '%c' failed\n", first);
pcercuei 0:03b5121a232e 11143 else if (third == 0)
pcercuei 0:03b5121a232e 11144 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11145 "PP: lookup '%c%c' failed\n", first, next);
pcercuei 0:03b5121a232e 11146 else
pcercuei 0:03b5121a232e 11147 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11148 "PP: lookup '%c%c%c' failed\n", first, next, third);
pcercuei 0:03b5121a232e 11149 #endif
pcercuei 0:03b5121a232e 11150 return(-1);
pcercuei 0:03b5121a232e 11151 }
pcercuei 0:03b5121a232e 11152
pcercuei 0:03b5121a232e 11153 /**
pcercuei 0:03b5121a232e 11154 * xmlParseGetLasts:
pcercuei 0:03b5121a232e 11155 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 11156 * @lastlt: pointer to store the last '<' from the input
pcercuei 0:03b5121a232e 11157 * @lastgt: pointer to store the last '>' from the input
pcercuei 0:03b5121a232e 11158 *
pcercuei 0:03b5121a232e 11159 * Lookup the last < and > in the current chunk
pcercuei 0:03b5121a232e 11160 */
pcercuei 0:03b5121a232e 11161 static void
pcercuei 0:03b5121a232e 11162 xmlParseGetLasts(xmlParserCtxtPtr ctxt, const xmlChar **lastlt,
pcercuei 0:03b5121a232e 11163 const xmlChar **lastgt) {
pcercuei 0:03b5121a232e 11164 const xmlChar *tmp;
pcercuei 0:03b5121a232e 11165
pcercuei 0:03b5121a232e 11166 if ((ctxt == NULL) || (lastlt == NULL) || (lastgt == NULL)) {
pcercuei 0:03b5121a232e 11167 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11168 "Internal error: xmlParseGetLasts\n");
pcercuei 0:03b5121a232e 11169 return;
pcercuei 0:03b5121a232e 11170 }
pcercuei 0:03b5121a232e 11171 if ((ctxt->progressive != 0) && (ctxt->inputNr == 1)) {
pcercuei 0:03b5121a232e 11172 tmp = ctxt->input->end;
pcercuei 0:03b5121a232e 11173 tmp--;
pcercuei 0:03b5121a232e 11174 while ((tmp >= ctxt->input->base) && (*tmp != '<')) tmp--;
pcercuei 0:03b5121a232e 11175 if (tmp < ctxt->input->base) {
pcercuei 0:03b5121a232e 11176 *lastlt = NULL;
pcercuei 0:03b5121a232e 11177 *lastgt = NULL;
pcercuei 0:03b5121a232e 11178 } else {
pcercuei 0:03b5121a232e 11179 *lastlt = tmp;
pcercuei 0:03b5121a232e 11180 tmp++;
pcercuei 0:03b5121a232e 11181 while ((tmp < ctxt->input->end) && (*tmp != '>')) {
pcercuei 0:03b5121a232e 11182 if (*tmp == '\'') {
pcercuei 0:03b5121a232e 11183 tmp++;
pcercuei 0:03b5121a232e 11184 while ((tmp < ctxt->input->end) && (*tmp != '\'')) tmp++;
pcercuei 0:03b5121a232e 11185 if (tmp < ctxt->input->end) tmp++;
pcercuei 0:03b5121a232e 11186 } else if (*tmp == '"') {
pcercuei 0:03b5121a232e 11187 tmp++;
pcercuei 0:03b5121a232e 11188 while ((tmp < ctxt->input->end) && (*tmp != '"')) tmp++;
pcercuei 0:03b5121a232e 11189 if (tmp < ctxt->input->end) tmp++;
pcercuei 0:03b5121a232e 11190 } else
pcercuei 0:03b5121a232e 11191 tmp++;
pcercuei 0:03b5121a232e 11192 }
pcercuei 0:03b5121a232e 11193 if (tmp < ctxt->input->end)
pcercuei 0:03b5121a232e 11194 *lastgt = tmp;
pcercuei 0:03b5121a232e 11195 else {
pcercuei 0:03b5121a232e 11196 tmp = *lastlt;
pcercuei 0:03b5121a232e 11197 tmp--;
pcercuei 0:03b5121a232e 11198 while ((tmp >= ctxt->input->base) && (*tmp != '>')) tmp--;
pcercuei 0:03b5121a232e 11199 if (tmp >= ctxt->input->base)
pcercuei 0:03b5121a232e 11200 *lastgt = tmp;
pcercuei 0:03b5121a232e 11201 else
pcercuei 0:03b5121a232e 11202 *lastgt = NULL;
pcercuei 0:03b5121a232e 11203 }
pcercuei 0:03b5121a232e 11204 }
pcercuei 0:03b5121a232e 11205 } else {
pcercuei 0:03b5121a232e 11206 *lastlt = NULL;
pcercuei 0:03b5121a232e 11207 *lastgt = NULL;
pcercuei 0:03b5121a232e 11208 }
pcercuei 0:03b5121a232e 11209 }
pcercuei 0:03b5121a232e 11210 /**
pcercuei 0:03b5121a232e 11211 * xmlCheckCdataPush:
pcercuei 0:03b5121a232e 11212 * @cur: pointer to the bock of characters
pcercuei 0:03b5121a232e 11213 * @len: length of the block in bytes
pcercuei 0:03b5121a232e 11214 *
pcercuei 0:03b5121a232e 11215 * Check that the block of characters is okay as SCdata content [20]
pcercuei 0:03b5121a232e 11216 *
pcercuei 0:03b5121a232e 11217 * Returns the number of bytes to pass if okay, a negative index where an
pcercuei 0:03b5121a232e 11218 * UTF-8 error occured otherwise
pcercuei 0:03b5121a232e 11219 */
pcercuei 0:03b5121a232e 11220 static int
pcercuei 0:03b5121a232e 11221 xmlCheckCdataPush(const xmlChar *utf, int len) {
pcercuei 0:03b5121a232e 11222 int ix;
pcercuei 0:03b5121a232e 11223 unsigned char c;
pcercuei 0:03b5121a232e 11224 int codepoint;
pcercuei 0:03b5121a232e 11225
pcercuei 0:03b5121a232e 11226 if ((utf == NULL) || (len <= 0))
pcercuei 0:03b5121a232e 11227 return(0);
pcercuei 0:03b5121a232e 11228
pcercuei 0:03b5121a232e 11229 for (ix = 0; ix < len;) { /* string is 0-terminated */
pcercuei 0:03b5121a232e 11230 c = utf[ix];
pcercuei 0:03b5121a232e 11231 if ((c & 0x80) == 0x00) { /* 1-byte code, starts with 10 */
pcercuei 0:03b5121a232e 11232 if (c >= 0x20)
pcercuei 0:03b5121a232e 11233 ix++;
pcercuei 0:03b5121a232e 11234 else if ((c == 0xA) || (c == 0xD) || (c == 0x9))
pcercuei 0:03b5121a232e 11235 ix++;
pcercuei 0:03b5121a232e 11236 else
pcercuei 0:03b5121a232e 11237 return(-ix);
pcercuei 0:03b5121a232e 11238 } else if ((c & 0xe0) == 0xc0) {/* 2-byte code, starts with 110 */
pcercuei 0:03b5121a232e 11239 if (ix + 2 > len) return(-ix);
pcercuei 0:03b5121a232e 11240 if ((utf[ix+1] & 0xc0 ) != 0x80)
pcercuei 0:03b5121a232e 11241 return(-ix);
pcercuei 0:03b5121a232e 11242 codepoint = (utf[ix] & 0x1f) << 6;
pcercuei 0:03b5121a232e 11243 codepoint |= utf[ix+1] & 0x3f;
pcercuei 0:03b5121a232e 11244 if (!xmlIsCharQ(codepoint))
pcercuei 0:03b5121a232e 11245 return(-ix);
pcercuei 0:03b5121a232e 11246 ix += 2;
pcercuei 0:03b5121a232e 11247 } else if ((c & 0xf0) == 0xe0) {/* 3-byte code, starts with 1110 */
pcercuei 0:03b5121a232e 11248 if (ix + 3 > len) return(-ix);
pcercuei 0:03b5121a232e 11249 if (((utf[ix+1] & 0xc0) != 0x80) ||
pcercuei 0:03b5121a232e 11250 ((utf[ix+2] & 0xc0) != 0x80))
pcercuei 0:03b5121a232e 11251 return(-ix);
pcercuei 0:03b5121a232e 11252 codepoint = (utf[ix] & 0xf) << 12;
pcercuei 0:03b5121a232e 11253 codepoint |= (utf[ix+1] & 0x3f) << 6;
pcercuei 0:03b5121a232e 11254 codepoint |= utf[ix+2] & 0x3f;
pcercuei 0:03b5121a232e 11255 if (!xmlIsCharQ(codepoint))
pcercuei 0:03b5121a232e 11256 return(-ix);
pcercuei 0:03b5121a232e 11257 ix += 3;
pcercuei 0:03b5121a232e 11258 } else if ((c & 0xf8) == 0xf0) {/* 4-byte code, starts with 11110 */
pcercuei 0:03b5121a232e 11259 if (ix + 4 > len) return(-ix);
pcercuei 0:03b5121a232e 11260 if (((utf[ix+1] & 0xc0) != 0x80) ||
pcercuei 0:03b5121a232e 11261 ((utf[ix+2] & 0xc0) != 0x80) ||
pcercuei 0:03b5121a232e 11262 ((utf[ix+3] & 0xc0) != 0x80))
pcercuei 0:03b5121a232e 11263 return(-ix);
pcercuei 0:03b5121a232e 11264 codepoint = (utf[ix] & 0x7) << 18;
pcercuei 0:03b5121a232e 11265 codepoint |= (utf[ix+1] & 0x3f) << 12;
pcercuei 0:03b5121a232e 11266 codepoint |= (utf[ix+2] & 0x3f) << 6;
pcercuei 0:03b5121a232e 11267 codepoint |= utf[ix+3] & 0x3f;
pcercuei 0:03b5121a232e 11268 if (!xmlIsCharQ(codepoint))
pcercuei 0:03b5121a232e 11269 return(-ix);
pcercuei 0:03b5121a232e 11270 ix += 4;
pcercuei 0:03b5121a232e 11271 } else /* unknown encoding */
pcercuei 0:03b5121a232e 11272 return(-ix);
pcercuei 0:03b5121a232e 11273 }
pcercuei 0:03b5121a232e 11274 return(ix);
pcercuei 0:03b5121a232e 11275 }
pcercuei 0:03b5121a232e 11276
pcercuei 0:03b5121a232e 11277 /**
pcercuei 0:03b5121a232e 11278 * xmlParseTryOrFinish:
pcercuei 0:03b5121a232e 11279 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 11280 * @terminate: last chunk indicator
pcercuei 0:03b5121a232e 11281 *
pcercuei 0:03b5121a232e 11282 * Try to progress on parsing
pcercuei 0:03b5121a232e 11283 *
pcercuei 0:03b5121a232e 11284 * Returns zero if no parsing was possible
pcercuei 0:03b5121a232e 11285 */
pcercuei 0:03b5121a232e 11286 static int
pcercuei 0:03b5121a232e 11287 xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
pcercuei 0:03b5121a232e 11288 int ret = 0;
pcercuei 0:03b5121a232e 11289 int avail, tlen;
pcercuei 0:03b5121a232e 11290 xmlChar cur, next;
pcercuei 0:03b5121a232e 11291 const xmlChar *lastlt, *lastgt;
pcercuei 0:03b5121a232e 11292
pcercuei 0:03b5121a232e 11293 if (ctxt->input == NULL)
pcercuei 0:03b5121a232e 11294 return(0);
pcercuei 0:03b5121a232e 11295
pcercuei 0:03b5121a232e 11296 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 11297 switch (ctxt->instate) {
pcercuei 0:03b5121a232e 11298 case XML_PARSER_EOF:
pcercuei 0:03b5121a232e 11299 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11300 "PP: try EOF\n"); break;
pcercuei 0:03b5121a232e 11301 case XML_PARSER_START:
pcercuei 0:03b5121a232e 11302 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11303 "PP: try START\n"); break;
pcercuei 0:03b5121a232e 11304 case XML_PARSER_MISC:
pcercuei 0:03b5121a232e 11305 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11306 "PP: try MISC\n");break;
pcercuei 0:03b5121a232e 11307 case XML_PARSER_COMMENT:
pcercuei 0:03b5121a232e 11308 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11309 "PP: try COMMENT\n");break;
pcercuei 0:03b5121a232e 11310 case XML_PARSER_PROLOG:
pcercuei 0:03b5121a232e 11311 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11312 "PP: try PROLOG\n");break;
pcercuei 0:03b5121a232e 11313 case XML_PARSER_START_TAG:
pcercuei 0:03b5121a232e 11314 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11315 "PP: try START_TAG\n");break;
pcercuei 0:03b5121a232e 11316 case XML_PARSER_CONTENT:
pcercuei 0:03b5121a232e 11317 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11318 "PP: try CONTENT\n");break;
pcercuei 0:03b5121a232e 11319 case XML_PARSER_CDATA_SECTION:
pcercuei 0:03b5121a232e 11320 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11321 "PP: try CDATA_SECTION\n");break;
pcercuei 0:03b5121a232e 11322 case XML_PARSER_END_TAG:
pcercuei 0:03b5121a232e 11323 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11324 "PP: try END_TAG\n");break;
pcercuei 0:03b5121a232e 11325 case XML_PARSER_ENTITY_DECL:
pcercuei 0:03b5121a232e 11326 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11327 "PP: try ENTITY_DECL\n");break;
pcercuei 0:03b5121a232e 11328 case XML_PARSER_ENTITY_VALUE:
pcercuei 0:03b5121a232e 11329 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11330 "PP: try ENTITY_VALUE\n");break;
pcercuei 0:03b5121a232e 11331 case XML_PARSER_ATTRIBUTE_VALUE:
pcercuei 0:03b5121a232e 11332 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11333 "PP: try ATTRIBUTE_VALUE\n");break;
pcercuei 0:03b5121a232e 11334 case XML_PARSER_DTD:
pcercuei 0:03b5121a232e 11335 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11336 "PP: try DTD\n");break;
pcercuei 0:03b5121a232e 11337 case XML_PARSER_EPILOG:
pcercuei 0:03b5121a232e 11338 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11339 "PP: try EPILOG\n");break;
pcercuei 0:03b5121a232e 11340 case XML_PARSER_PI:
pcercuei 0:03b5121a232e 11341 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11342 "PP: try PI\n");break;
pcercuei 0:03b5121a232e 11343 case XML_PARSER_IGNORE:
pcercuei 0:03b5121a232e 11344 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11345 "PP: try IGNORE\n");break;
pcercuei 0:03b5121a232e 11346 }
pcercuei 0:03b5121a232e 11347 #endif
pcercuei 0:03b5121a232e 11348
pcercuei 0:03b5121a232e 11349 if ((ctxt->input != NULL) &&
pcercuei 0:03b5121a232e 11350 (ctxt->input->cur - ctxt->input->base > 4096)) {
pcercuei 0:03b5121a232e 11351 xmlSHRINK(ctxt);
pcercuei 0:03b5121a232e 11352 ctxt->checkIndex = 0;
pcercuei 0:03b5121a232e 11353 }
pcercuei 0:03b5121a232e 11354 xmlParseGetLasts(ctxt, &lastlt, &lastgt);
pcercuei 0:03b5121a232e 11355
pcercuei 0:03b5121a232e 11356 while (ctxt->instate != XML_PARSER_EOF) {
pcercuei 0:03b5121a232e 11357 if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
pcercuei 0:03b5121a232e 11358 return(0);
pcercuei 0:03b5121a232e 11359
pcercuei 0:03b5121a232e 11360
pcercuei 0:03b5121a232e 11361 /*
pcercuei 0:03b5121a232e 11362 * Pop-up of finished entities.
pcercuei 0:03b5121a232e 11363 */
pcercuei 0:03b5121a232e 11364 while ((RAW == 0) && (ctxt->inputNr > 1))
pcercuei 0:03b5121a232e 11365 xmlPopInput(ctxt);
pcercuei 0:03b5121a232e 11366
pcercuei 0:03b5121a232e 11367 if (ctxt->input == NULL) break;
pcercuei 0:03b5121a232e 11368 if (ctxt->input->buf == NULL)
pcercuei 0:03b5121a232e 11369 avail = ctxt->input->length -
pcercuei 0:03b5121a232e 11370 (ctxt->input->cur - ctxt->input->base);
pcercuei 0:03b5121a232e 11371 else {
pcercuei 0:03b5121a232e 11372 /*
pcercuei 0:03b5121a232e 11373 * If we are operating on converted input, try to flush
pcercuei 0:03b5121a232e 11374 * remainng chars to avoid them stalling in the non-converted
pcercuei 0:03b5121a232e 11375 * buffer. But do not do this in document start where
pcercuei 0:03b5121a232e 11376 * encoding="..." may not have been read and we work on a
pcercuei 0:03b5121a232e 11377 * guessed encoding.
pcercuei 0:03b5121a232e 11378 */
pcercuei 0:03b5121a232e 11379 if ((ctxt->instate != XML_PARSER_START) &&
pcercuei 0:03b5121a232e 11380 (ctxt->input->buf->raw != NULL) &&
pcercuei 0:03b5121a232e 11381 (xmlBufIsEmpty(ctxt->input->buf->raw) == 0)) {
pcercuei 0:03b5121a232e 11382 size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer,
pcercuei 0:03b5121a232e 11383 ctxt->input);
pcercuei 0:03b5121a232e 11384 size_t current = ctxt->input->cur - ctxt->input->base;
pcercuei 0:03b5121a232e 11385
pcercuei 0:03b5121a232e 11386 xmlParserInputBufferPush(ctxt->input->buf, 0, "");
pcercuei 0:03b5121a232e 11387 xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input,
pcercuei 0:03b5121a232e 11388 base, current);
pcercuei 0:03b5121a232e 11389 }
pcercuei 0:03b5121a232e 11390 avail = xmlBufUse(ctxt->input->buf->buffer) -
pcercuei 0:03b5121a232e 11391 (ctxt->input->cur - ctxt->input->base);
pcercuei 0:03b5121a232e 11392 }
pcercuei 0:03b5121a232e 11393 if (avail < 1)
pcercuei 0:03b5121a232e 11394 goto done;
pcercuei 0:03b5121a232e 11395 switch (ctxt->instate) {
pcercuei 0:03b5121a232e 11396 case XML_PARSER_EOF:
pcercuei 0:03b5121a232e 11397 /*
pcercuei 0:03b5121a232e 11398 * Document parsing is done !
pcercuei 0:03b5121a232e 11399 */
pcercuei 0:03b5121a232e 11400 goto done;
pcercuei 0:03b5121a232e 11401 case XML_PARSER_START:
pcercuei 0:03b5121a232e 11402 if (ctxt->charset == XML_CHAR_ENCODING_NONE) {
pcercuei 0:03b5121a232e 11403 xmlChar start[4];
pcercuei 0:03b5121a232e 11404 xmlCharEncoding enc;
pcercuei 0:03b5121a232e 11405
pcercuei 0:03b5121a232e 11406 /*
pcercuei 0:03b5121a232e 11407 * Very first chars read from the document flow.
pcercuei 0:03b5121a232e 11408 */
pcercuei 0:03b5121a232e 11409 if (avail < 4)
pcercuei 0:03b5121a232e 11410 goto done;
pcercuei 0:03b5121a232e 11411
pcercuei 0:03b5121a232e 11412 /*
pcercuei 0:03b5121a232e 11413 * Get the 4 first bytes and decode the charset
pcercuei 0:03b5121a232e 11414 * if enc != XML_CHAR_ENCODING_NONE
pcercuei 0:03b5121a232e 11415 * plug some encoding conversion routines,
pcercuei 0:03b5121a232e 11416 * else xmlSwitchEncoding will set to (default)
pcercuei 0:03b5121a232e 11417 * UTF8.
pcercuei 0:03b5121a232e 11418 */
pcercuei 0:03b5121a232e 11419 start[0] = RAW;
pcercuei 0:03b5121a232e 11420 start[1] = NXT(1);
pcercuei 0:03b5121a232e 11421 start[2] = NXT(2);
pcercuei 0:03b5121a232e 11422 start[3] = NXT(3);
pcercuei 0:03b5121a232e 11423 enc = xmlDetectCharEncoding(start, 4);
pcercuei 0:03b5121a232e 11424 xmlSwitchEncoding(ctxt, enc);
pcercuei 0:03b5121a232e 11425 break;
pcercuei 0:03b5121a232e 11426 }
pcercuei 0:03b5121a232e 11427
pcercuei 0:03b5121a232e 11428 if (avail < 2)
pcercuei 0:03b5121a232e 11429 goto done;
pcercuei 0:03b5121a232e 11430 cur = ctxt->input->cur[0];
pcercuei 0:03b5121a232e 11431 next = ctxt->input->cur[1];
pcercuei 0:03b5121a232e 11432 if (cur == 0) {
pcercuei 0:03b5121a232e 11433 if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
pcercuei 0:03b5121a232e 11434 ctxt->sax->setDocumentLocator(ctxt->userData,
pcercuei 0:03b5121a232e 11435 &xmlDefaultSAXLocator);
pcercuei 0:03b5121a232e 11436 xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
pcercuei 0:03b5121a232e 11437 xmlHaltParser(ctxt);
pcercuei 0:03b5121a232e 11438 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 11439 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11440 "PP: entering EOF\n");
pcercuei 0:03b5121a232e 11441 #endif
pcercuei 0:03b5121a232e 11442 if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
pcercuei 0:03b5121a232e 11443 ctxt->sax->endDocument(ctxt->userData);
pcercuei 0:03b5121a232e 11444 goto done;
pcercuei 0:03b5121a232e 11445 }
pcercuei 0:03b5121a232e 11446 if ((cur == '<') && (next == '?')) {
pcercuei 0:03b5121a232e 11447 /* PI or XML decl */
pcercuei 0:03b5121a232e 11448 if (avail < 5) return(ret);
pcercuei 0:03b5121a232e 11449 if ((!terminate) &&
pcercuei 0:03b5121a232e 11450 (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
pcercuei 0:03b5121a232e 11451 return(ret);
pcercuei 0:03b5121a232e 11452 if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
pcercuei 0:03b5121a232e 11453 ctxt->sax->setDocumentLocator(ctxt->userData,
pcercuei 0:03b5121a232e 11454 &xmlDefaultSAXLocator);
pcercuei 0:03b5121a232e 11455 if ((ctxt->input->cur[2] == 'x') &&
pcercuei 0:03b5121a232e 11456 (ctxt->input->cur[3] == 'm') &&
pcercuei 0:03b5121a232e 11457 (ctxt->input->cur[4] == 'l') &&
pcercuei 0:03b5121a232e 11458 (IS_BLANK_CH(ctxt->input->cur[5]))) {
pcercuei 0:03b5121a232e 11459 ret += 5;
pcercuei 0:03b5121a232e 11460 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 11461 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11462 "PP: Parsing XML Decl\n");
pcercuei 0:03b5121a232e 11463 #endif
pcercuei 0:03b5121a232e 11464 xmlParseXMLDecl(ctxt);
pcercuei 0:03b5121a232e 11465 if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
pcercuei 0:03b5121a232e 11466 /*
pcercuei 0:03b5121a232e 11467 * The XML REC instructs us to stop parsing right
pcercuei 0:03b5121a232e 11468 * here
pcercuei 0:03b5121a232e 11469 */
pcercuei 0:03b5121a232e 11470 xmlHaltParser(ctxt);
pcercuei 0:03b5121a232e 11471 return(0);
pcercuei 0:03b5121a232e 11472 }
pcercuei 0:03b5121a232e 11473 ctxt->standalone = ctxt->input->standalone;
pcercuei 0:03b5121a232e 11474 if ((ctxt->encoding == NULL) &&
pcercuei 0:03b5121a232e 11475 (ctxt->input->encoding != NULL))
pcercuei 0:03b5121a232e 11476 ctxt->encoding = xmlStrdup(ctxt->input->encoding);
pcercuei 0:03b5121a232e 11477 if ((ctxt->sax) && (ctxt->sax->startDocument) &&
pcercuei 0:03b5121a232e 11478 (!ctxt->disableSAX))
pcercuei 0:03b5121a232e 11479 ctxt->sax->startDocument(ctxt->userData);
pcercuei 0:03b5121a232e 11480 ctxt->instate = XML_PARSER_MISC;
pcercuei 0:03b5121a232e 11481 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 11482 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11483 "PP: entering MISC\n");
pcercuei 0:03b5121a232e 11484 #endif
pcercuei 0:03b5121a232e 11485 } else {
pcercuei 0:03b5121a232e 11486 ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
pcercuei 0:03b5121a232e 11487 if ((ctxt->sax) && (ctxt->sax->startDocument) &&
pcercuei 0:03b5121a232e 11488 (!ctxt->disableSAX))
pcercuei 0:03b5121a232e 11489 ctxt->sax->startDocument(ctxt->userData);
pcercuei 0:03b5121a232e 11490 ctxt->instate = XML_PARSER_MISC;
pcercuei 0:03b5121a232e 11491 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 11492 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11493 "PP: entering MISC\n");
pcercuei 0:03b5121a232e 11494 #endif
pcercuei 0:03b5121a232e 11495 }
pcercuei 0:03b5121a232e 11496 } else {
pcercuei 0:03b5121a232e 11497 if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
pcercuei 0:03b5121a232e 11498 ctxt->sax->setDocumentLocator(ctxt->userData,
pcercuei 0:03b5121a232e 11499 &xmlDefaultSAXLocator);
pcercuei 0:03b5121a232e 11500 ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
pcercuei 0:03b5121a232e 11501 if (ctxt->version == NULL) {
pcercuei 0:03b5121a232e 11502 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 11503 break;
pcercuei 0:03b5121a232e 11504 }
pcercuei 0:03b5121a232e 11505 if ((ctxt->sax) && (ctxt->sax->startDocument) &&
pcercuei 0:03b5121a232e 11506 (!ctxt->disableSAX))
pcercuei 0:03b5121a232e 11507 ctxt->sax->startDocument(ctxt->userData);
pcercuei 0:03b5121a232e 11508 ctxt->instate = XML_PARSER_MISC;
pcercuei 0:03b5121a232e 11509 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 11510 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11511 "PP: entering MISC\n");
pcercuei 0:03b5121a232e 11512 #endif
pcercuei 0:03b5121a232e 11513 }
pcercuei 0:03b5121a232e 11514 break;
pcercuei 0:03b5121a232e 11515 case XML_PARSER_START_TAG: {
pcercuei 0:03b5121a232e 11516 const xmlChar *name;
pcercuei 0:03b5121a232e 11517 const xmlChar *prefix = NULL;
pcercuei 0:03b5121a232e 11518 const xmlChar *URI = NULL;
pcercuei 0:03b5121a232e 11519 int nsNr = ctxt->nsNr;
pcercuei 0:03b5121a232e 11520
pcercuei 0:03b5121a232e 11521 if ((avail < 2) && (ctxt->inputNr == 1))
pcercuei 0:03b5121a232e 11522 goto done;
pcercuei 0:03b5121a232e 11523 cur = ctxt->input->cur[0];
pcercuei 0:03b5121a232e 11524 if (cur != '<') {
pcercuei 0:03b5121a232e 11525 xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
pcercuei 0:03b5121a232e 11526 xmlHaltParser(ctxt);
pcercuei 0:03b5121a232e 11527 if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
pcercuei 0:03b5121a232e 11528 ctxt->sax->endDocument(ctxt->userData);
pcercuei 0:03b5121a232e 11529 goto done;
pcercuei 0:03b5121a232e 11530 }
pcercuei 0:03b5121a232e 11531 if (!terminate) {
pcercuei 0:03b5121a232e 11532 if (ctxt->progressive) {
pcercuei 0:03b5121a232e 11533 /* > can be found unescaped in attribute values */
pcercuei 0:03b5121a232e 11534 if ((lastgt == NULL) || (ctxt->input->cur >= lastgt))
pcercuei 0:03b5121a232e 11535 goto done;
pcercuei 0:03b5121a232e 11536 } else if (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0) {
pcercuei 0:03b5121a232e 11537 goto done;
pcercuei 0:03b5121a232e 11538 }
pcercuei 0:03b5121a232e 11539 }
pcercuei 0:03b5121a232e 11540 if (ctxt->spaceNr == 0)
pcercuei 0:03b5121a232e 11541 spacePush(ctxt, -1);
pcercuei 0:03b5121a232e 11542 else if (*ctxt->space == -2)
pcercuei 0:03b5121a232e 11543 spacePush(ctxt, -1);
pcercuei 0:03b5121a232e 11544 else
pcercuei 0:03b5121a232e 11545 spacePush(ctxt, *ctxt->space);
pcercuei 0:03b5121a232e 11546 #ifdef LIBXML_SAX1_ENABLED
pcercuei 0:03b5121a232e 11547 if (ctxt->sax2)
pcercuei 0:03b5121a232e 11548 #endif /* LIBXML_SAX1_ENABLED */
pcercuei 0:03b5121a232e 11549 name = xmlParseStartTag2(ctxt, &prefix, &URI, &tlen);
pcercuei 0:03b5121a232e 11550 #ifdef LIBXML_SAX1_ENABLED
pcercuei 0:03b5121a232e 11551 else
pcercuei 0:03b5121a232e 11552 name = xmlParseStartTag(ctxt);
pcercuei 0:03b5121a232e 11553 #endif /* LIBXML_SAX1_ENABLED */
pcercuei 0:03b5121a232e 11554 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 11555 goto done;
pcercuei 0:03b5121a232e 11556 if (name == NULL) {
pcercuei 0:03b5121a232e 11557 spacePop(ctxt);
pcercuei 0:03b5121a232e 11558 xmlHaltParser(ctxt);
pcercuei 0:03b5121a232e 11559 if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
pcercuei 0:03b5121a232e 11560 ctxt->sax->endDocument(ctxt->userData);
pcercuei 0:03b5121a232e 11561 goto done;
pcercuei 0:03b5121a232e 11562 }
pcercuei 0:03b5121a232e 11563 #ifdef LIBXML_VALID_ENABLED
pcercuei 0:03b5121a232e 11564 /*
pcercuei 0:03b5121a232e 11565 * [ VC: Root Element Type ]
pcercuei 0:03b5121a232e 11566 * The Name in the document type declaration must match
pcercuei 0:03b5121a232e 11567 * the element type of the root element.
pcercuei 0:03b5121a232e 11568 */
pcercuei 0:03b5121a232e 11569 if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
pcercuei 0:03b5121a232e 11570 ctxt->node && (ctxt->node == ctxt->myDoc->children))
pcercuei 0:03b5121a232e 11571 ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
pcercuei 0:03b5121a232e 11572 #endif /* LIBXML_VALID_ENABLED */
pcercuei 0:03b5121a232e 11573
pcercuei 0:03b5121a232e 11574 /*
pcercuei 0:03b5121a232e 11575 * Check for an Empty Element.
pcercuei 0:03b5121a232e 11576 */
pcercuei 0:03b5121a232e 11577 if ((RAW == '/') && (NXT(1) == '>')) {
pcercuei 0:03b5121a232e 11578 SKIP(2);
pcercuei 0:03b5121a232e 11579
pcercuei 0:03b5121a232e 11580 if (ctxt->sax2) {
pcercuei 0:03b5121a232e 11581 if ((ctxt->sax != NULL) &&
pcercuei 0:03b5121a232e 11582 (ctxt->sax->endElementNs != NULL) &&
pcercuei 0:03b5121a232e 11583 (!ctxt->disableSAX))
pcercuei 0:03b5121a232e 11584 ctxt->sax->endElementNs(ctxt->userData, name,
pcercuei 0:03b5121a232e 11585 prefix, URI);
pcercuei 0:03b5121a232e 11586 if (ctxt->nsNr - nsNr > 0)
pcercuei 0:03b5121a232e 11587 nsPop(ctxt, ctxt->nsNr - nsNr);
pcercuei 0:03b5121a232e 11588 #ifdef LIBXML_SAX1_ENABLED
pcercuei 0:03b5121a232e 11589 } else {
pcercuei 0:03b5121a232e 11590 if ((ctxt->sax != NULL) &&
pcercuei 0:03b5121a232e 11591 (ctxt->sax->endElement != NULL) &&
pcercuei 0:03b5121a232e 11592 (!ctxt->disableSAX))
pcercuei 0:03b5121a232e 11593 ctxt->sax->endElement(ctxt->userData, name);
pcercuei 0:03b5121a232e 11594 #endif /* LIBXML_SAX1_ENABLED */
pcercuei 0:03b5121a232e 11595 }
pcercuei 0:03b5121a232e 11596 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 11597 goto done;
pcercuei 0:03b5121a232e 11598 spacePop(ctxt);
pcercuei 0:03b5121a232e 11599 if (ctxt->nameNr == 0) {
pcercuei 0:03b5121a232e 11600 ctxt->instate = XML_PARSER_EPILOG;
pcercuei 0:03b5121a232e 11601 } else {
pcercuei 0:03b5121a232e 11602 ctxt->instate = XML_PARSER_CONTENT;
pcercuei 0:03b5121a232e 11603 }
pcercuei 0:03b5121a232e 11604 ctxt->progressive = 1;
pcercuei 0:03b5121a232e 11605 break;
pcercuei 0:03b5121a232e 11606 }
pcercuei 0:03b5121a232e 11607 if (RAW == '>') {
pcercuei 0:03b5121a232e 11608 NEXT;
pcercuei 0:03b5121a232e 11609 } else {
pcercuei 0:03b5121a232e 11610 xmlFatalErrMsgStr(ctxt, XML_ERR_GT_REQUIRED,
pcercuei 0:03b5121a232e 11611 "Couldn't find end of Start Tag %s\n",
pcercuei 0:03b5121a232e 11612 name);
pcercuei 0:03b5121a232e 11613 nodePop(ctxt);
pcercuei 0:03b5121a232e 11614 spacePop(ctxt);
pcercuei 0:03b5121a232e 11615 }
pcercuei 0:03b5121a232e 11616 if (ctxt->sax2)
pcercuei 0:03b5121a232e 11617 nameNsPush(ctxt, name, prefix, URI, ctxt->nsNr - nsNr);
pcercuei 0:03b5121a232e 11618 #ifdef LIBXML_SAX1_ENABLED
pcercuei 0:03b5121a232e 11619 else
pcercuei 0:03b5121a232e 11620 namePush(ctxt, name);
pcercuei 0:03b5121a232e 11621 #endif /* LIBXML_SAX1_ENABLED */
pcercuei 0:03b5121a232e 11622
pcercuei 0:03b5121a232e 11623 ctxt->instate = XML_PARSER_CONTENT;
pcercuei 0:03b5121a232e 11624 ctxt->progressive = 1;
pcercuei 0:03b5121a232e 11625 break;
pcercuei 0:03b5121a232e 11626 }
pcercuei 0:03b5121a232e 11627 case XML_PARSER_CONTENT: {
pcercuei 0:03b5121a232e 11628 const xmlChar *test;
pcercuei 0:03b5121a232e 11629 unsigned int cons;
pcercuei 0:03b5121a232e 11630 if ((avail < 2) && (ctxt->inputNr == 1))
pcercuei 0:03b5121a232e 11631 goto done;
pcercuei 0:03b5121a232e 11632 cur = ctxt->input->cur[0];
pcercuei 0:03b5121a232e 11633 next = ctxt->input->cur[1];
pcercuei 0:03b5121a232e 11634
pcercuei 0:03b5121a232e 11635 test = CUR_PTR;
pcercuei 0:03b5121a232e 11636 cons = ctxt->input->consumed;
pcercuei 0:03b5121a232e 11637 if ((cur == '<') && (next == '/')) {
pcercuei 0:03b5121a232e 11638 ctxt->instate = XML_PARSER_END_TAG;
pcercuei 0:03b5121a232e 11639 break;
pcercuei 0:03b5121a232e 11640 } else if ((cur == '<') && (next == '?')) {
pcercuei 0:03b5121a232e 11641 if ((!terminate) &&
pcercuei 0:03b5121a232e 11642 (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0)) {
pcercuei 0:03b5121a232e 11643 ctxt->progressive = XML_PARSER_PI;
pcercuei 0:03b5121a232e 11644 goto done;
pcercuei 0:03b5121a232e 11645 }
pcercuei 0:03b5121a232e 11646 xmlParsePI(ctxt);
pcercuei 0:03b5121a232e 11647 ctxt->instate = XML_PARSER_CONTENT;
pcercuei 0:03b5121a232e 11648 ctxt->progressive = 1;
pcercuei 0:03b5121a232e 11649 } else if ((cur == '<') && (next != '!')) {
pcercuei 0:03b5121a232e 11650 ctxt->instate = XML_PARSER_START_TAG;
pcercuei 0:03b5121a232e 11651 break;
pcercuei 0:03b5121a232e 11652 } else if ((cur == '<') && (next == '!') &&
pcercuei 0:03b5121a232e 11653 (ctxt->input->cur[2] == '-') &&
pcercuei 0:03b5121a232e 11654 (ctxt->input->cur[3] == '-')) {
pcercuei 0:03b5121a232e 11655 int term;
pcercuei 0:03b5121a232e 11656
pcercuei 0:03b5121a232e 11657 if (avail < 4)
pcercuei 0:03b5121a232e 11658 goto done;
pcercuei 0:03b5121a232e 11659 ctxt->input->cur += 4;
pcercuei 0:03b5121a232e 11660 term = xmlParseLookupSequence(ctxt, '-', '-', '>');
pcercuei 0:03b5121a232e 11661 ctxt->input->cur -= 4;
pcercuei 0:03b5121a232e 11662 if ((!terminate) && (term < 0)) {
pcercuei 0:03b5121a232e 11663 ctxt->progressive = XML_PARSER_COMMENT;
pcercuei 0:03b5121a232e 11664 goto done;
pcercuei 0:03b5121a232e 11665 }
pcercuei 0:03b5121a232e 11666 xmlParseComment(ctxt);
pcercuei 0:03b5121a232e 11667 ctxt->instate = XML_PARSER_CONTENT;
pcercuei 0:03b5121a232e 11668 ctxt->progressive = 1;
pcercuei 0:03b5121a232e 11669 } else if ((cur == '<') && (ctxt->input->cur[1] == '!') &&
pcercuei 0:03b5121a232e 11670 (ctxt->input->cur[2] == '[') &&
pcercuei 0:03b5121a232e 11671 (ctxt->input->cur[3] == 'C') &&
pcercuei 0:03b5121a232e 11672 (ctxt->input->cur[4] == 'D') &&
pcercuei 0:03b5121a232e 11673 (ctxt->input->cur[5] == 'A') &&
pcercuei 0:03b5121a232e 11674 (ctxt->input->cur[6] == 'T') &&
pcercuei 0:03b5121a232e 11675 (ctxt->input->cur[7] == 'A') &&
pcercuei 0:03b5121a232e 11676 (ctxt->input->cur[8] == '[')) {
pcercuei 0:03b5121a232e 11677 SKIP(9);
pcercuei 0:03b5121a232e 11678 ctxt->instate = XML_PARSER_CDATA_SECTION;
pcercuei 0:03b5121a232e 11679 break;
pcercuei 0:03b5121a232e 11680 } else if ((cur == '<') && (next == '!') &&
pcercuei 0:03b5121a232e 11681 (avail < 9)) {
pcercuei 0:03b5121a232e 11682 goto done;
pcercuei 0:03b5121a232e 11683 } else if (cur == '&') {
pcercuei 0:03b5121a232e 11684 if ((!terminate) &&
pcercuei 0:03b5121a232e 11685 (xmlParseLookupSequence(ctxt, ';', 0, 0) < 0))
pcercuei 0:03b5121a232e 11686 goto done;
pcercuei 0:03b5121a232e 11687 xmlParseReference(ctxt);
pcercuei 0:03b5121a232e 11688 } else {
pcercuei 0:03b5121a232e 11689 /* TODO Avoid the extra copy, handle directly !!! */
pcercuei 0:03b5121a232e 11690 /*
pcercuei 0:03b5121a232e 11691 * Goal of the following test is:
pcercuei 0:03b5121a232e 11692 * - minimize calls to the SAX 'character' callback
pcercuei 0:03b5121a232e 11693 * when they are mergeable
pcercuei 0:03b5121a232e 11694 * - handle an problem for isBlank when we only parse
pcercuei 0:03b5121a232e 11695 * a sequence of blank chars and the next one is
pcercuei 0:03b5121a232e 11696 * not available to check against '<' presence.
pcercuei 0:03b5121a232e 11697 * - tries to homogenize the differences in SAX
pcercuei 0:03b5121a232e 11698 * callbacks between the push and pull versions
pcercuei 0:03b5121a232e 11699 * of the parser.
pcercuei 0:03b5121a232e 11700 */
pcercuei 0:03b5121a232e 11701 if ((ctxt->inputNr == 1) &&
pcercuei 0:03b5121a232e 11702 (avail < XML_PARSER_BIG_BUFFER_SIZE)) {
pcercuei 0:03b5121a232e 11703 if (!terminate) {
pcercuei 0:03b5121a232e 11704 if (ctxt->progressive) {
pcercuei 0:03b5121a232e 11705 if ((lastlt == NULL) ||
pcercuei 0:03b5121a232e 11706 (ctxt->input->cur > lastlt))
pcercuei 0:03b5121a232e 11707 goto done;
pcercuei 0:03b5121a232e 11708 } else if (xmlParseLookupSequence(ctxt,
pcercuei 0:03b5121a232e 11709 '<', 0, 0) < 0) {
pcercuei 0:03b5121a232e 11710 goto done;
pcercuei 0:03b5121a232e 11711 }
pcercuei 0:03b5121a232e 11712 }
pcercuei 0:03b5121a232e 11713 }
pcercuei 0:03b5121a232e 11714 ctxt->checkIndex = 0;
pcercuei 0:03b5121a232e 11715 xmlParseCharData(ctxt, 0);
pcercuei 0:03b5121a232e 11716 }
pcercuei 0:03b5121a232e 11717 /*
pcercuei 0:03b5121a232e 11718 * Pop-up of finished entities.
pcercuei 0:03b5121a232e 11719 */
pcercuei 0:03b5121a232e 11720 while ((RAW == 0) && (ctxt->inputNr > 1))
pcercuei 0:03b5121a232e 11721 xmlPopInput(ctxt);
pcercuei 0:03b5121a232e 11722 if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
pcercuei 0:03b5121a232e 11723 xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
pcercuei 0:03b5121a232e 11724 "detected an error in element content\n");
pcercuei 0:03b5121a232e 11725 xmlHaltParser(ctxt);
pcercuei 0:03b5121a232e 11726 break;
pcercuei 0:03b5121a232e 11727 }
pcercuei 0:03b5121a232e 11728 break;
pcercuei 0:03b5121a232e 11729 }
pcercuei 0:03b5121a232e 11730 case XML_PARSER_END_TAG:
pcercuei 0:03b5121a232e 11731 if (avail < 2)
pcercuei 0:03b5121a232e 11732 goto done;
pcercuei 0:03b5121a232e 11733 if (!terminate) {
pcercuei 0:03b5121a232e 11734 if (ctxt->progressive) {
pcercuei 0:03b5121a232e 11735 /* > can be found unescaped in attribute values */
pcercuei 0:03b5121a232e 11736 if ((lastgt == NULL) || (ctxt->input->cur >= lastgt))
pcercuei 0:03b5121a232e 11737 goto done;
pcercuei 0:03b5121a232e 11738 } else if (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0) {
pcercuei 0:03b5121a232e 11739 goto done;
pcercuei 0:03b5121a232e 11740 }
pcercuei 0:03b5121a232e 11741 }
pcercuei 0:03b5121a232e 11742 if (ctxt->sax2) {
pcercuei 0:03b5121a232e 11743 xmlParseEndTag2(ctxt,
pcercuei 0:03b5121a232e 11744 (void *) ctxt->pushTab[ctxt->nameNr * 3 - 3],
pcercuei 0:03b5121a232e 11745 (void *) ctxt->pushTab[ctxt->nameNr * 3 - 2], 0,
pcercuei 0:03b5121a232e 11746 (int) (long) ctxt->pushTab[ctxt->nameNr * 3 - 1], 0);
pcercuei 0:03b5121a232e 11747 nameNsPop(ctxt);
pcercuei 0:03b5121a232e 11748 }
pcercuei 0:03b5121a232e 11749 #ifdef LIBXML_SAX1_ENABLED
pcercuei 0:03b5121a232e 11750 else
pcercuei 0:03b5121a232e 11751 xmlParseEndTag1(ctxt, 0);
pcercuei 0:03b5121a232e 11752 #endif /* LIBXML_SAX1_ENABLED */
pcercuei 0:03b5121a232e 11753 if (ctxt->instate == XML_PARSER_EOF) {
pcercuei 0:03b5121a232e 11754 /* Nothing */
pcercuei 0:03b5121a232e 11755 } else if (ctxt->nameNr == 0) {
pcercuei 0:03b5121a232e 11756 ctxt->instate = XML_PARSER_EPILOG;
pcercuei 0:03b5121a232e 11757 } else {
pcercuei 0:03b5121a232e 11758 ctxt->instate = XML_PARSER_CONTENT;
pcercuei 0:03b5121a232e 11759 }
pcercuei 0:03b5121a232e 11760 break;
pcercuei 0:03b5121a232e 11761 case XML_PARSER_CDATA_SECTION: {
pcercuei 0:03b5121a232e 11762 /*
pcercuei 0:03b5121a232e 11763 * The Push mode need to have the SAX callback for
pcercuei 0:03b5121a232e 11764 * cdataBlock merge back contiguous callbacks.
pcercuei 0:03b5121a232e 11765 */
pcercuei 0:03b5121a232e 11766 int base;
pcercuei 0:03b5121a232e 11767
pcercuei 0:03b5121a232e 11768 base = xmlParseLookupSequence(ctxt, ']', ']', '>');
pcercuei 0:03b5121a232e 11769 if (base < 0) {
pcercuei 0:03b5121a232e 11770 if (avail >= XML_PARSER_BIG_BUFFER_SIZE + 2) {
pcercuei 0:03b5121a232e 11771 int tmp;
pcercuei 0:03b5121a232e 11772
pcercuei 0:03b5121a232e 11773 tmp = xmlCheckCdataPush(ctxt->input->cur,
pcercuei 0:03b5121a232e 11774 XML_PARSER_BIG_BUFFER_SIZE);
pcercuei 0:03b5121a232e 11775 if (tmp < 0) {
pcercuei 0:03b5121a232e 11776 tmp = -tmp;
pcercuei 0:03b5121a232e 11777 ctxt->input->cur += tmp;
pcercuei 0:03b5121a232e 11778 goto encoding_error;
pcercuei 0:03b5121a232e 11779 }
pcercuei 0:03b5121a232e 11780 if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
pcercuei 0:03b5121a232e 11781 if (ctxt->sax->cdataBlock != NULL)
pcercuei 0:03b5121a232e 11782 ctxt->sax->cdataBlock(ctxt->userData,
pcercuei 0:03b5121a232e 11783 ctxt->input->cur, tmp);
pcercuei 0:03b5121a232e 11784 else if (ctxt->sax->characters != NULL)
pcercuei 0:03b5121a232e 11785 ctxt->sax->characters(ctxt->userData,
pcercuei 0:03b5121a232e 11786 ctxt->input->cur, tmp);
pcercuei 0:03b5121a232e 11787 }
pcercuei 0:03b5121a232e 11788 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 11789 goto done;
pcercuei 0:03b5121a232e 11790 SKIPL(tmp);
pcercuei 0:03b5121a232e 11791 ctxt->checkIndex = 0;
pcercuei 0:03b5121a232e 11792 }
pcercuei 0:03b5121a232e 11793 goto done;
pcercuei 0:03b5121a232e 11794 } else {
pcercuei 0:03b5121a232e 11795 int tmp;
pcercuei 0:03b5121a232e 11796
pcercuei 0:03b5121a232e 11797 tmp = xmlCheckCdataPush(ctxt->input->cur, base);
pcercuei 0:03b5121a232e 11798 if ((tmp < 0) || (tmp != base)) {
pcercuei 0:03b5121a232e 11799 tmp = -tmp;
pcercuei 0:03b5121a232e 11800 ctxt->input->cur += tmp;
pcercuei 0:03b5121a232e 11801 goto encoding_error;
pcercuei 0:03b5121a232e 11802 }
pcercuei 0:03b5121a232e 11803 if ((ctxt->sax != NULL) && (base == 0) &&
pcercuei 0:03b5121a232e 11804 (ctxt->sax->cdataBlock != NULL) &&
pcercuei 0:03b5121a232e 11805 (!ctxt->disableSAX)) {
pcercuei 0:03b5121a232e 11806 /*
pcercuei 0:03b5121a232e 11807 * Special case to provide identical behaviour
pcercuei 0:03b5121a232e 11808 * between pull and push parsers on enpty CDATA
pcercuei 0:03b5121a232e 11809 * sections
pcercuei 0:03b5121a232e 11810 */
pcercuei 0:03b5121a232e 11811 if ((ctxt->input->cur - ctxt->input->base >= 9) &&
pcercuei 0:03b5121a232e 11812 (!strncmp((const char *)&ctxt->input->cur[-9],
pcercuei 0:03b5121a232e 11813 "<![CDATA[", 9)))
pcercuei 0:03b5121a232e 11814 ctxt->sax->cdataBlock(ctxt->userData,
pcercuei 0:03b5121a232e 11815 BAD_CAST "", 0);
pcercuei 0:03b5121a232e 11816 } else if ((ctxt->sax != NULL) && (base > 0) &&
pcercuei 0:03b5121a232e 11817 (!ctxt->disableSAX)) {
pcercuei 0:03b5121a232e 11818 if (ctxt->sax->cdataBlock != NULL)
pcercuei 0:03b5121a232e 11819 ctxt->sax->cdataBlock(ctxt->userData,
pcercuei 0:03b5121a232e 11820 ctxt->input->cur, base);
pcercuei 0:03b5121a232e 11821 else if (ctxt->sax->characters != NULL)
pcercuei 0:03b5121a232e 11822 ctxt->sax->characters(ctxt->userData,
pcercuei 0:03b5121a232e 11823 ctxt->input->cur, base);
pcercuei 0:03b5121a232e 11824 }
pcercuei 0:03b5121a232e 11825 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 11826 goto done;
pcercuei 0:03b5121a232e 11827 SKIPL(base + 3);
pcercuei 0:03b5121a232e 11828 ctxt->checkIndex = 0;
pcercuei 0:03b5121a232e 11829 ctxt->instate = XML_PARSER_CONTENT;
pcercuei 0:03b5121a232e 11830 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 11831 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11832 "PP: entering CONTENT\n");
pcercuei 0:03b5121a232e 11833 #endif
pcercuei 0:03b5121a232e 11834 }
pcercuei 0:03b5121a232e 11835 break;
pcercuei 0:03b5121a232e 11836 }
pcercuei 0:03b5121a232e 11837 case XML_PARSER_MISC:
pcercuei 0:03b5121a232e 11838 SKIP_BLANKS;
pcercuei 0:03b5121a232e 11839 if (ctxt->input->buf == NULL)
pcercuei 0:03b5121a232e 11840 avail = ctxt->input->length -
pcercuei 0:03b5121a232e 11841 (ctxt->input->cur - ctxt->input->base);
pcercuei 0:03b5121a232e 11842 else
pcercuei 0:03b5121a232e 11843 avail = xmlBufUse(ctxt->input->buf->buffer) -
pcercuei 0:03b5121a232e 11844 (ctxt->input->cur - ctxt->input->base);
pcercuei 0:03b5121a232e 11845 if (avail < 2)
pcercuei 0:03b5121a232e 11846 goto done;
pcercuei 0:03b5121a232e 11847 cur = ctxt->input->cur[0];
pcercuei 0:03b5121a232e 11848 next = ctxt->input->cur[1];
pcercuei 0:03b5121a232e 11849 if ((cur == '<') && (next == '?')) {
pcercuei 0:03b5121a232e 11850 if ((!terminate) &&
pcercuei 0:03b5121a232e 11851 (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0)) {
pcercuei 0:03b5121a232e 11852 ctxt->progressive = XML_PARSER_PI;
pcercuei 0:03b5121a232e 11853 goto done;
pcercuei 0:03b5121a232e 11854 }
pcercuei 0:03b5121a232e 11855 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 11856 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11857 "PP: Parsing PI\n");
pcercuei 0:03b5121a232e 11858 #endif
pcercuei 0:03b5121a232e 11859 xmlParsePI(ctxt);
pcercuei 0:03b5121a232e 11860 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 11861 goto done;
pcercuei 0:03b5121a232e 11862 ctxt->instate = XML_PARSER_MISC;
pcercuei 0:03b5121a232e 11863 ctxt->progressive = 1;
pcercuei 0:03b5121a232e 11864 ctxt->checkIndex = 0;
pcercuei 0:03b5121a232e 11865 } else if ((cur == '<') && (next == '!') &&
pcercuei 0:03b5121a232e 11866 (ctxt->input->cur[2] == '-') &&
pcercuei 0:03b5121a232e 11867 (ctxt->input->cur[3] == '-')) {
pcercuei 0:03b5121a232e 11868 if ((!terminate) &&
pcercuei 0:03b5121a232e 11869 (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0)) {
pcercuei 0:03b5121a232e 11870 ctxt->progressive = XML_PARSER_COMMENT;
pcercuei 0:03b5121a232e 11871 goto done;
pcercuei 0:03b5121a232e 11872 }
pcercuei 0:03b5121a232e 11873 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 11874 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11875 "PP: Parsing Comment\n");
pcercuei 0:03b5121a232e 11876 #endif
pcercuei 0:03b5121a232e 11877 xmlParseComment(ctxt);
pcercuei 0:03b5121a232e 11878 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 11879 goto done;
pcercuei 0:03b5121a232e 11880 ctxt->instate = XML_PARSER_MISC;
pcercuei 0:03b5121a232e 11881 ctxt->progressive = 1;
pcercuei 0:03b5121a232e 11882 ctxt->checkIndex = 0;
pcercuei 0:03b5121a232e 11883 } else if ((cur == '<') && (next == '!') &&
pcercuei 0:03b5121a232e 11884 (ctxt->input->cur[2] == 'D') &&
pcercuei 0:03b5121a232e 11885 (ctxt->input->cur[3] == 'O') &&
pcercuei 0:03b5121a232e 11886 (ctxt->input->cur[4] == 'C') &&
pcercuei 0:03b5121a232e 11887 (ctxt->input->cur[5] == 'T') &&
pcercuei 0:03b5121a232e 11888 (ctxt->input->cur[6] == 'Y') &&
pcercuei 0:03b5121a232e 11889 (ctxt->input->cur[7] == 'P') &&
pcercuei 0:03b5121a232e 11890 (ctxt->input->cur[8] == 'E')) {
pcercuei 0:03b5121a232e 11891 if ((!terminate) &&
pcercuei 0:03b5121a232e 11892 (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0)) {
pcercuei 0:03b5121a232e 11893 ctxt->progressive = XML_PARSER_DTD;
pcercuei 0:03b5121a232e 11894 goto done;
pcercuei 0:03b5121a232e 11895 }
pcercuei 0:03b5121a232e 11896 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 11897 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11898 "PP: Parsing internal subset\n");
pcercuei 0:03b5121a232e 11899 #endif
pcercuei 0:03b5121a232e 11900 ctxt->inSubset = 1;
pcercuei 0:03b5121a232e 11901 ctxt->progressive = 0;
pcercuei 0:03b5121a232e 11902 ctxt->checkIndex = 0;
pcercuei 0:03b5121a232e 11903 xmlParseDocTypeDecl(ctxt);
pcercuei 0:03b5121a232e 11904 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 11905 goto done;
pcercuei 0:03b5121a232e 11906 if (RAW == '[') {
pcercuei 0:03b5121a232e 11907 ctxt->instate = XML_PARSER_DTD;
pcercuei 0:03b5121a232e 11908 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 11909 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11910 "PP: entering DTD\n");
pcercuei 0:03b5121a232e 11911 #endif
pcercuei 0:03b5121a232e 11912 } else {
pcercuei 0:03b5121a232e 11913 /*
pcercuei 0:03b5121a232e 11914 * Create and update the external subset.
pcercuei 0:03b5121a232e 11915 */
pcercuei 0:03b5121a232e 11916 ctxt->inSubset = 2;
pcercuei 0:03b5121a232e 11917 if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
pcercuei 0:03b5121a232e 11918 (ctxt->sax->externalSubset != NULL))
pcercuei 0:03b5121a232e 11919 ctxt->sax->externalSubset(ctxt->userData,
pcercuei 0:03b5121a232e 11920 ctxt->intSubName, ctxt->extSubSystem,
pcercuei 0:03b5121a232e 11921 ctxt->extSubURI);
pcercuei 0:03b5121a232e 11922 ctxt->inSubset = 0;
pcercuei 0:03b5121a232e 11923 xmlCleanSpecialAttr(ctxt);
pcercuei 0:03b5121a232e 11924 ctxt->instate = XML_PARSER_PROLOG;
pcercuei 0:03b5121a232e 11925 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 11926 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11927 "PP: entering PROLOG\n");
pcercuei 0:03b5121a232e 11928 #endif
pcercuei 0:03b5121a232e 11929 }
pcercuei 0:03b5121a232e 11930 } else if ((cur == '<') && (next == '!') &&
pcercuei 0:03b5121a232e 11931 (avail < 9)) {
pcercuei 0:03b5121a232e 11932 goto done;
pcercuei 0:03b5121a232e 11933 } else {
pcercuei 0:03b5121a232e 11934 ctxt->instate = XML_PARSER_START_TAG;
pcercuei 0:03b5121a232e 11935 ctxt->progressive = XML_PARSER_START_TAG;
pcercuei 0:03b5121a232e 11936 xmlParseGetLasts(ctxt, &lastlt, &lastgt);
pcercuei 0:03b5121a232e 11937 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 11938 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11939 "PP: entering START_TAG\n");
pcercuei 0:03b5121a232e 11940 #endif
pcercuei 0:03b5121a232e 11941 }
pcercuei 0:03b5121a232e 11942 break;
pcercuei 0:03b5121a232e 11943 case XML_PARSER_PROLOG:
pcercuei 0:03b5121a232e 11944 SKIP_BLANKS;
pcercuei 0:03b5121a232e 11945 if (ctxt->input->buf == NULL)
pcercuei 0:03b5121a232e 11946 avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
pcercuei 0:03b5121a232e 11947 else
pcercuei 0:03b5121a232e 11948 avail = xmlBufUse(ctxt->input->buf->buffer) -
pcercuei 0:03b5121a232e 11949 (ctxt->input->cur - ctxt->input->base);
pcercuei 0:03b5121a232e 11950 if (avail < 2)
pcercuei 0:03b5121a232e 11951 goto done;
pcercuei 0:03b5121a232e 11952 cur = ctxt->input->cur[0];
pcercuei 0:03b5121a232e 11953 next = ctxt->input->cur[1];
pcercuei 0:03b5121a232e 11954 if ((cur == '<') && (next == '?')) {
pcercuei 0:03b5121a232e 11955 if ((!terminate) &&
pcercuei 0:03b5121a232e 11956 (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0)) {
pcercuei 0:03b5121a232e 11957 ctxt->progressive = XML_PARSER_PI;
pcercuei 0:03b5121a232e 11958 goto done;
pcercuei 0:03b5121a232e 11959 }
pcercuei 0:03b5121a232e 11960 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 11961 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11962 "PP: Parsing PI\n");
pcercuei 0:03b5121a232e 11963 #endif
pcercuei 0:03b5121a232e 11964 xmlParsePI(ctxt);
pcercuei 0:03b5121a232e 11965 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 11966 goto done;
pcercuei 0:03b5121a232e 11967 ctxt->instate = XML_PARSER_PROLOG;
pcercuei 0:03b5121a232e 11968 ctxt->progressive = 1;
pcercuei 0:03b5121a232e 11969 } else if ((cur == '<') && (next == '!') &&
pcercuei 0:03b5121a232e 11970 (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
pcercuei 0:03b5121a232e 11971 if ((!terminate) &&
pcercuei 0:03b5121a232e 11972 (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0)) {
pcercuei 0:03b5121a232e 11973 ctxt->progressive = XML_PARSER_COMMENT;
pcercuei 0:03b5121a232e 11974 goto done;
pcercuei 0:03b5121a232e 11975 }
pcercuei 0:03b5121a232e 11976 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 11977 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11978 "PP: Parsing Comment\n");
pcercuei 0:03b5121a232e 11979 #endif
pcercuei 0:03b5121a232e 11980 xmlParseComment(ctxt);
pcercuei 0:03b5121a232e 11981 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 11982 goto done;
pcercuei 0:03b5121a232e 11983 ctxt->instate = XML_PARSER_PROLOG;
pcercuei 0:03b5121a232e 11984 ctxt->progressive = 1;
pcercuei 0:03b5121a232e 11985 } else if ((cur == '<') && (next == '!') &&
pcercuei 0:03b5121a232e 11986 (avail < 4)) {
pcercuei 0:03b5121a232e 11987 goto done;
pcercuei 0:03b5121a232e 11988 } else {
pcercuei 0:03b5121a232e 11989 ctxt->instate = XML_PARSER_START_TAG;
pcercuei 0:03b5121a232e 11990 if (ctxt->progressive == 0)
pcercuei 0:03b5121a232e 11991 ctxt->progressive = XML_PARSER_START_TAG;
pcercuei 0:03b5121a232e 11992 xmlParseGetLasts(ctxt, &lastlt, &lastgt);
pcercuei 0:03b5121a232e 11993 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 11994 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 11995 "PP: entering START_TAG\n");
pcercuei 0:03b5121a232e 11996 #endif
pcercuei 0:03b5121a232e 11997 }
pcercuei 0:03b5121a232e 11998 break;
pcercuei 0:03b5121a232e 11999 case XML_PARSER_EPILOG:
pcercuei 0:03b5121a232e 12000 SKIP_BLANKS;
pcercuei 0:03b5121a232e 12001 if (ctxt->input->buf == NULL)
pcercuei 0:03b5121a232e 12002 avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
pcercuei 0:03b5121a232e 12003 else
pcercuei 0:03b5121a232e 12004 avail = xmlBufUse(ctxt->input->buf->buffer) -
pcercuei 0:03b5121a232e 12005 (ctxt->input->cur - ctxt->input->base);
pcercuei 0:03b5121a232e 12006 if (avail < 2)
pcercuei 0:03b5121a232e 12007 goto done;
pcercuei 0:03b5121a232e 12008 cur = ctxt->input->cur[0];
pcercuei 0:03b5121a232e 12009 next = ctxt->input->cur[1];
pcercuei 0:03b5121a232e 12010 if ((cur == '<') && (next == '?')) {
pcercuei 0:03b5121a232e 12011 if ((!terminate) &&
pcercuei 0:03b5121a232e 12012 (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0)) {
pcercuei 0:03b5121a232e 12013 ctxt->progressive = XML_PARSER_PI;
pcercuei 0:03b5121a232e 12014 goto done;
pcercuei 0:03b5121a232e 12015 }
pcercuei 0:03b5121a232e 12016 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 12017 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 12018 "PP: Parsing PI\n");
pcercuei 0:03b5121a232e 12019 #endif
pcercuei 0:03b5121a232e 12020 xmlParsePI(ctxt);
pcercuei 0:03b5121a232e 12021 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 12022 goto done;
pcercuei 0:03b5121a232e 12023 ctxt->instate = XML_PARSER_EPILOG;
pcercuei 0:03b5121a232e 12024 ctxt->progressive = 1;
pcercuei 0:03b5121a232e 12025 } else if ((cur == '<') && (next == '!') &&
pcercuei 0:03b5121a232e 12026 (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
pcercuei 0:03b5121a232e 12027 if ((!terminate) &&
pcercuei 0:03b5121a232e 12028 (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0)) {
pcercuei 0:03b5121a232e 12029 ctxt->progressive = XML_PARSER_COMMENT;
pcercuei 0:03b5121a232e 12030 goto done;
pcercuei 0:03b5121a232e 12031 }
pcercuei 0:03b5121a232e 12032 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 12033 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 12034 "PP: Parsing Comment\n");
pcercuei 0:03b5121a232e 12035 #endif
pcercuei 0:03b5121a232e 12036 xmlParseComment(ctxt);
pcercuei 0:03b5121a232e 12037 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 12038 goto done;
pcercuei 0:03b5121a232e 12039 ctxt->instate = XML_PARSER_EPILOG;
pcercuei 0:03b5121a232e 12040 ctxt->progressive = 1;
pcercuei 0:03b5121a232e 12041 } else if ((cur == '<') && (next == '!') &&
pcercuei 0:03b5121a232e 12042 (avail < 4)) {
pcercuei 0:03b5121a232e 12043 goto done;
pcercuei 0:03b5121a232e 12044 } else {
pcercuei 0:03b5121a232e 12045 xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
pcercuei 0:03b5121a232e 12046 xmlHaltParser(ctxt);
pcercuei 0:03b5121a232e 12047 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 12048 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 12049 "PP: entering EOF\n");
pcercuei 0:03b5121a232e 12050 #endif
pcercuei 0:03b5121a232e 12051 if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
pcercuei 0:03b5121a232e 12052 ctxt->sax->endDocument(ctxt->userData);
pcercuei 0:03b5121a232e 12053 goto done;
pcercuei 0:03b5121a232e 12054 }
pcercuei 0:03b5121a232e 12055 break;
pcercuei 0:03b5121a232e 12056 case XML_PARSER_DTD: {
pcercuei 0:03b5121a232e 12057 /*
pcercuei 0:03b5121a232e 12058 * Sorry but progressive parsing of the internal subset
pcercuei 0:03b5121a232e 12059 * is not expected to be supported. We first check that
pcercuei 0:03b5121a232e 12060 * the full content of the internal subset is available and
pcercuei 0:03b5121a232e 12061 * the parsing is launched only at that point.
pcercuei 0:03b5121a232e 12062 * Internal subset ends up with "']' S? '>'" in an unescaped
pcercuei 0:03b5121a232e 12063 * section and not in a ']]>' sequence which are conditional
pcercuei 0:03b5121a232e 12064 * sections (whoever argued to keep that crap in XML deserve
pcercuei 0:03b5121a232e 12065 * a place in hell !).
pcercuei 0:03b5121a232e 12066 */
pcercuei 0:03b5121a232e 12067 int base, i;
pcercuei 0:03b5121a232e 12068 xmlChar *buf;
pcercuei 0:03b5121a232e 12069 xmlChar quote = 0;
pcercuei 0:03b5121a232e 12070 size_t use;
pcercuei 0:03b5121a232e 12071
pcercuei 0:03b5121a232e 12072 base = ctxt->input->cur - ctxt->input->base;
pcercuei 0:03b5121a232e 12073 if (base < 0) return(0);
pcercuei 0:03b5121a232e 12074 if (ctxt->checkIndex > base)
pcercuei 0:03b5121a232e 12075 base = ctxt->checkIndex;
pcercuei 0:03b5121a232e 12076 buf = xmlBufContent(ctxt->input->buf->buffer);
pcercuei 0:03b5121a232e 12077 use = xmlBufUse(ctxt->input->buf->buffer);
pcercuei 0:03b5121a232e 12078 for (;(unsigned int) base < use; base++) {
pcercuei 0:03b5121a232e 12079 if (quote != 0) {
pcercuei 0:03b5121a232e 12080 if (buf[base] == quote)
pcercuei 0:03b5121a232e 12081 quote = 0;
pcercuei 0:03b5121a232e 12082 continue;
pcercuei 0:03b5121a232e 12083 }
pcercuei 0:03b5121a232e 12084 if ((quote == 0) && (buf[base] == '<')) {
pcercuei 0:03b5121a232e 12085 int found = 0;
pcercuei 0:03b5121a232e 12086 /* special handling of comments */
pcercuei 0:03b5121a232e 12087 if (((unsigned int) base + 4 < use) &&
pcercuei 0:03b5121a232e 12088 (buf[base + 1] == '!') &&
pcercuei 0:03b5121a232e 12089 (buf[base + 2] == '-') &&
pcercuei 0:03b5121a232e 12090 (buf[base + 3] == '-')) {
pcercuei 0:03b5121a232e 12091 for (;(unsigned int) base + 3 < use; base++) {
pcercuei 0:03b5121a232e 12092 if ((buf[base] == '-') &&
pcercuei 0:03b5121a232e 12093 (buf[base + 1] == '-') &&
pcercuei 0:03b5121a232e 12094 (buf[base + 2] == '>')) {
pcercuei 0:03b5121a232e 12095 found = 1;
pcercuei 0:03b5121a232e 12096 base += 2;
pcercuei 0:03b5121a232e 12097 break;
pcercuei 0:03b5121a232e 12098 }
pcercuei 0:03b5121a232e 12099 }
pcercuei 0:03b5121a232e 12100 if (!found) {
pcercuei 0:03b5121a232e 12101 #if 0
pcercuei 0:03b5121a232e 12102 fprintf(stderr, "unfinished comment\n");
pcercuei 0:03b5121a232e 12103 #endif
pcercuei 0:03b5121a232e 12104 break; /* for */
pcercuei 0:03b5121a232e 12105 }
pcercuei 0:03b5121a232e 12106 continue;
pcercuei 0:03b5121a232e 12107 }
pcercuei 0:03b5121a232e 12108 }
pcercuei 0:03b5121a232e 12109 if (buf[base] == '"') {
pcercuei 0:03b5121a232e 12110 quote = '"';
pcercuei 0:03b5121a232e 12111 continue;
pcercuei 0:03b5121a232e 12112 }
pcercuei 0:03b5121a232e 12113 if (buf[base] == '\'') {
pcercuei 0:03b5121a232e 12114 quote = '\'';
pcercuei 0:03b5121a232e 12115 continue;
pcercuei 0:03b5121a232e 12116 }
pcercuei 0:03b5121a232e 12117 if (buf[base] == ']') {
pcercuei 0:03b5121a232e 12118 #if 0
pcercuei 0:03b5121a232e 12119 fprintf(stderr, "%c%c%c%c: ", buf[base],
pcercuei 0:03b5121a232e 12120 buf[base + 1], buf[base + 2], buf[base + 3]);
pcercuei 0:03b5121a232e 12121 #endif
pcercuei 0:03b5121a232e 12122 if ((unsigned int) base +1 >= use)
pcercuei 0:03b5121a232e 12123 break;
pcercuei 0:03b5121a232e 12124 if (buf[base + 1] == ']') {
pcercuei 0:03b5121a232e 12125 /* conditional crap, skip both ']' ! */
pcercuei 0:03b5121a232e 12126 base++;
pcercuei 0:03b5121a232e 12127 continue;
pcercuei 0:03b5121a232e 12128 }
pcercuei 0:03b5121a232e 12129 for (i = 1; (unsigned int) base + i < use; i++) {
pcercuei 0:03b5121a232e 12130 if (buf[base + i] == '>') {
pcercuei 0:03b5121a232e 12131 #if 0
pcercuei 0:03b5121a232e 12132 fprintf(stderr, "found\n");
pcercuei 0:03b5121a232e 12133 #endif
pcercuei 0:03b5121a232e 12134 goto found_end_int_subset;
pcercuei 0:03b5121a232e 12135 }
pcercuei 0:03b5121a232e 12136 if (!IS_BLANK_CH(buf[base + i])) {
pcercuei 0:03b5121a232e 12137 #if 0
pcercuei 0:03b5121a232e 12138 fprintf(stderr, "not found\n");
pcercuei 0:03b5121a232e 12139 #endif
pcercuei 0:03b5121a232e 12140 goto not_end_of_int_subset;
pcercuei 0:03b5121a232e 12141 }
pcercuei 0:03b5121a232e 12142 }
pcercuei 0:03b5121a232e 12143 #if 0
pcercuei 0:03b5121a232e 12144 fprintf(stderr, "end of stream\n");
pcercuei 0:03b5121a232e 12145 #endif
pcercuei 0:03b5121a232e 12146 break;
pcercuei 0:03b5121a232e 12147
pcercuei 0:03b5121a232e 12148 }
pcercuei 0:03b5121a232e 12149 not_end_of_int_subset:
pcercuei 0:03b5121a232e 12150 continue; /* for */
pcercuei 0:03b5121a232e 12151 }
pcercuei 0:03b5121a232e 12152 /*
pcercuei 0:03b5121a232e 12153 * We didn't found the end of the Internal subset
pcercuei 0:03b5121a232e 12154 */
pcercuei 0:03b5121a232e 12155 if (quote == 0)
pcercuei 0:03b5121a232e 12156 ctxt->checkIndex = base;
pcercuei 0:03b5121a232e 12157 else
pcercuei 0:03b5121a232e 12158 ctxt->checkIndex = 0;
pcercuei 0:03b5121a232e 12159 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 12160 if (next == 0)
pcercuei 0:03b5121a232e 12161 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 12162 "PP: lookup of int subset end filed\n");
pcercuei 0:03b5121a232e 12163 #endif
pcercuei 0:03b5121a232e 12164 goto done;
pcercuei 0:03b5121a232e 12165
pcercuei 0:03b5121a232e 12166 found_end_int_subset:
pcercuei 0:03b5121a232e 12167 ctxt->checkIndex = 0;
pcercuei 0:03b5121a232e 12168 xmlParseInternalSubset(ctxt);
pcercuei 0:03b5121a232e 12169 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 12170 goto done;
pcercuei 0:03b5121a232e 12171 ctxt->inSubset = 2;
pcercuei 0:03b5121a232e 12172 if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
pcercuei 0:03b5121a232e 12173 (ctxt->sax->externalSubset != NULL))
pcercuei 0:03b5121a232e 12174 ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
pcercuei 0:03b5121a232e 12175 ctxt->extSubSystem, ctxt->extSubURI);
pcercuei 0:03b5121a232e 12176 ctxt->inSubset = 0;
pcercuei 0:03b5121a232e 12177 xmlCleanSpecialAttr(ctxt);
pcercuei 0:03b5121a232e 12178 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 12179 goto done;
pcercuei 0:03b5121a232e 12180 ctxt->instate = XML_PARSER_PROLOG;
pcercuei 0:03b5121a232e 12181 ctxt->checkIndex = 0;
pcercuei 0:03b5121a232e 12182 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 12183 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 12184 "PP: entering PROLOG\n");
pcercuei 0:03b5121a232e 12185 #endif
pcercuei 0:03b5121a232e 12186 break;
pcercuei 0:03b5121a232e 12187 }
pcercuei 0:03b5121a232e 12188 case XML_PARSER_COMMENT:
pcercuei 0:03b5121a232e 12189 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 12190 "PP: internal error, state == COMMENT\n");
pcercuei 0:03b5121a232e 12191 ctxt->instate = XML_PARSER_CONTENT;
pcercuei 0:03b5121a232e 12192 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 12193 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 12194 "PP: entering CONTENT\n");
pcercuei 0:03b5121a232e 12195 #endif
pcercuei 0:03b5121a232e 12196 break;
pcercuei 0:03b5121a232e 12197 case XML_PARSER_IGNORE:
pcercuei 0:03b5121a232e 12198 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 12199 "PP: internal error, state == IGNORE");
pcercuei 0:03b5121a232e 12200 ctxt->instate = XML_PARSER_DTD;
pcercuei 0:03b5121a232e 12201 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 12202 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 12203 "PP: entering DTD\n");
pcercuei 0:03b5121a232e 12204 #endif
pcercuei 0:03b5121a232e 12205 break;
pcercuei 0:03b5121a232e 12206 case XML_PARSER_PI:
pcercuei 0:03b5121a232e 12207 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 12208 "PP: internal error, state == PI\n");
pcercuei 0:03b5121a232e 12209 ctxt->instate = XML_PARSER_CONTENT;
pcercuei 0:03b5121a232e 12210 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 12211 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 12212 "PP: entering CONTENT\n");
pcercuei 0:03b5121a232e 12213 #endif
pcercuei 0:03b5121a232e 12214 break;
pcercuei 0:03b5121a232e 12215 case XML_PARSER_ENTITY_DECL:
pcercuei 0:03b5121a232e 12216 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 12217 "PP: internal error, state == ENTITY_DECL\n");
pcercuei 0:03b5121a232e 12218 ctxt->instate = XML_PARSER_DTD;
pcercuei 0:03b5121a232e 12219 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 12220 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 12221 "PP: entering DTD\n");
pcercuei 0:03b5121a232e 12222 #endif
pcercuei 0:03b5121a232e 12223 break;
pcercuei 0:03b5121a232e 12224 case XML_PARSER_ENTITY_VALUE:
pcercuei 0:03b5121a232e 12225 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 12226 "PP: internal error, state == ENTITY_VALUE\n");
pcercuei 0:03b5121a232e 12227 ctxt->instate = XML_PARSER_CONTENT;
pcercuei 0:03b5121a232e 12228 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 12229 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 12230 "PP: entering DTD\n");
pcercuei 0:03b5121a232e 12231 #endif
pcercuei 0:03b5121a232e 12232 break;
pcercuei 0:03b5121a232e 12233 case XML_PARSER_ATTRIBUTE_VALUE:
pcercuei 0:03b5121a232e 12234 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 12235 "PP: internal error, state == ATTRIBUTE_VALUE\n");
pcercuei 0:03b5121a232e 12236 ctxt->instate = XML_PARSER_START_TAG;
pcercuei 0:03b5121a232e 12237 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 12238 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 12239 "PP: entering START_TAG\n");
pcercuei 0:03b5121a232e 12240 #endif
pcercuei 0:03b5121a232e 12241 break;
pcercuei 0:03b5121a232e 12242 case XML_PARSER_SYSTEM_LITERAL:
pcercuei 0:03b5121a232e 12243 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 12244 "PP: internal error, state == SYSTEM_LITERAL\n");
pcercuei 0:03b5121a232e 12245 ctxt->instate = XML_PARSER_START_TAG;
pcercuei 0:03b5121a232e 12246 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 12247 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 12248 "PP: entering START_TAG\n");
pcercuei 0:03b5121a232e 12249 #endif
pcercuei 0:03b5121a232e 12250 break;
pcercuei 0:03b5121a232e 12251 case XML_PARSER_PUBLIC_LITERAL:
pcercuei 0:03b5121a232e 12252 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 12253 "PP: internal error, state == PUBLIC_LITERAL\n");
pcercuei 0:03b5121a232e 12254 ctxt->instate = XML_PARSER_START_TAG;
pcercuei 0:03b5121a232e 12255 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 12256 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 12257 "PP: entering START_TAG\n");
pcercuei 0:03b5121a232e 12258 #endif
pcercuei 0:03b5121a232e 12259 break;
pcercuei 0:03b5121a232e 12260 }
pcercuei 0:03b5121a232e 12261 }
pcercuei 0:03b5121a232e 12262 done:
pcercuei 0:03b5121a232e 12263 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 12264 xmlGenericError(xmlGenericErrorContext, "PP: done %d\n", ret);
pcercuei 0:03b5121a232e 12265 #endif
pcercuei 0:03b5121a232e 12266 return(ret);
pcercuei 0:03b5121a232e 12267 encoding_error:
pcercuei 0:03b5121a232e 12268 {
pcercuei 0:03b5121a232e 12269 char buffer[150];
pcercuei 0:03b5121a232e 12270
pcercuei 0:03b5121a232e 12271 snprintf(buffer, 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
pcercuei 0:03b5121a232e 12272 ctxt->input->cur[0], ctxt->input->cur[1],
pcercuei 0:03b5121a232e 12273 ctxt->input->cur[2], ctxt->input->cur[3]);
pcercuei 0:03b5121a232e 12274 __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
pcercuei 0:03b5121a232e 12275 "Input is not proper UTF-8, indicate encoding !\n%s",
pcercuei 0:03b5121a232e 12276 BAD_CAST buffer, NULL);
pcercuei 0:03b5121a232e 12277 }
pcercuei 0:03b5121a232e 12278 return(0);
pcercuei 0:03b5121a232e 12279 }
pcercuei 0:03b5121a232e 12280
pcercuei 0:03b5121a232e 12281 /**
pcercuei 0:03b5121a232e 12282 * xmlParseCheckTransition:
pcercuei 0:03b5121a232e 12283 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 12284 * @chunk: a char array
pcercuei 0:03b5121a232e 12285 * @size: the size in byte of the chunk
pcercuei 0:03b5121a232e 12286 *
pcercuei 0:03b5121a232e 12287 * Check depending on the current parser state if the chunk given must be
pcercuei 0:03b5121a232e 12288 * processed immediately or one need more data to advance on parsing.
pcercuei 0:03b5121a232e 12289 *
pcercuei 0:03b5121a232e 12290 * Returns -1 in case of error, 0 if the push is not needed and 1 if needed
pcercuei 0:03b5121a232e 12291 */
pcercuei 0:03b5121a232e 12292 static int
pcercuei 0:03b5121a232e 12293 xmlParseCheckTransition(xmlParserCtxtPtr ctxt, const char *chunk, int size) {
pcercuei 0:03b5121a232e 12294 if ((ctxt == NULL) || (chunk == NULL) || (size < 0))
pcercuei 0:03b5121a232e 12295 return(-1);
pcercuei 0:03b5121a232e 12296 if (ctxt->instate == XML_PARSER_START_TAG) {
pcercuei 0:03b5121a232e 12297 if (memchr(chunk, '>', size) != NULL)
pcercuei 0:03b5121a232e 12298 return(1);
pcercuei 0:03b5121a232e 12299 return(0);
pcercuei 0:03b5121a232e 12300 }
pcercuei 0:03b5121a232e 12301 if (ctxt->progressive == XML_PARSER_COMMENT) {
pcercuei 0:03b5121a232e 12302 if (memchr(chunk, '>', size) != NULL)
pcercuei 0:03b5121a232e 12303 return(1);
pcercuei 0:03b5121a232e 12304 return(0);
pcercuei 0:03b5121a232e 12305 }
pcercuei 0:03b5121a232e 12306 if (ctxt->instate == XML_PARSER_CDATA_SECTION) {
pcercuei 0:03b5121a232e 12307 if (memchr(chunk, '>', size) != NULL)
pcercuei 0:03b5121a232e 12308 return(1);
pcercuei 0:03b5121a232e 12309 return(0);
pcercuei 0:03b5121a232e 12310 }
pcercuei 0:03b5121a232e 12311 if (ctxt->progressive == XML_PARSER_PI) {
pcercuei 0:03b5121a232e 12312 if (memchr(chunk, '>', size) != NULL)
pcercuei 0:03b5121a232e 12313 return(1);
pcercuei 0:03b5121a232e 12314 return(0);
pcercuei 0:03b5121a232e 12315 }
pcercuei 0:03b5121a232e 12316 if (ctxt->instate == XML_PARSER_END_TAG) {
pcercuei 0:03b5121a232e 12317 if (memchr(chunk, '>', size) != NULL)
pcercuei 0:03b5121a232e 12318 return(1);
pcercuei 0:03b5121a232e 12319 return(0);
pcercuei 0:03b5121a232e 12320 }
pcercuei 0:03b5121a232e 12321 if ((ctxt->progressive == XML_PARSER_DTD) ||
pcercuei 0:03b5121a232e 12322 (ctxt->instate == XML_PARSER_DTD)) {
pcercuei 0:03b5121a232e 12323 if (memchr(chunk, '>', size) != NULL)
pcercuei 0:03b5121a232e 12324 return(1);
pcercuei 0:03b5121a232e 12325 return(0);
pcercuei 0:03b5121a232e 12326 }
pcercuei 0:03b5121a232e 12327 return(1);
pcercuei 0:03b5121a232e 12328 }
pcercuei 0:03b5121a232e 12329
pcercuei 0:03b5121a232e 12330 /**
pcercuei 0:03b5121a232e 12331 * xmlParseChunk:
pcercuei 0:03b5121a232e 12332 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 12333 * @chunk: an char array
pcercuei 0:03b5121a232e 12334 * @size: the size in byte of the chunk
pcercuei 0:03b5121a232e 12335 * @terminate: last chunk indicator
pcercuei 0:03b5121a232e 12336 *
pcercuei 0:03b5121a232e 12337 * Parse a Chunk of memory
pcercuei 0:03b5121a232e 12338 *
pcercuei 0:03b5121a232e 12339 * Returns zero if no error, the xmlParserErrors otherwise.
pcercuei 0:03b5121a232e 12340 */
pcercuei 0:03b5121a232e 12341 int
pcercuei 0:03b5121a232e 12342 xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
pcercuei 0:03b5121a232e 12343 int terminate) {
pcercuei 0:03b5121a232e 12344 int end_in_lf = 0;
pcercuei 0:03b5121a232e 12345 int remain = 0;
pcercuei 0:03b5121a232e 12346 size_t old_avail = 0;
pcercuei 0:03b5121a232e 12347 size_t avail = 0;
pcercuei 0:03b5121a232e 12348
pcercuei 0:03b5121a232e 12349 if (ctxt == NULL)
pcercuei 0:03b5121a232e 12350 return(XML_ERR_INTERNAL_ERROR);
pcercuei 0:03b5121a232e 12351 if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
pcercuei 0:03b5121a232e 12352 return(ctxt->errNo);
pcercuei 0:03b5121a232e 12353 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 12354 return(-1);
pcercuei 0:03b5121a232e 12355 if (ctxt->instate == XML_PARSER_START)
pcercuei 0:03b5121a232e 12356 xmlDetectSAX2(ctxt);
pcercuei 0:03b5121a232e 12357 if ((size > 0) && (chunk != NULL) && (!terminate) &&
pcercuei 0:03b5121a232e 12358 (chunk[size - 1] == '\r')) {
pcercuei 0:03b5121a232e 12359 end_in_lf = 1;
pcercuei 0:03b5121a232e 12360 size--;
pcercuei 0:03b5121a232e 12361 }
pcercuei 0:03b5121a232e 12362
pcercuei 0:03b5121a232e 12363 xmldecl_done:
pcercuei 0:03b5121a232e 12364
pcercuei 0:03b5121a232e 12365 if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
pcercuei 0:03b5121a232e 12366 (ctxt->input->buf != NULL) && (ctxt->instate != XML_PARSER_EOF)) {
pcercuei 0:03b5121a232e 12367 size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer, ctxt->input);
pcercuei 0:03b5121a232e 12368 size_t cur = ctxt->input->cur - ctxt->input->base;
pcercuei 0:03b5121a232e 12369 int res;
pcercuei 0:03b5121a232e 12370
pcercuei 0:03b5121a232e 12371 old_avail = xmlBufUse(ctxt->input->buf->buffer);
pcercuei 0:03b5121a232e 12372 /*
pcercuei 0:03b5121a232e 12373 * Specific handling if we autodetected an encoding, we should not
pcercuei 0:03b5121a232e 12374 * push more than the first line ... which depend on the encoding
pcercuei 0:03b5121a232e 12375 * And only push the rest once the final encoding was detected
pcercuei 0:03b5121a232e 12376 */
pcercuei 0:03b5121a232e 12377 if ((ctxt->instate == XML_PARSER_START) && (ctxt->input != NULL) &&
pcercuei 0:03b5121a232e 12378 (ctxt->input->buf != NULL) && (ctxt->input->buf->encoder != NULL)) {
pcercuei 0:03b5121a232e 12379 unsigned int len = 45;
pcercuei 0:03b5121a232e 12380
pcercuei 0:03b5121a232e 12381 if ((xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
pcercuei 0:03b5121a232e 12382 BAD_CAST "UTF-16")) ||
pcercuei 0:03b5121a232e 12383 (xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
pcercuei 0:03b5121a232e 12384 BAD_CAST "UTF16")))
pcercuei 0:03b5121a232e 12385 len = 90;
pcercuei 0:03b5121a232e 12386 else if ((xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
pcercuei 0:03b5121a232e 12387 BAD_CAST "UCS-4")) ||
pcercuei 0:03b5121a232e 12388 (xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
pcercuei 0:03b5121a232e 12389 BAD_CAST "UCS4")))
pcercuei 0:03b5121a232e 12390 len = 180;
pcercuei 0:03b5121a232e 12391
pcercuei 0:03b5121a232e 12392 if (ctxt->input->buf->rawconsumed < len)
pcercuei 0:03b5121a232e 12393 len -= ctxt->input->buf->rawconsumed;
pcercuei 0:03b5121a232e 12394
pcercuei 0:03b5121a232e 12395 /*
pcercuei 0:03b5121a232e 12396 * Change size for reading the initial declaration only
pcercuei 0:03b5121a232e 12397 * if size is greater than len. Otherwise, memmove in xmlBufferAdd
pcercuei 0:03b5121a232e 12398 * will blindly copy extra bytes from memory.
pcercuei 0:03b5121a232e 12399 */
pcercuei 0:03b5121a232e 12400 if ((unsigned int) size > len) {
pcercuei 0:03b5121a232e 12401 remain = size - len;
pcercuei 0:03b5121a232e 12402 size = len;
pcercuei 0:03b5121a232e 12403 } else {
pcercuei 0:03b5121a232e 12404 remain = 0;
pcercuei 0:03b5121a232e 12405 }
pcercuei 0:03b5121a232e 12406 }
pcercuei 0:03b5121a232e 12407 res = xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
pcercuei 0:03b5121a232e 12408 if (res < 0) {
pcercuei 0:03b5121a232e 12409 ctxt->errNo = XML_PARSER_EOF;
pcercuei 0:03b5121a232e 12410 xmlHaltParser(ctxt);
pcercuei 0:03b5121a232e 12411 return (XML_PARSER_EOF);
pcercuei 0:03b5121a232e 12412 }
pcercuei 0:03b5121a232e 12413 xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur);
pcercuei 0:03b5121a232e 12414 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 12415 xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
pcercuei 0:03b5121a232e 12416 #endif
pcercuei 0:03b5121a232e 12417
pcercuei 0:03b5121a232e 12418 } else if (ctxt->instate != XML_PARSER_EOF) {
pcercuei 0:03b5121a232e 12419 if ((ctxt->input != NULL) && ctxt->input->buf != NULL) {
pcercuei 0:03b5121a232e 12420 xmlParserInputBufferPtr in = ctxt->input->buf;
pcercuei 0:03b5121a232e 12421 if ((in->encoder != NULL) && (in->buffer != NULL) &&
pcercuei 0:03b5121a232e 12422 (in->raw != NULL)) {
pcercuei 0:03b5121a232e 12423 int nbchars;
pcercuei 0:03b5121a232e 12424 size_t base = xmlBufGetInputBase(in->buffer, ctxt->input);
pcercuei 0:03b5121a232e 12425 size_t current = ctxt->input->cur - ctxt->input->base;
pcercuei 0:03b5121a232e 12426
pcercuei 0:03b5121a232e 12427 nbchars = xmlCharEncInput(in, terminate);
pcercuei 0:03b5121a232e 12428 if (nbchars < 0) {
pcercuei 0:03b5121a232e 12429 /* TODO 2.6.0 */
pcercuei 0:03b5121a232e 12430 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 12431 "xmlParseChunk: encoder error\n");
pcercuei 0:03b5121a232e 12432 return(XML_ERR_INVALID_ENCODING);
pcercuei 0:03b5121a232e 12433 }
pcercuei 0:03b5121a232e 12434 xmlBufSetInputBaseCur(in->buffer, ctxt->input, base, current);
pcercuei 0:03b5121a232e 12435 }
pcercuei 0:03b5121a232e 12436 }
pcercuei 0:03b5121a232e 12437 }
pcercuei 0:03b5121a232e 12438 if (remain != 0) {
pcercuei 0:03b5121a232e 12439 xmlParseTryOrFinish(ctxt, 0);
pcercuei 0:03b5121a232e 12440 } else {
pcercuei 0:03b5121a232e 12441 if ((ctxt->input != NULL) && (ctxt->input->buf != NULL))
pcercuei 0:03b5121a232e 12442 avail = xmlBufUse(ctxt->input->buf->buffer);
pcercuei 0:03b5121a232e 12443 /*
pcercuei 0:03b5121a232e 12444 * Depending on the current state it may not be such
pcercuei 0:03b5121a232e 12445 * a good idea to try parsing if there is nothing in the chunk
pcercuei 0:03b5121a232e 12446 * which would be worth doing a parser state transition and we
pcercuei 0:03b5121a232e 12447 * need to wait for more data
pcercuei 0:03b5121a232e 12448 */
pcercuei 0:03b5121a232e 12449 if ((terminate) || (avail > XML_MAX_TEXT_LENGTH) ||
pcercuei 0:03b5121a232e 12450 (old_avail == 0) || (avail == 0) ||
pcercuei 0:03b5121a232e 12451 (xmlParseCheckTransition(ctxt,
pcercuei 0:03b5121a232e 12452 (const char *)&ctxt->input->base[old_avail],
pcercuei 0:03b5121a232e 12453 avail - old_avail)))
pcercuei 0:03b5121a232e 12454 xmlParseTryOrFinish(ctxt, terminate);
pcercuei 0:03b5121a232e 12455 }
pcercuei 0:03b5121a232e 12456 if (ctxt->instate == XML_PARSER_EOF)
pcercuei 0:03b5121a232e 12457 return(ctxt->errNo);
pcercuei 0:03b5121a232e 12458
pcercuei 0:03b5121a232e 12459 if ((ctxt->input != NULL) &&
pcercuei 0:03b5121a232e 12460 (((ctxt->input->end - ctxt->input->cur) > XML_MAX_LOOKUP_LIMIT) ||
pcercuei 0:03b5121a232e 12461 ((ctxt->input->cur - ctxt->input->base) > XML_MAX_LOOKUP_LIMIT)) &&
pcercuei 0:03b5121a232e 12462 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
pcercuei 0:03b5121a232e 12463 xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "Huge input lookup");
pcercuei 0:03b5121a232e 12464 xmlHaltParser(ctxt);
pcercuei 0:03b5121a232e 12465 }
pcercuei 0:03b5121a232e 12466 if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
pcercuei 0:03b5121a232e 12467 return(ctxt->errNo);
pcercuei 0:03b5121a232e 12468
pcercuei 0:03b5121a232e 12469 if (remain != 0) {
pcercuei 0:03b5121a232e 12470 chunk += size;
pcercuei 0:03b5121a232e 12471 size = remain;
pcercuei 0:03b5121a232e 12472 remain = 0;
pcercuei 0:03b5121a232e 12473 goto xmldecl_done;
pcercuei 0:03b5121a232e 12474 }
pcercuei 0:03b5121a232e 12475 if ((end_in_lf == 1) && (ctxt->input != NULL) &&
pcercuei 0:03b5121a232e 12476 (ctxt->input->buf != NULL)) {
pcercuei 0:03b5121a232e 12477 size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer,
pcercuei 0:03b5121a232e 12478 ctxt->input);
pcercuei 0:03b5121a232e 12479 size_t current = ctxt->input->cur - ctxt->input->base;
pcercuei 0:03b5121a232e 12480
pcercuei 0:03b5121a232e 12481 xmlParserInputBufferPush(ctxt->input->buf, 1, "\r");
pcercuei 0:03b5121a232e 12482
pcercuei 0:03b5121a232e 12483 xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input,
pcercuei 0:03b5121a232e 12484 base, current);
pcercuei 0:03b5121a232e 12485 }
pcercuei 0:03b5121a232e 12486 if (terminate) {
pcercuei 0:03b5121a232e 12487 /*
pcercuei 0:03b5121a232e 12488 * Check for termination
pcercuei 0:03b5121a232e 12489 */
pcercuei 0:03b5121a232e 12490 int cur_avail = 0;
pcercuei 0:03b5121a232e 12491
pcercuei 0:03b5121a232e 12492 if (ctxt->input != NULL) {
pcercuei 0:03b5121a232e 12493 if (ctxt->input->buf == NULL)
pcercuei 0:03b5121a232e 12494 cur_avail = ctxt->input->length -
pcercuei 0:03b5121a232e 12495 (ctxt->input->cur - ctxt->input->base);
pcercuei 0:03b5121a232e 12496 else
pcercuei 0:03b5121a232e 12497 cur_avail = xmlBufUse(ctxt->input->buf->buffer) -
pcercuei 0:03b5121a232e 12498 (ctxt->input->cur - ctxt->input->base);
pcercuei 0:03b5121a232e 12499 }
pcercuei 0:03b5121a232e 12500
pcercuei 0:03b5121a232e 12501 if ((ctxt->instate != XML_PARSER_EOF) &&
pcercuei 0:03b5121a232e 12502 (ctxt->instate != XML_PARSER_EPILOG)) {
pcercuei 0:03b5121a232e 12503 xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
pcercuei 0:03b5121a232e 12504 }
pcercuei 0:03b5121a232e 12505 if ((ctxt->instate == XML_PARSER_EPILOG) && (cur_avail > 0)) {
pcercuei 0:03b5121a232e 12506 xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
pcercuei 0:03b5121a232e 12507 }
pcercuei 0:03b5121a232e 12508 if (ctxt->instate != XML_PARSER_EOF) {
pcercuei 0:03b5121a232e 12509 if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
pcercuei 0:03b5121a232e 12510 ctxt->sax->endDocument(ctxt->userData);
pcercuei 0:03b5121a232e 12511 }
pcercuei 0:03b5121a232e 12512 ctxt->instate = XML_PARSER_EOF;
pcercuei 0:03b5121a232e 12513 }
pcercuei 0:03b5121a232e 12514 if (ctxt->wellFormed == 0)
pcercuei 0:03b5121a232e 12515 return((xmlParserErrors) ctxt->errNo);
pcercuei 0:03b5121a232e 12516 else
pcercuei 0:03b5121a232e 12517 return(0);
pcercuei 0:03b5121a232e 12518 }
pcercuei 0:03b5121a232e 12519
pcercuei 0:03b5121a232e 12520 /************************************************************************
pcercuei 0:03b5121a232e 12521 * *
pcercuei 0:03b5121a232e 12522 * I/O front end functions to the parser *
pcercuei 0:03b5121a232e 12523 * *
pcercuei 0:03b5121a232e 12524 ************************************************************************/
pcercuei 0:03b5121a232e 12525
pcercuei 0:03b5121a232e 12526 /**
pcercuei 0:03b5121a232e 12527 * xmlCreatePushParserCtxt:
pcercuei 0:03b5121a232e 12528 * @sax: a SAX handler
pcercuei 0:03b5121a232e 12529 * @user_data: The user data returned on SAX callbacks
pcercuei 0:03b5121a232e 12530 * @chunk: a pointer to an array of chars
pcercuei 0:03b5121a232e 12531 * @size: number of chars in the array
pcercuei 0:03b5121a232e 12532 * @filename: an optional file name or URI
pcercuei 0:03b5121a232e 12533 *
pcercuei 0:03b5121a232e 12534 * Create a parser context for using the XML parser in push mode.
pcercuei 0:03b5121a232e 12535 * If @buffer and @size are non-NULL, the data is used to detect
pcercuei 0:03b5121a232e 12536 * the encoding. The remaining characters will be parsed so they
pcercuei 0:03b5121a232e 12537 * don't need to be fed in again through xmlParseChunk.
pcercuei 0:03b5121a232e 12538 * To allow content encoding detection, @size should be >= 4
pcercuei 0:03b5121a232e 12539 * The value of @filename is used for fetching external entities
pcercuei 0:03b5121a232e 12540 * and error/warning reports.
pcercuei 0:03b5121a232e 12541 *
pcercuei 0:03b5121a232e 12542 * Returns the new parser context or NULL
pcercuei 0:03b5121a232e 12543 */
pcercuei 0:03b5121a232e 12544
pcercuei 0:03b5121a232e 12545 xmlParserCtxtPtr
pcercuei 0:03b5121a232e 12546 xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
pcercuei 0:03b5121a232e 12547 const char *chunk, int size, const char *filename) {
pcercuei 0:03b5121a232e 12548 xmlParserCtxtPtr ctxt;
pcercuei 0:03b5121a232e 12549 xmlParserInputPtr inputStream;
pcercuei 0:03b5121a232e 12550 xmlParserInputBufferPtr buf;
pcercuei 0:03b5121a232e 12551 xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
pcercuei 0:03b5121a232e 12552
pcercuei 0:03b5121a232e 12553 /*
pcercuei 0:03b5121a232e 12554 * plug some encoding conversion routines
pcercuei 0:03b5121a232e 12555 */
pcercuei 0:03b5121a232e 12556 if ((chunk != NULL) && (size >= 4))
pcercuei 0:03b5121a232e 12557 enc = xmlDetectCharEncoding((const xmlChar *) chunk, size);
pcercuei 0:03b5121a232e 12558
pcercuei 0:03b5121a232e 12559 buf = xmlAllocParserInputBuffer(enc);
pcercuei 0:03b5121a232e 12560 if (buf == NULL) return(NULL);
pcercuei 0:03b5121a232e 12561
pcercuei 0:03b5121a232e 12562 ctxt = xmlNewParserCtxt();
pcercuei 0:03b5121a232e 12563 if (ctxt == NULL) {
pcercuei 0:03b5121a232e 12564 xmlErrMemory(NULL, "creating parser: out of memory\n");
pcercuei 0:03b5121a232e 12565 xmlFreeParserInputBuffer(buf);
pcercuei 0:03b5121a232e 12566 return(NULL);
pcercuei 0:03b5121a232e 12567 }
pcercuei 0:03b5121a232e 12568 ctxt->dictNames = 1;
pcercuei 0:03b5121a232e 12569 ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 * sizeof(xmlChar *));
pcercuei 0:03b5121a232e 12570 if (ctxt->pushTab == NULL) {
pcercuei 0:03b5121a232e 12571 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 12572 xmlFreeParserInputBuffer(buf);
pcercuei 0:03b5121a232e 12573 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 12574 return(NULL);
pcercuei 0:03b5121a232e 12575 }
pcercuei 0:03b5121a232e 12576 if (sax != NULL) {
pcercuei 0:03b5121a232e 12577 #ifdef LIBXML_SAX1_ENABLED
pcercuei 0:03b5121a232e 12578 if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
pcercuei 0:03b5121a232e 12579 #endif /* LIBXML_SAX1_ENABLED */
pcercuei 0:03b5121a232e 12580 xmlFree(ctxt->sax);
pcercuei 0:03b5121a232e 12581 ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
pcercuei 0:03b5121a232e 12582 if (ctxt->sax == NULL) {
pcercuei 0:03b5121a232e 12583 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 12584 xmlFreeParserInputBuffer(buf);
pcercuei 0:03b5121a232e 12585 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 12586 return(NULL);
pcercuei 0:03b5121a232e 12587 }
pcercuei 0:03b5121a232e 12588 memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
pcercuei 0:03b5121a232e 12589 if (sax->initialized == XML_SAX2_MAGIC)
pcercuei 0:03b5121a232e 12590 memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
pcercuei 0:03b5121a232e 12591 else
pcercuei 0:03b5121a232e 12592 memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
pcercuei 0:03b5121a232e 12593 if (user_data != NULL)
pcercuei 0:03b5121a232e 12594 ctxt->userData = user_data;
pcercuei 0:03b5121a232e 12595 }
pcercuei 0:03b5121a232e 12596 if (filename == NULL) {
pcercuei 0:03b5121a232e 12597 ctxt->directory = NULL;
pcercuei 0:03b5121a232e 12598 } else {
pcercuei 0:03b5121a232e 12599 ctxt->directory = xmlParserGetDirectory(filename);
pcercuei 0:03b5121a232e 12600 }
pcercuei 0:03b5121a232e 12601
pcercuei 0:03b5121a232e 12602 inputStream = xmlNewInputStream(ctxt);
pcercuei 0:03b5121a232e 12603 if (inputStream == NULL) {
pcercuei 0:03b5121a232e 12604 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 12605 xmlFreeParserInputBuffer(buf);
pcercuei 0:03b5121a232e 12606 return(NULL);
pcercuei 0:03b5121a232e 12607 }
pcercuei 0:03b5121a232e 12608
pcercuei 0:03b5121a232e 12609 if (filename == NULL)
pcercuei 0:03b5121a232e 12610 inputStream->filename = NULL;
pcercuei 0:03b5121a232e 12611 else {
pcercuei 0:03b5121a232e 12612 inputStream->filename = (char *)
pcercuei 0:03b5121a232e 12613 xmlCanonicPath((const xmlChar *) filename);
pcercuei 0:03b5121a232e 12614 if (inputStream->filename == NULL) {
pcercuei 0:03b5121a232e 12615 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 12616 xmlFreeParserInputBuffer(buf);
pcercuei 0:03b5121a232e 12617 return(NULL);
pcercuei 0:03b5121a232e 12618 }
pcercuei 0:03b5121a232e 12619 }
pcercuei 0:03b5121a232e 12620 inputStream->buf = buf;
pcercuei 0:03b5121a232e 12621 xmlBufResetInput(inputStream->buf->buffer, inputStream);
pcercuei 0:03b5121a232e 12622 inputPush(ctxt, inputStream);
pcercuei 0:03b5121a232e 12623
pcercuei 0:03b5121a232e 12624 /*
pcercuei 0:03b5121a232e 12625 * If the caller didn't provide an initial 'chunk' for determining
pcercuei 0:03b5121a232e 12626 * the encoding, we set the context to XML_CHAR_ENCODING_NONE so
pcercuei 0:03b5121a232e 12627 * that it can be automatically determined later
pcercuei 0:03b5121a232e 12628 */
pcercuei 0:03b5121a232e 12629 if ((size == 0) || (chunk == NULL)) {
pcercuei 0:03b5121a232e 12630 ctxt->charset = XML_CHAR_ENCODING_NONE;
pcercuei 0:03b5121a232e 12631 } else if ((ctxt->input != NULL) && (ctxt->input->buf != NULL)) {
pcercuei 0:03b5121a232e 12632 size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer, ctxt->input);
pcercuei 0:03b5121a232e 12633 size_t cur = ctxt->input->cur - ctxt->input->base;
pcercuei 0:03b5121a232e 12634
pcercuei 0:03b5121a232e 12635 xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
pcercuei 0:03b5121a232e 12636
pcercuei 0:03b5121a232e 12637 xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur);
pcercuei 0:03b5121a232e 12638 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 12639 xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
pcercuei 0:03b5121a232e 12640 #endif
pcercuei 0:03b5121a232e 12641 }
pcercuei 0:03b5121a232e 12642
pcercuei 0:03b5121a232e 12643 if (enc != XML_CHAR_ENCODING_NONE) {
pcercuei 0:03b5121a232e 12644 xmlSwitchEncoding(ctxt, enc);
pcercuei 0:03b5121a232e 12645 }
pcercuei 0:03b5121a232e 12646
pcercuei 0:03b5121a232e 12647 return(ctxt);
pcercuei 0:03b5121a232e 12648 }
pcercuei 0:03b5121a232e 12649 #endif /* LIBXML_PUSH_ENABLED */
pcercuei 0:03b5121a232e 12650
pcercuei 0:03b5121a232e 12651 /**
pcercuei 0:03b5121a232e 12652 * xmlHaltParser:
pcercuei 0:03b5121a232e 12653 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 12654 *
pcercuei 0:03b5121a232e 12655 * Blocks further parser processing don't override error
pcercuei 0:03b5121a232e 12656 * for internal use
pcercuei 0:03b5121a232e 12657 */
pcercuei 0:03b5121a232e 12658 static void
pcercuei 0:03b5121a232e 12659 xmlHaltParser(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 12660 if (ctxt == NULL)
pcercuei 0:03b5121a232e 12661 return;
pcercuei 0:03b5121a232e 12662 ctxt->instate = XML_PARSER_EOF;
pcercuei 0:03b5121a232e 12663 ctxt->disableSAX = 1;
pcercuei 0:03b5121a232e 12664 if (ctxt->input != NULL) {
pcercuei 0:03b5121a232e 12665 /*
pcercuei 0:03b5121a232e 12666 * in case there was a specific allocation deallocate before
pcercuei 0:03b5121a232e 12667 * overriding base
pcercuei 0:03b5121a232e 12668 */
pcercuei 0:03b5121a232e 12669 if (ctxt->input->free != NULL) {
pcercuei 0:03b5121a232e 12670 ctxt->input->free((xmlChar *) ctxt->input->base);
pcercuei 0:03b5121a232e 12671 ctxt->input->free = NULL;
pcercuei 0:03b5121a232e 12672 }
pcercuei 0:03b5121a232e 12673 ctxt->input->cur = BAD_CAST"";
pcercuei 0:03b5121a232e 12674 ctxt->input->base = ctxt->input->cur;
pcercuei 0:03b5121a232e 12675 }
pcercuei 0:03b5121a232e 12676 }
pcercuei 0:03b5121a232e 12677
pcercuei 0:03b5121a232e 12678 /**
pcercuei 0:03b5121a232e 12679 * xmlStopParser:
pcercuei 0:03b5121a232e 12680 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 12681 *
pcercuei 0:03b5121a232e 12682 * Blocks further parser processing
pcercuei 0:03b5121a232e 12683 */
pcercuei 0:03b5121a232e 12684 void
pcercuei 0:03b5121a232e 12685 xmlStopParser(xmlParserCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 12686 if (ctxt == NULL)
pcercuei 0:03b5121a232e 12687 return;
pcercuei 0:03b5121a232e 12688 xmlHaltParser(ctxt);
pcercuei 0:03b5121a232e 12689 ctxt->errNo = XML_ERR_USER_STOP;
pcercuei 0:03b5121a232e 12690 }
pcercuei 0:03b5121a232e 12691
pcercuei 0:03b5121a232e 12692 /**
pcercuei 0:03b5121a232e 12693 * xmlCreateIOParserCtxt:
pcercuei 0:03b5121a232e 12694 * @sax: a SAX handler
pcercuei 0:03b5121a232e 12695 * @user_data: The user data returned on SAX callbacks
pcercuei 0:03b5121a232e 12696 * @ioread: an I/O read function
pcercuei 0:03b5121a232e 12697 * @ioclose: an I/O close function
pcercuei 0:03b5121a232e 12698 * @ioctx: an I/O handler
pcercuei 0:03b5121a232e 12699 * @enc: the charset encoding if known
pcercuei 0:03b5121a232e 12700 *
pcercuei 0:03b5121a232e 12701 * Create a parser context for using the XML parser with an existing
pcercuei 0:03b5121a232e 12702 * I/O stream
pcercuei 0:03b5121a232e 12703 *
pcercuei 0:03b5121a232e 12704 * Returns the new parser context or NULL
pcercuei 0:03b5121a232e 12705 */
pcercuei 0:03b5121a232e 12706 xmlParserCtxtPtr
pcercuei 0:03b5121a232e 12707 xmlCreateIOParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
pcercuei 0:03b5121a232e 12708 xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
pcercuei 0:03b5121a232e 12709 void *ioctx, xmlCharEncoding enc) {
pcercuei 0:03b5121a232e 12710 xmlParserCtxtPtr ctxt;
pcercuei 0:03b5121a232e 12711 xmlParserInputPtr inputStream;
pcercuei 0:03b5121a232e 12712 xmlParserInputBufferPtr buf;
pcercuei 0:03b5121a232e 12713
pcercuei 0:03b5121a232e 12714 if (ioread == NULL) return(NULL);
pcercuei 0:03b5121a232e 12715
pcercuei 0:03b5121a232e 12716 buf = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx, enc);
pcercuei 0:03b5121a232e 12717 if (buf == NULL) {
pcercuei 0:03b5121a232e 12718 if (ioclose != NULL)
pcercuei 0:03b5121a232e 12719 ioclose(ioctx);
pcercuei 0:03b5121a232e 12720 return (NULL);
pcercuei 0:03b5121a232e 12721 }
pcercuei 0:03b5121a232e 12722
pcercuei 0:03b5121a232e 12723 ctxt = xmlNewParserCtxt();
pcercuei 0:03b5121a232e 12724 if (ctxt == NULL) {
pcercuei 0:03b5121a232e 12725 xmlFreeParserInputBuffer(buf);
pcercuei 0:03b5121a232e 12726 return(NULL);
pcercuei 0:03b5121a232e 12727 }
pcercuei 0:03b5121a232e 12728 if (sax != NULL) {
pcercuei 0:03b5121a232e 12729 #ifdef LIBXML_SAX1_ENABLED
pcercuei 0:03b5121a232e 12730 if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
pcercuei 0:03b5121a232e 12731 #endif /* LIBXML_SAX1_ENABLED */
pcercuei 0:03b5121a232e 12732 xmlFree(ctxt->sax);
pcercuei 0:03b5121a232e 12733 ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
pcercuei 0:03b5121a232e 12734 if (ctxt->sax == NULL) {
pcercuei 0:03b5121a232e 12735 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 12736 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 12737 return(NULL);
pcercuei 0:03b5121a232e 12738 }
pcercuei 0:03b5121a232e 12739 memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
pcercuei 0:03b5121a232e 12740 if (sax->initialized == XML_SAX2_MAGIC)
pcercuei 0:03b5121a232e 12741 memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
pcercuei 0:03b5121a232e 12742 else
pcercuei 0:03b5121a232e 12743 memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
pcercuei 0:03b5121a232e 12744 if (user_data != NULL)
pcercuei 0:03b5121a232e 12745 ctxt->userData = user_data;
pcercuei 0:03b5121a232e 12746 }
pcercuei 0:03b5121a232e 12747
pcercuei 0:03b5121a232e 12748 inputStream = xmlNewIOInputStream(ctxt, buf, enc);
pcercuei 0:03b5121a232e 12749 if (inputStream == NULL) {
pcercuei 0:03b5121a232e 12750 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 12751 return(NULL);
pcercuei 0:03b5121a232e 12752 }
pcercuei 0:03b5121a232e 12753 inputPush(ctxt, inputStream);
pcercuei 0:03b5121a232e 12754
pcercuei 0:03b5121a232e 12755 return(ctxt);
pcercuei 0:03b5121a232e 12756 }
pcercuei 0:03b5121a232e 12757
pcercuei 0:03b5121a232e 12758 #ifdef LIBXML_VALID_ENABLED
pcercuei 0:03b5121a232e 12759 /************************************************************************
pcercuei 0:03b5121a232e 12760 * *
pcercuei 0:03b5121a232e 12761 * Front ends when parsing a DTD *
pcercuei 0:03b5121a232e 12762 * *
pcercuei 0:03b5121a232e 12763 ************************************************************************/
pcercuei 0:03b5121a232e 12764
pcercuei 0:03b5121a232e 12765 /**
pcercuei 0:03b5121a232e 12766 * xmlIOParseDTD:
pcercuei 0:03b5121a232e 12767 * @sax: the SAX handler block or NULL
pcercuei 0:03b5121a232e 12768 * @input: an Input Buffer
pcercuei 0:03b5121a232e 12769 * @enc: the charset encoding if known
pcercuei 0:03b5121a232e 12770 *
pcercuei 0:03b5121a232e 12771 * Load and parse a DTD
pcercuei 0:03b5121a232e 12772 *
pcercuei 0:03b5121a232e 12773 * Returns the resulting xmlDtdPtr or NULL in case of error.
pcercuei 0:03b5121a232e 12774 * @input will be freed by the function in any case.
pcercuei 0:03b5121a232e 12775 */
pcercuei 0:03b5121a232e 12776
pcercuei 0:03b5121a232e 12777 xmlDtdPtr
pcercuei 0:03b5121a232e 12778 xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlParserInputBufferPtr input,
pcercuei 0:03b5121a232e 12779 xmlCharEncoding enc) {
pcercuei 0:03b5121a232e 12780 xmlDtdPtr ret = NULL;
pcercuei 0:03b5121a232e 12781 xmlParserCtxtPtr ctxt;
pcercuei 0:03b5121a232e 12782 xmlParserInputPtr pinput = NULL;
pcercuei 0:03b5121a232e 12783 xmlChar start[4];
pcercuei 0:03b5121a232e 12784
pcercuei 0:03b5121a232e 12785 if (input == NULL)
pcercuei 0:03b5121a232e 12786 return(NULL);
pcercuei 0:03b5121a232e 12787
pcercuei 0:03b5121a232e 12788 ctxt = xmlNewParserCtxt();
pcercuei 0:03b5121a232e 12789 if (ctxt == NULL) {
pcercuei 0:03b5121a232e 12790 xmlFreeParserInputBuffer(input);
pcercuei 0:03b5121a232e 12791 return(NULL);
pcercuei 0:03b5121a232e 12792 }
pcercuei 0:03b5121a232e 12793
pcercuei 0:03b5121a232e 12794 /* We are loading a DTD */
pcercuei 0:03b5121a232e 12795 ctxt->options |= XML_PARSE_DTDLOAD;
pcercuei 0:03b5121a232e 12796
pcercuei 0:03b5121a232e 12797 /*
pcercuei 0:03b5121a232e 12798 * Set-up the SAX context
pcercuei 0:03b5121a232e 12799 */
pcercuei 0:03b5121a232e 12800 if (sax != NULL) {
pcercuei 0:03b5121a232e 12801 if (ctxt->sax != NULL)
pcercuei 0:03b5121a232e 12802 xmlFree(ctxt->sax);
pcercuei 0:03b5121a232e 12803 ctxt->sax = sax;
pcercuei 0:03b5121a232e 12804 ctxt->userData = ctxt;
pcercuei 0:03b5121a232e 12805 }
pcercuei 0:03b5121a232e 12806 xmlDetectSAX2(ctxt);
pcercuei 0:03b5121a232e 12807
pcercuei 0:03b5121a232e 12808 /*
pcercuei 0:03b5121a232e 12809 * generate a parser input from the I/O handler
pcercuei 0:03b5121a232e 12810 */
pcercuei 0:03b5121a232e 12811
pcercuei 0:03b5121a232e 12812 pinput = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
pcercuei 0:03b5121a232e 12813 if (pinput == NULL) {
pcercuei 0:03b5121a232e 12814 if (sax != NULL) ctxt->sax = NULL;
pcercuei 0:03b5121a232e 12815 xmlFreeParserInputBuffer(input);
pcercuei 0:03b5121a232e 12816 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 12817 return(NULL);
pcercuei 0:03b5121a232e 12818 }
pcercuei 0:03b5121a232e 12819
pcercuei 0:03b5121a232e 12820 /*
pcercuei 0:03b5121a232e 12821 * plug some encoding conversion routines here.
pcercuei 0:03b5121a232e 12822 */
pcercuei 0:03b5121a232e 12823 if (xmlPushInput(ctxt, pinput) < 0) {
pcercuei 0:03b5121a232e 12824 if (sax != NULL) ctxt->sax = NULL;
pcercuei 0:03b5121a232e 12825 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 12826 return(NULL);
pcercuei 0:03b5121a232e 12827 }
pcercuei 0:03b5121a232e 12828 if (enc != XML_CHAR_ENCODING_NONE) {
pcercuei 0:03b5121a232e 12829 xmlSwitchEncoding(ctxt, enc);
pcercuei 0:03b5121a232e 12830 }
pcercuei 0:03b5121a232e 12831
pcercuei 0:03b5121a232e 12832 pinput->filename = NULL;
pcercuei 0:03b5121a232e 12833 pinput->line = 1;
pcercuei 0:03b5121a232e 12834 pinput->col = 1;
pcercuei 0:03b5121a232e 12835 pinput->base = ctxt->input->cur;
pcercuei 0:03b5121a232e 12836 pinput->cur = ctxt->input->cur;
pcercuei 0:03b5121a232e 12837 pinput->free = NULL;
pcercuei 0:03b5121a232e 12838
pcercuei 0:03b5121a232e 12839 /*
pcercuei 0:03b5121a232e 12840 * let's parse that entity knowing it's an external subset.
pcercuei 0:03b5121a232e 12841 */
pcercuei 0:03b5121a232e 12842 ctxt->inSubset = 2;
pcercuei 0:03b5121a232e 12843 ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
pcercuei 0:03b5121a232e 12844 if (ctxt->myDoc == NULL) {
pcercuei 0:03b5121a232e 12845 xmlErrMemory(ctxt, "New Doc failed");
pcercuei 0:03b5121a232e 12846 return(NULL);
pcercuei 0:03b5121a232e 12847 }
pcercuei 0:03b5121a232e 12848 ctxt->myDoc->properties = XML_DOC_INTERNAL;
pcercuei 0:03b5121a232e 12849 ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
pcercuei 0:03b5121a232e 12850 BAD_CAST "none", BAD_CAST "none");
pcercuei 0:03b5121a232e 12851
pcercuei 0:03b5121a232e 12852 if ((enc == XML_CHAR_ENCODING_NONE) &&
pcercuei 0:03b5121a232e 12853 ((ctxt->input->end - ctxt->input->cur) >= 4)) {
pcercuei 0:03b5121a232e 12854 /*
pcercuei 0:03b5121a232e 12855 * Get the 4 first bytes and decode the charset
pcercuei 0:03b5121a232e 12856 * if enc != XML_CHAR_ENCODING_NONE
pcercuei 0:03b5121a232e 12857 * plug some encoding conversion routines.
pcercuei 0:03b5121a232e 12858 */
pcercuei 0:03b5121a232e 12859 start[0] = RAW;
pcercuei 0:03b5121a232e 12860 start[1] = NXT(1);
pcercuei 0:03b5121a232e 12861 start[2] = NXT(2);
pcercuei 0:03b5121a232e 12862 start[3] = NXT(3);
pcercuei 0:03b5121a232e 12863 enc = xmlDetectCharEncoding(start, 4);
pcercuei 0:03b5121a232e 12864 if (enc != XML_CHAR_ENCODING_NONE) {
pcercuei 0:03b5121a232e 12865 xmlSwitchEncoding(ctxt, enc);
pcercuei 0:03b5121a232e 12866 }
pcercuei 0:03b5121a232e 12867 }
pcercuei 0:03b5121a232e 12868
pcercuei 0:03b5121a232e 12869 xmlParseExternalSubset(ctxt, BAD_CAST "none", BAD_CAST "none");
pcercuei 0:03b5121a232e 12870
pcercuei 0:03b5121a232e 12871 if (ctxt->myDoc != NULL) {
pcercuei 0:03b5121a232e 12872 if (ctxt->wellFormed) {
pcercuei 0:03b5121a232e 12873 ret = ctxt->myDoc->extSubset;
pcercuei 0:03b5121a232e 12874 ctxt->myDoc->extSubset = NULL;
pcercuei 0:03b5121a232e 12875 if (ret != NULL) {
pcercuei 0:03b5121a232e 12876 xmlNodePtr tmp;
pcercuei 0:03b5121a232e 12877
pcercuei 0:03b5121a232e 12878 ret->doc = NULL;
pcercuei 0:03b5121a232e 12879 tmp = ret->children;
pcercuei 0:03b5121a232e 12880 while (tmp != NULL) {
pcercuei 0:03b5121a232e 12881 tmp->doc = NULL;
pcercuei 0:03b5121a232e 12882 tmp = tmp->next;
pcercuei 0:03b5121a232e 12883 }
pcercuei 0:03b5121a232e 12884 }
pcercuei 0:03b5121a232e 12885 } else {
pcercuei 0:03b5121a232e 12886 ret = NULL;
pcercuei 0:03b5121a232e 12887 }
pcercuei 0:03b5121a232e 12888 xmlFreeDoc(ctxt->myDoc);
pcercuei 0:03b5121a232e 12889 ctxt->myDoc = NULL;
pcercuei 0:03b5121a232e 12890 }
pcercuei 0:03b5121a232e 12891 if (sax != NULL) ctxt->sax = NULL;
pcercuei 0:03b5121a232e 12892 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 12893
pcercuei 0:03b5121a232e 12894 return(ret);
pcercuei 0:03b5121a232e 12895 }
pcercuei 0:03b5121a232e 12896
pcercuei 0:03b5121a232e 12897 /**
pcercuei 0:03b5121a232e 12898 * xmlSAXParseDTD:
pcercuei 0:03b5121a232e 12899 * @sax: the SAX handler block
pcercuei 0:03b5121a232e 12900 * @ExternalID: a NAME* containing the External ID of the DTD
pcercuei 0:03b5121a232e 12901 * @SystemID: a NAME* containing the URL to the DTD
pcercuei 0:03b5121a232e 12902 *
pcercuei 0:03b5121a232e 12903 * Load and parse an external subset.
pcercuei 0:03b5121a232e 12904 *
pcercuei 0:03b5121a232e 12905 * Returns the resulting xmlDtdPtr or NULL in case of error.
pcercuei 0:03b5121a232e 12906 */
pcercuei 0:03b5121a232e 12907
pcercuei 0:03b5121a232e 12908 xmlDtdPtr
pcercuei 0:03b5121a232e 12909 xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID,
pcercuei 0:03b5121a232e 12910 const xmlChar *SystemID) {
pcercuei 0:03b5121a232e 12911 xmlDtdPtr ret = NULL;
pcercuei 0:03b5121a232e 12912 xmlParserCtxtPtr ctxt;
pcercuei 0:03b5121a232e 12913 xmlParserInputPtr input = NULL;
pcercuei 0:03b5121a232e 12914 xmlCharEncoding enc;
pcercuei 0:03b5121a232e 12915 xmlChar* systemIdCanonic;
pcercuei 0:03b5121a232e 12916
pcercuei 0:03b5121a232e 12917 if ((ExternalID == NULL) && (SystemID == NULL)) return(NULL);
pcercuei 0:03b5121a232e 12918
pcercuei 0:03b5121a232e 12919 ctxt = xmlNewParserCtxt();
pcercuei 0:03b5121a232e 12920 if (ctxt == NULL) {
pcercuei 0:03b5121a232e 12921 return(NULL);
pcercuei 0:03b5121a232e 12922 }
pcercuei 0:03b5121a232e 12923
pcercuei 0:03b5121a232e 12924 /* We are loading a DTD */
pcercuei 0:03b5121a232e 12925 ctxt->options |= XML_PARSE_DTDLOAD;
pcercuei 0:03b5121a232e 12926
pcercuei 0:03b5121a232e 12927 /*
pcercuei 0:03b5121a232e 12928 * Set-up the SAX context
pcercuei 0:03b5121a232e 12929 */
pcercuei 0:03b5121a232e 12930 if (sax != NULL) {
pcercuei 0:03b5121a232e 12931 if (ctxt->sax != NULL)
pcercuei 0:03b5121a232e 12932 xmlFree(ctxt->sax);
pcercuei 0:03b5121a232e 12933 ctxt->sax = sax;
pcercuei 0:03b5121a232e 12934 ctxt->userData = ctxt;
pcercuei 0:03b5121a232e 12935 }
pcercuei 0:03b5121a232e 12936
pcercuei 0:03b5121a232e 12937 /*
pcercuei 0:03b5121a232e 12938 * Canonicalise the system ID
pcercuei 0:03b5121a232e 12939 */
pcercuei 0:03b5121a232e 12940 systemIdCanonic = xmlCanonicPath(SystemID);
pcercuei 0:03b5121a232e 12941 if ((SystemID != NULL) && (systemIdCanonic == NULL)) {
pcercuei 0:03b5121a232e 12942 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 12943 return(NULL);
pcercuei 0:03b5121a232e 12944 }
pcercuei 0:03b5121a232e 12945
pcercuei 0:03b5121a232e 12946 /*
pcercuei 0:03b5121a232e 12947 * Ask the Entity resolver to load the damn thing
pcercuei 0:03b5121a232e 12948 */
pcercuei 0:03b5121a232e 12949
pcercuei 0:03b5121a232e 12950 if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
pcercuei 0:03b5121a232e 12951 input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID,
pcercuei 0:03b5121a232e 12952 systemIdCanonic);
pcercuei 0:03b5121a232e 12953 if (input == NULL) {
pcercuei 0:03b5121a232e 12954 if (sax != NULL) ctxt->sax = NULL;
pcercuei 0:03b5121a232e 12955 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 12956 if (systemIdCanonic != NULL)
pcercuei 0:03b5121a232e 12957 xmlFree(systemIdCanonic);
pcercuei 0:03b5121a232e 12958 return(NULL);
pcercuei 0:03b5121a232e 12959 }
pcercuei 0:03b5121a232e 12960
pcercuei 0:03b5121a232e 12961 /*
pcercuei 0:03b5121a232e 12962 * plug some encoding conversion routines here.
pcercuei 0:03b5121a232e 12963 */
pcercuei 0:03b5121a232e 12964 if (xmlPushInput(ctxt, input) < 0) {
pcercuei 0:03b5121a232e 12965 if (sax != NULL) ctxt->sax = NULL;
pcercuei 0:03b5121a232e 12966 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 12967 if (systemIdCanonic != NULL)
pcercuei 0:03b5121a232e 12968 xmlFree(systemIdCanonic);
pcercuei 0:03b5121a232e 12969 return(NULL);
pcercuei 0:03b5121a232e 12970 }
pcercuei 0:03b5121a232e 12971 if ((ctxt->input->end - ctxt->input->cur) >= 4) {
pcercuei 0:03b5121a232e 12972 enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
pcercuei 0:03b5121a232e 12973 xmlSwitchEncoding(ctxt, enc);
pcercuei 0:03b5121a232e 12974 }
pcercuei 0:03b5121a232e 12975
pcercuei 0:03b5121a232e 12976 if (input->filename == NULL)
pcercuei 0:03b5121a232e 12977 input->filename = (char *) systemIdCanonic;
pcercuei 0:03b5121a232e 12978 else
pcercuei 0:03b5121a232e 12979 xmlFree(systemIdCanonic);
pcercuei 0:03b5121a232e 12980 input->line = 1;
pcercuei 0:03b5121a232e 12981 input->col = 1;
pcercuei 0:03b5121a232e 12982 input->base = ctxt->input->cur;
pcercuei 0:03b5121a232e 12983 input->cur = ctxt->input->cur;
pcercuei 0:03b5121a232e 12984 input->free = NULL;
pcercuei 0:03b5121a232e 12985
pcercuei 0:03b5121a232e 12986 /*
pcercuei 0:03b5121a232e 12987 * let's parse that entity knowing it's an external subset.
pcercuei 0:03b5121a232e 12988 */
pcercuei 0:03b5121a232e 12989 ctxt->inSubset = 2;
pcercuei 0:03b5121a232e 12990 ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
pcercuei 0:03b5121a232e 12991 if (ctxt->myDoc == NULL) {
pcercuei 0:03b5121a232e 12992 xmlErrMemory(ctxt, "New Doc failed");
pcercuei 0:03b5121a232e 12993 if (sax != NULL) ctxt->sax = NULL;
pcercuei 0:03b5121a232e 12994 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 12995 return(NULL);
pcercuei 0:03b5121a232e 12996 }
pcercuei 0:03b5121a232e 12997 ctxt->myDoc->properties = XML_DOC_INTERNAL;
pcercuei 0:03b5121a232e 12998 ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
pcercuei 0:03b5121a232e 12999 ExternalID, SystemID);
pcercuei 0:03b5121a232e 13000 xmlParseExternalSubset(ctxt, ExternalID, SystemID);
pcercuei 0:03b5121a232e 13001
pcercuei 0:03b5121a232e 13002 if (ctxt->myDoc != NULL) {
pcercuei 0:03b5121a232e 13003 if (ctxt->wellFormed) {
pcercuei 0:03b5121a232e 13004 ret = ctxt->myDoc->extSubset;
pcercuei 0:03b5121a232e 13005 ctxt->myDoc->extSubset = NULL;
pcercuei 0:03b5121a232e 13006 if (ret != NULL) {
pcercuei 0:03b5121a232e 13007 xmlNodePtr tmp;
pcercuei 0:03b5121a232e 13008
pcercuei 0:03b5121a232e 13009 ret->doc = NULL;
pcercuei 0:03b5121a232e 13010 tmp = ret->children;
pcercuei 0:03b5121a232e 13011 while (tmp != NULL) {
pcercuei 0:03b5121a232e 13012 tmp->doc = NULL;
pcercuei 0:03b5121a232e 13013 tmp = tmp->next;
pcercuei 0:03b5121a232e 13014 }
pcercuei 0:03b5121a232e 13015 }
pcercuei 0:03b5121a232e 13016 } else {
pcercuei 0:03b5121a232e 13017 ret = NULL;
pcercuei 0:03b5121a232e 13018 }
pcercuei 0:03b5121a232e 13019 xmlFreeDoc(ctxt->myDoc);
pcercuei 0:03b5121a232e 13020 ctxt->myDoc = NULL;
pcercuei 0:03b5121a232e 13021 }
pcercuei 0:03b5121a232e 13022 if (sax != NULL) ctxt->sax = NULL;
pcercuei 0:03b5121a232e 13023 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 13024
pcercuei 0:03b5121a232e 13025 return(ret);
pcercuei 0:03b5121a232e 13026 }
pcercuei 0:03b5121a232e 13027
pcercuei 0:03b5121a232e 13028
pcercuei 0:03b5121a232e 13029 /**
pcercuei 0:03b5121a232e 13030 * xmlParseDTD:
pcercuei 0:03b5121a232e 13031 * @ExternalID: a NAME* containing the External ID of the DTD
pcercuei 0:03b5121a232e 13032 * @SystemID: a NAME* containing the URL to the DTD
pcercuei 0:03b5121a232e 13033 *
pcercuei 0:03b5121a232e 13034 * Load and parse an external subset.
pcercuei 0:03b5121a232e 13035 *
pcercuei 0:03b5121a232e 13036 * Returns the resulting xmlDtdPtr or NULL in case of error.
pcercuei 0:03b5121a232e 13037 */
pcercuei 0:03b5121a232e 13038
pcercuei 0:03b5121a232e 13039 xmlDtdPtr
pcercuei 0:03b5121a232e 13040 xmlParseDTD(const xmlChar *ExternalID, const xmlChar *SystemID) {
pcercuei 0:03b5121a232e 13041 return(xmlSAXParseDTD(NULL, ExternalID, SystemID));
pcercuei 0:03b5121a232e 13042 }
pcercuei 0:03b5121a232e 13043 #endif /* LIBXML_VALID_ENABLED */
pcercuei 0:03b5121a232e 13044
pcercuei 0:03b5121a232e 13045 /************************************************************************
pcercuei 0:03b5121a232e 13046 * *
pcercuei 0:03b5121a232e 13047 * Front ends when parsing an Entity *
pcercuei 0:03b5121a232e 13048 * *
pcercuei 0:03b5121a232e 13049 ************************************************************************/
pcercuei 0:03b5121a232e 13050
pcercuei 0:03b5121a232e 13051 /**
pcercuei 0:03b5121a232e 13052 * xmlParseCtxtExternalEntity:
pcercuei 0:03b5121a232e 13053 * @ctx: the existing parsing context
pcercuei 0:03b5121a232e 13054 * @URL: the URL for the entity to load
pcercuei 0:03b5121a232e 13055 * @ID: the System ID for the entity to load
pcercuei 0:03b5121a232e 13056 * @lst: the return value for the set of parsed nodes
pcercuei 0:03b5121a232e 13057 *
pcercuei 0:03b5121a232e 13058 * Parse an external general entity within an existing parsing context
pcercuei 0:03b5121a232e 13059 * An external general parsed entity is well-formed if it matches the
pcercuei 0:03b5121a232e 13060 * production labeled extParsedEnt.
pcercuei 0:03b5121a232e 13061 *
pcercuei 0:03b5121a232e 13062 * [78] extParsedEnt ::= TextDecl? content
pcercuei 0:03b5121a232e 13063 *
pcercuei 0:03b5121a232e 13064 * Returns 0 if the entity is well formed, -1 in case of args problem and
pcercuei 0:03b5121a232e 13065 * the parser error code otherwise
pcercuei 0:03b5121a232e 13066 */
pcercuei 0:03b5121a232e 13067
pcercuei 0:03b5121a232e 13068 int
pcercuei 0:03b5121a232e 13069 xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx, const xmlChar *URL,
pcercuei 0:03b5121a232e 13070 const xmlChar *ID, xmlNodePtr *lst) {
pcercuei 0:03b5121a232e 13071 xmlParserCtxtPtr ctxt;
pcercuei 0:03b5121a232e 13072 xmlDocPtr newDoc;
pcercuei 0:03b5121a232e 13073 xmlNodePtr newRoot;
pcercuei 0:03b5121a232e 13074 xmlSAXHandlerPtr oldsax = NULL;
pcercuei 0:03b5121a232e 13075 int ret = 0;
pcercuei 0:03b5121a232e 13076 xmlChar start[4];
pcercuei 0:03b5121a232e 13077 xmlCharEncoding enc;
pcercuei 0:03b5121a232e 13078
pcercuei 0:03b5121a232e 13079 if (ctx == NULL) return(-1);
pcercuei 0:03b5121a232e 13080
pcercuei 0:03b5121a232e 13081 if (((ctx->depth > 40) && ((ctx->options & XML_PARSE_HUGE) == 0)) ||
pcercuei 0:03b5121a232e 13082 (ctx->depth > 1024)) {
pcercuei 0:03b5121a232e 13083 return(XML_ERR_ENTITY_LOOP);
pcercuei 0:03b5121a232e 13084 }
pcercuei 0:03b5121a232e 13085
pcercuei 0:03b5121a232e 13086 if (lst != NULL)
pcercuei 0:03b5121a232e 13087 *lst = NULL;
pcercuei 0:03b5121a232e 13088 if ((URL == NULL) && (ID == NULL))
pcercuei 0:03b5121a232e 13089 return(-1);
pcercuei 0:03b5121a232e 13090 if (ctx->myDoc == NULL) /* @@ relax but check for dereferences */
pcercuei 0:03b5121a232e 13091 return(-1);
pcercuei 0:03b5121a232e 13092
pcercuei 0:03b5121a232e 13093 ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, ctx);
pcercuei 0:03b5121a232e 13094 if (ctxt == NULL) {
pcercuei 0:03b5121a232e 13095 return(-1);
pcercuei 0:03b5121a232e 13096 }
pcercuei 0:03b5121a232e 13097
pcercuei 0:03b5121a232e 13098 oldsax = ctxt->sax;
pcercuei 0:03b5121a232e 13099 ctxt->sax = ctx->sax;
pcercuei 0:03b5121a232e 13100 xmlDetectSAX2(ctxt);
pcercuei 0:03b5121a232e 13101 newDoc = xmlNewDoc(BAD_CAST "1.0");
pcercuei 0:03b5121a232e 13102 if (newDoc == NULL) {
pcercuei 0:03b5121a232e 13103 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 13104 return(-1);
pcercuei 0:03b5121a232e 13105 }
pcercuei 0:03b5121a232e 13106 newDoc->properties = XML_DOC_INTERNAL;
pcercuei 0:03b5121a232e 13107 if (ctx->myDoc->dict) {
pcercuei 0:03b5121a232e 13108 newDoc->dict = ctx->myDoc->dict;
pcercuei 0:03b5121a232e 13109 xmlDictReference(newDoc->dict);
pcercuei 0:03b5121a232e 13110 }
pcercuei 0:03b5121a232e 13111 if (ctx->myDoc != NULL) {
pcercuei 0:03b5121a232e 13112 newDoc->intSubset = ctx->myDoc->intSubset;
pcercuei 0:03b5121a232e 13113 newDoc->extSubset = ctx->myDoc->extSubset;
pcercuei 0:03b5121a232e 13114 }
pcercuei 0:03b5121a232e 13115 if (ctx->myDoc->URL != NULL) {
pcercuei 0:03b5121a232e 13116 newDoc->URL = xmlStrdup(ctx->myDoc->URL);
pcercuei 0:03b5121a232e 13117 }
pcercuei 0:03b5121a232e 13118 newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
pcercuei 0:03b5121a232e 13119 if (newRoot == NULL) {
pcercuei 0:03b5121a232e 13120 ctxt->sax = oldsax;
pcercuei 0:03b5121a232e 13121 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 13122 newDoc->intSubset = NULL;
pcercuei 0:03b5121a232e 13123 newDoc->extSubset = NULL;
pcercuei 0:03b5121a232e 13124 xmlFreeDoc(newDoc);
pcercuei 0:03b5121a232e 13125 return(-1);
pcercuei 0:03b5121a232e 13126 }
pcercuei 0:03b5121a232e 13127 xmlAddChild((xmlNodePtr) newDoc, newRoot);
pcercuei 0:03b5121a232e 13128 nodePush(ctxt, newDoc->children);
pcercuei 0:03b5121a232e 13129 if (ctx->myDoc == NULL) {
pcercuei 0:03b5121a232e 13130 ctxt->myDoc = newDoc;
pcercuei 0:03b5121a232e 13131 } else {
pcercuei 0:03b5121a232e 13132 ctxt->myDoc = ctx->myDoc;
pcercuei 0:03b5121a232e 13133 newDoc->children->doc = ctx->myDoc;
pcercuei 0:03b5121a232e 13134 }
pcercuei 0:03b5121a232e 13135
pcercuei 0:03b5121a232e 13136 /*
pcercuei 0:03b5121a232e 13137 * Get the 4 first bytes and decode the charset
pcercuei 0:03b5121a232e 13138 * if enc != XML_CHAR_ENCODING_NONE
pcercuei 0:03b5121a232e 13139 * plug some encoding conversion routines.
pcercuei 0:03b5121a232e 13140 */
pcercuei 0:03b5121a232e 13141 GROW
pcercuei 0:03b5121a232e 13142 if ((ctxt->input->end - ctxt->input->cur) >= 4) {
pcercuei 0:03b5121a232e 13143 start[0] = RAW;
pcercuei 0:03b5121a232e 13144 start[1] = NXT(1);
pcercuei 0:03b5121a232e 13145 start[2] = NXT(2);
pcercuei 0:03b5121a232e 13146 start[3] = NXT(3);
pcercuei 0:03b5121a232e 13147 enc = xmlDetectCharEncoding(start, 4);
pcercuei 0:03b5121a232e 13148 if (enc != XML_CHAR_ENCODING_NONE) {
pcercuei 0:03b5121a232e 13149 xmlSwitchEncoding(ctxt, enc);
pcercuei 0:03b5121a232e 13150 }
pcercuei 0:03b5121a232e 13151 }
pcercuei 0:03b5121a232e 13152
pcercuei 0:03b5121a232e 13153 /*
pcercuei 0:03b5121a232e 13154 * Parse a possible text declaration first
pcercuei 0:03b5121a232e 13155 */
pcercuei 0:03b5121a232e 13156 if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
pcercuei 0:03b5121a232e 13157 xmlParseTextDecl(ctxt);
pcercuei 0:03b5121a232e 13158 /*
pcercuei 0:03b5121a232e 13159 * An XML-1.0 document can't reference an entity not XML-1.0
pcercuei 0:03b5121a232e 13160 */
pcercuei 0:03b5121a232e 13161 if ((xmlStrEqual(ctx->version, BAD_CAST "1.0")) &&
pcercuei 0:03b5121a232e 13162 (!xmlStrEqual(ctxt->input->version, BAD_CAST "1.0"))) {
pcercuei 0:03b5121a232e 13163 xmlFatalErrMsg(ctxt, XML_ERR_VERSION_MISMATCH,
pcercuei 0:03b5121a232e 13164 "Version mismatch between document and entity\n");
pcercuei 0:03b5121a232e 13165 }
pcercuei 0:03b5121a232e 13166 }
pcercuei 0:03b5121a232e 13167
pcercuei 0:03b5121a232e 13168 /*
pcercuei 0:03b5121a232e 13169 * If the user provided its own SAX callbacks then reuse the
pcercuei 0:03b5121a232e 13170 * useData callback field, otherwise the expected setup in a
pcercuei 0:03b5121a232e 13171 * DOM builder is to have userData == ctxt
pcercuei 0:03b5121a232e 13172 */
pcercuei 0:03b5121a232e 13173 if (ctx->userData == ctx)
pcercuei 0:03b5121a232e 13174 ctxt->userData = ctxt;
pcercuei 0:03b5121a232e 13175 else
pcercuei 0:03b5121a232e 13176 ctxt->userData = ctx->userData;
pcercuei 0:03b5121a232e 13177
pcercuei 0:03b5121a232e 13178 /*
pcercuei 0:03b5121a232e 13179 * Doing validity checking on chunk doesn't make sense
pcercuei 0:03b5121a232e 13180 */
pcercuei 0:03b5121a232e 13181 ctxt->instate = XML_PARSER_CONTENT;
pcercuei 0:03b5121a232e 13182 ctxt->validate = ctx->validate;
pcercuei 0:03b5121a232e 13183 ctxt->valid = ctx->valid;
pcercuei 0:03b5121a232e 13184 ctxt->loadsubset = ctx->loadsubset;
pcercuei 0:03b5121a232e 13185 ctxt->depth = ctx->depth + 1;
pcercuei 0:03b5121a232e 13186 ctxt->replaceEntities = ctx->replaceEntities;
pcercuei 0:03b5121a232e 13187 if (ctxt->validate) {
pcercuei 0:03b5121a232e 13188 ctxt->vctxt.error = ctx->vctxt.error;
pcercuei 0:03b5121a232e 13189 ctxt->vctxt.warning = ctx->vctxt.warning;
pcercuei 0:03b5121a232e 13190 } else {
pcercuei 0:03b5121a232e 13191 ctxt->vctxt.error = NULL;
pcercuei 0:03b5121a232e 13192 ctxt->vctxt.warning = NULL;
pcercuei 0:03b5121a232e 13193 }
pcercuei 0:03b5121a232e 13194 ctxt->vctxt.nodeTab = NULL;
pcercuei 0:03b5121a232e 13195 ctxt->vctxt.nodeNr = 0;
pcercuei 0:03b5121a232e 13196 ctxt->vctxt.nodeMax = 0;
pcercuei 0:03b5121a232e 13197 ctxt->vctxt.node = NULL;
pcercuei 0:03b5121a232e 13198 if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
pcercuei 0:03b5121a232e 13199 ctxt->dict = ctx->dict;
pcercuei 0:03b5121a232e 13200 ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
pcercuei 0:03b5121a232e 13201 ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
pcercuei 0:03b5121a232e 13202 ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
pcercuei 0:03b5121a232e 13203 ctxt->dictNames = ctx->dictNames;
pcercuei 0:03b5121a232e 13204 ctxt->attsDefault = ctx->attsDefault;
pcercuei 0:03b5121a232e 13205 ctxt->attsSpecial = ctx->attsSpecial;
pcercuei 0:03b5121a232e 13206 ctxt->linenumbers = ctx->linenumbers;
pcercuei 0:03b5121a232e 13207
pcercuei 0:03b5121a232e 13208 xmlParseContent(ctxt);
pcercuei 0:03b5121a232e 13209
pcercuei 0:03b5121a232e 13210 ctx->validate = ctxt->validate;
pcercuei 0:03b5121a232e 13211 ctx->valid = ctxt->valid;
pcercuei 0:03b5121a232e 13212 if ((RAW == '<') && (NXT(1) == '/')) {
pcercuei 0:03b5121a232e 13213 xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
pcercuei 0:03b5121a232e 13214 } else if (RAW != 0) {
pcercuei 0:03b5121a232e 13215 xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
pcercuei 0:03b5121a232e 13216 }
pcercuei 0:03b5121a232e 13217 if (ctxt->node != newDoc->children) {
pcercuei 0:03b5121a232e 13218 xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
pcercuei 0:03b5121a232e 13219 }
pcercuei 0:03b5121a232e 13220
pcercuei 0:03b5121a232e 13221 if (!ctxt->wellFormed) {
pcercuei 0:03b5121a232e 13222 if (ctxt->errNo == 0)
pcercuei 0:03b5121a232e 13223 ret = 1;
pcercuei 0:03b5121a232e 13224 else
pcercuei 0:03b5121a232e 13225 ret = ctxt->errNo;
pcercuei 0:03b5121a232e 13226 } else {
pcercuei 0:03b5121a232e 13227 if (lst != NULL) {
pcercuei 0:03b5121a232e 13228 xmlNodePtr cur;
pcercuei 0:03b5121a232e 13229
pcercuei 0:03b5121a232e 13230 /*
pcercuei 0:03b5121a232e 13231 * Return the newly created nodeset after unlinking it from
pcercuei 0:03b5121a232e 13232 * they pseudo parent.
pcercuei 0:03b5121a232e 13233 */
pcercuei 0:03b5121a232e 13234 cur = newDoc->children->children;
pcercuei 0:03b5121a232e 13235 *lst = cur;
pcercuei 0:03b5121a232e 13236 while (cur != NULL) {
pcercuei 0:03b5121a232e 13237 cur->parent = NULL;
pcercuei 0:03b5121a232e 13238 cur = cur->next;
pcercuei 0:03b5121a232e 13239 }
pcercuei 0:03b5121a232e 13240 newDoc->children->children = NULL;
pcercuei 0:03b5121a232e 13241 }
pcercuei 0:03b5121a232e 13242 ret = 0;
pcercuei 0:03b5121a232e 13243 }
pcercuei 0:03b5121a232e 13244 ctxt->sax = oldsax;
pcercuei 0:03b5121a232e 13245 ctxt->dict = NULL;
pcercuei 0:03b5121a232e 13246 ctxt->attsDefault = NULL;
pcercuei 0:03b5121a232e 13247 ctxt->attsSpecial = NULL;
pcercuei 0:03b5121a232e 13248 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 13249 newDoc->intSubset = NULL;
pcercuei 0:03b5121a232e 13250 newDoc->extSubset = NULL;
pcercuei 0:03b5121a232e 13251 xmlFreeDoc(newDoc);
pcercuei 0:03b5121a232e 13252
pcercuei 0:03b5121a232e 13253 return(ret);
pcercuei 0:03b5121a232e 13254 }
pcercuei 0:03b5121a232e 13255
pcercuei 0:03b5121a232e 13256 /**
pcercuei 0:03b5121a232e 13257 * xmlParseExternalEntityPrivate:
pcercuei 0:03b5121a232e 13258 * @doc: the document the chunk pertains to
pcercuei 0:03b5121a232e 13259 * @oldctxt: the previous parser context if available
pcercuei 0:03b5121a232e 13260 * @sax: the SAX handler bloc (possibly NULL)
pcercuei 0:03b5121a232e 13261 * @user_data: The user data returned on SAX callbacks (possibly NULL)
pcercuei 0:03b5121a232e 13262 * @depth: Used for loop detection, use 0
pcercuei 0:03b5121a232e 13263 * @URL: the URL for the entity to load
pcercuei 0:03b5121a232e 13264 * @ID: the System ID for the entity to load
pcercuei 0:03b5121a232e 13265 * @list: the return value for the set of parsed nodes
pcercuei 0:03b5121a232e 13266 *
pcercuei 0:03b5121a232e 13267 * Private version of xmlParseExternalEntity()
pcercuei 0:03b5121a232e 13268 *
pcercuei 0:03b5121a232e 13269 * Returns 0 if the entity is well formed, -1 in case of args problem and
pcercuei 0:03b5121a232e 13270 * the parser error code otherwise
pcercuei 0:03b5121a232e 13271 */
pcercuei 0:03b5121a232e 13272
pcercuei 0:03b5121a232e 13273 static xmlParserErrors
pcercuei 0:03b5121a232e 13274 xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
pcercuei 0:03b5121a232e 13275 xmlSAXHandlerPtr sax,
pcercuei 0:03b5121a232e 13276 void *user_data, int depth, const xmlChar *URL,
pcercuei 0:03b5121a232e 13277 const xmlChar *ID, xmlNodePtr *list) {
pcercuei 0:03b5121a232e 13278 xmlParserCtxtPtr ctxt;
pcercuei 0:03b5121a232e 13279 xmlDocPtr newDoc;
pcercuei 0:03b5121a232e 13280 xmlNodePtr newRoot;
pcercuei 0:03b5121a232e 13281 xmlSAXHandlerPtr oldsax = NULL;
pcercuei 0:03b5121a232e 13282 xmlParserErrors ret = XML_ERR_OK;
pcercuei 0:03b5121a232e 13283 xmlChar start[4];
pcercuei 0:03b5121a232e 13284 xmlCharEncoding enc;
pcercuei 0:03b5121a232e 13285
pcercuei 0:03b5121a232e 13286 if (((depth > 40) &&
pcercuei 0:03b5121a232e 13287 ((oldctxt == NULL) || (oldctxt->options & XML_PARSE_HUGE) == 0)) ||
pcercuei 0:03b5121a232e 13288 (depth > 1024)) {
pcercuei 0:03b5121a232e 13289 return(XML_ERR_ENTITY_LOOP);
pcercuei 0:03b5121a232e 13290 }
pcercuei 0:03b5121a232e 13291
pcercuei 0:03b5121a232e 13292 if (list != NULL)
pcercuei 0:03b5121a232e 13293 *list = NULL;
pcercuei 0:03b5121a232e 13294 if ((URL == NULL) && (ID == NULL))
pcercuei 0:03b5121a232e 13295 return(XML_ERR_INTERNAL_ERROR);
pcercuei 0:03b5121a232e 13296 if (doc == NULL)
pcercuei 0:03b5121a232e 13297 return(XML_ERR_INTERNAL_ERROR);
pcercuei 0:03b5121a232e 13298
pcercuei 0:03b5121a232e 13299
pcercuei 0:03b5121a232e 13300 ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, oldctxt);
pcercuei 0:03b5121a232e 13301 if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
pcercuei 0:03b5121a232e 13302 ctxt->userData = ctxt;
pcercuei 0:03b5121a232e 13303 if (oldctxt != NULL) {
pcercuei 0:03b5121a232e 13304 ctxt->_private = oldctxt->_private;
pcercuei 0:03b5121a232e 13305 ctxt->loadsubset = oldctxt->loadsubset;
pcercuei 0:03b5121a232e 13306 ctxt->validate = oldctxt->validate;
pcercuei 0:03b5121a232e 13307 ctxt->external = oldctxt->external;
pcercuei 0:03b5121a232e 13308 ctxt->record_info = oldctxt->record_info;
pcercuei 0:03b5121a232e 13309 ctxt->node_seq.maximum = oldctxt->node_seq.maximum;
pcercuei 0:03b5121a232e 13310 ctxt->node_seq.length = oldctxt->node_seq.length;
pcercuei 0:03b5121a232e 13311 ctxt->node_seq.buffer = oldctxt->node_seq.buffer;
pcercuei 0:03b5121a232e 13312 } else {
pcercuei 0:03b5121a232e 13313 /*
pcercuei 0:03b5121a232e 13314 * Doing validity checking on chunk without context
pcercuei 0:03b5121a232e 13315 * doesn't make sense
pcercuei 0:03b5121a232e 13316 */
pcercuei 0:03b5121a232e 13317 ctxt->_private = NULL;
pcercuei 0:03b5121a232e 13318 ctxt->validate = 0;
pcercuei 0:03b5121a232e 13319 ctxt->external = 2;
pcercuei 0:03b5121a232e 13320 ctxt->loadsubset = 0;
pcercuei 0:03b5121a232e 13321 }
pcercuei 0:03b5121a232e 13322 if (sax != NULL) {
pcercuei 0:03b5121a232e 13323 oldsax = ctxt->sax;
pcercuei 0:03b5121a232e 13324 ctxt->sax = sax;
pcercuei 0:03b5121a232e 13325 if (user_data != NULL)
pcercuei 0:03b5121a232e 13326 ctxt->userData = user_data;
pcercuei 0:03b5121a232e 13327 }
pcercuei 0:03b5121a232e 13328 xmlDetectSAX2(ctxt);
pcercuei 0:03b5121a232e 13329 newDoc = xmlNewDoc(BAD_CAST "1.0");
pcercuei 0:03b5121a232e 13330 if (newDoc == NULL) {
pcercuei 0:03b5121a232e 13331 ctxt->node_seq.maximum = 0;
pcercuei 0:03b5121a232e 13332 ctxt->node_seq.length = 0;
pcercuei 0:03b5121a232e 13333 ctxt->node_seq.buffer = NULL;
pcercuei 0:03b5121a232e 13334 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 13335 return(XML_ERR_INTERNAL_ERROR);
pcercuei 0:03b5121a232e 13336 }
pcercuei 0:03b5121a232e 13337 newDoc->properties = XML_DOC_INTERNAL;
pcercuei 0:03b5121a232e 13338 newDoc->intSubset = doc->intSubset;
pcercuei 0:03b5121a232e 13339 newDoc->extSubset = doc->extSubset;
pcercuei 0:03b5121a232e 13340 newDoc->dict = doc->dict;
pcercuei 0:03b5121a232e 13341 xmlDictReference(newDoc->dict);
pcercuei 0:03b5121a232e 13342
pcercuei 0:03b5121a232e 13343 if (doc->URL != NULL) {
pcercuei 0:03b5121a232e 13344 newDoc->URL = xmlStrdup(doc->URL);
pcercuei 0:03b5121a232e 13345 }
pcercuei 0:03b5121a232e 13346 newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
pcercuei 0:03b5121a232e 13347 if (newRoot == NULL) {
pcercuei 0:03b5121a232e 13348 if (sax != NULL)
pcercuei 0:03b5121a232e 13349 ctxt->sax = oldsax;
pcercuei 0:03b5121a232e 13350 ctxt->node_seq.maximum = 0;
pcercuei 0:03b5121a232e 13351 ctxt->node_seq.length = 0;
pcercuei 0:03b5121a232e 13352 ctxt->node_seq.buffer = NULL;
pcercuei 0:03b5121a232e 13353 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 13354 newDoc->intSubset = NULL;
pcercuei 0:03b5121a232e 13355 newDoc->extSubset = NULL;
pcercuei 0:03b5121a232e 13356 xmlFreeDoc(newDoc);
pcercuei 0:03b5121a232e 13357 return(XML_ERR_INTERNAL_ERROR);
pcercuei 0:03b5121a232e 13358 }
pcercuei 0:03b5121a232e 13359 xmlAddChild((xmlNodePtr) newDoc, newRoot);
pcercuei 0:03b5121a232e 13360 nodePush(ctxt, newDoc->children);
pcercuei 0:03b5121a232e 13361 ctxt->myDoc = doc;
pcercuei 0:03b5121a232e 13362 newRoot->doc = doc;
pcercuei 0:03b5121a232e 13363
pcercuei 0:03b5121a232e 13364 /*
pcercuei 0:03b5121a232e 13365 * Get the 4 first bytes and decode the charset
pcercuei 0:03b5121a232e 13366 * if enc != XML_CHAR_ENCODING_NONE
pcercuei 0:03b5121a232e 13367 * plug some encoding conversion routines.
pcercuei 0:03b5121a232e 13368 */
pcercuei 0:03b5121a232e 13369 GROW;
pcercuei 0:03b5121a232e 13370 if ((ctxt->input->end - ctxt->input->cur) >= 4) {
pcercuei 0:03b5121a232e 13371 start[0] = RAW;
pcercuei 0:03b5121a232e 13372 start[1] = NXT(1);
pcercuei 0:03b5121a232e 13373 start[2] = NXT(2);
pcercuei 0:03b5121a232e 13374 start[3] = NXT(3);
pcercuei 0:03b5121a232e 13375 enc = xmlDetectCharEncoding(start, 4);
pcercuei 0:03b5121a232e 13376 if (enc != XML_CHAR_ENCODING_NONE) {
pcercuei 0:03b5121a232e 13377 xmlSwitchEncoding(ctxt, enc);
pcercuei 0:03b5121a232e 13378 }
pcercuei 0:03b5121a232e 13379 }
pcercuei 0:03b5121a232e 13380
pcercuei 0:03b5121a232e 13381 /*
pcercuei 0:03b5121a232e 13382 * Parse a possible text declaration first
pcercuei 0:03b5121a232e 13383 */
pcercuei 0:03b5121a232e 13384 if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
pcercuei 0:03b5121a232e 13385 xmlParseTextDecl(ctxt);
pcercuei 0:03b5121a232e 13386 }
pcercuei 0:03b5121a232e 13387
pcercuei 0:03b5121a232e 13388 ctxt->instate = XML_PARSER_CONTENT;
pcercuei 0:03b5121a232e 13389 ctxt->depth = depth;
pcercuei 0:03b5121a232e 13390
pcercuei 0:03b5121a232e 13391 xmlParseContent(ctxt);
pcercuei 0:03b5121a232e 13392
pcercuei 0:03b5121a232e 13393 if ((RAW == '<') && (NXT(1) == '/')) {
pcercuei 0:03b5121a232e 13394 xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
pcercuei 0:03b5121a232e 13395 } else if (RAW != 0) {
pcercuei 0:03b5121a232e 13396 xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
pcercuei 0:03b5121a232e 13397 }
pcercuei 0:03b5121a232e 13398 if (ctxt->node != newDoc->children) {
pcercuei 0:03b5121a232e 13399 xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
pcercuei 0:03b5121a232e 13400 }
pcercuei 0:03b5121a232e 13401
pcercuei 0:03b5121a232e 13402 if (!ctxt->wellFormed) {
pcercuei 0:03b5121a232e 13403 if (ctxt->errNo == 0)
pcercuei 0:03b5121a232e 13404 ret = XML_ERR_INTERNAL_ERROR;
pcercuei 0:03b5121a232e 13405 else
pcercuei 0:03b5121a232e 13406 ret = (xmlParserErrors)ctxt->errNo;
pcercuei 0:03b5121a232e 13407 } else {
pcercuei 0:03b5121a232e 13408 if (list != NULL) {
pcercuei 0:03b5121a232e 13409 xmlNodePtr cur;
pcercuei 0:03b5121a232e 13410
pcercuei 0:03b5121a232e 13411 /*
pcercuei 0:03b5121a232e 13412 * Return the newly created nodeset after unlinking it from
pcercuei 0:03b5121a232e 13413 * they pseudo parent.
pcercuei 0:03b5121a232e 13414 */
pcercuei 0:03b5121a232e 13415 cur = newDoc->children->children;
pcercuei 0:03b5121a232e 13416 *list = cur;
pcercuei 0:03b5121a232e 13417 while (cur != NULL) {
pcercuei 0:03b5121a232e 13418 cur->parent = NULL;
pcercuei 0:03b5121a232e 13419 cur = cur->next;
pcercuei 0:03b5121a232e 13420 }
pcercuei 0:03b5121a232e 13421 newDoc->children->children = NULL;
pcercuei 0:03b5121a232e 13422 }
pcercuei 0:03b5121a232e 13423 ret = XML_ERR_OK;
pcercuei 0:03b5121a232e 13424 }
pcercuei 0:03b5121a232e 13425
pcercuei 0:03b5121a232e 13426 /*
pcercuei 0:03b5121a232e 13427 * Record in the parent context the number of entities replacement
pcercuei 0:03b5121a232e 13428 * done when parsing that reference.
pcercuei 0:03b5121a232e 13429 */
pcercuei 0:03b5121a232e 13430 if (oldctxt != NULL)
pcercuei 0:03b5121a232e 13431 oldctxt->nbentities += ctxt->nbentities;
pcercuei 0:03b5121a232e 13432
pcercuei 0:03b5121a232e 13433 /*
pcercuei 0:03b5121a232e 13434 * Also record the size of the entity parsed
pcercuei 0:03b5121a232e 13435 */
pcercuei 0:03b5121a232e 13436 if (ctxt->input != NULL && oldctxt != NULL) {
pcercuei 0:03b5121a232e 13437 oldctxt->sizeentities += ctxt->input->consumed;
pcercuei 0:03b5121a232e 13438 oldctxt->sizeentities += (ctxt->input->cur - ctxt->input->base);
pcercuei 0:03b5121a232e 13439 }
pcercuei 0:03b5121a232e 13440 /*
pcercuei 0:03b5121a232e 13441 * And record the last error if any
pcercuei 0:03b5121a232e 13442 */
pcercuei 0:03b5121a232e 13443 if (ctxt->lastError.code != XML_ERR_OK)
pcercuei 0:03b5121a232e 13444 xmlCopyError(&ctxt->lastError, &oldctxt->lastError);
pcercuei 0:03b5121a232e 13445
pcercuei 0:03b5121a232e 13446 if (sax != NULL)
pcercuei 0:03b5121a232e 13447 ctxt->sax = oldsax;
pcercuei 0:03b5121a232e 13448 if (oldctxt != NULL) {
pcercuei 0:03b5121a232e 13449 oldctxt->node_seq.maximum = ctxt->node_seq.maximum;
pcercuei 0:03b5121a232e 13450 oldctxt->node_seq.length = ctxt->node_seq.length;
pcercuei 0:03b5121a232e 13451 oldctxt->node_seq.buffer = ctxt->node_seq.buffer;
pcercuei 0:03b5121a232e 13452 }
pcercuei 0:03b5121a232e 13453 ctxt->node_seq.maximum = 0;
pcercuei 0:03b5121a232e 13454 ctxt->node_seq.length = 0;
pcercuei 0:03b5121a232e 13455 ctxt->node_seq.buffer = NULL;
pcercuei 0:03b5121a232e 13456 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 13457 newDoc->intSubset = NULL;
pcercuei 0:03b5121a232e 13458 newDoc->extSubset = NULL;
pcercuei 0:03b5121a232e 13459 xmlFreeDoc(newDoc);
pcercuei 0:03b5121a232e 13460
pcercuei 0:03b5121a232e 13461 return(ret);
pcercuei 0:03b5121a232e 13462 }
pcercuei 0:03b5121a232e 13463
pcercuei 0:03b5121a232e 13464 #ifdef LIBXML_SAX1_ENABLED
pcercuei 0:03b5121a232e 13465 /**
pcercuei 0:03b5121a232e 13466 * xmlParseExternalEntity:
pcercuei 0:03b5121a232e 13467 * @doc: the document the chunk pertains to
pcercuei 0:03b5121a232e 13468 * @sax: the SAX handler bloc (possibly NULL)
pcercuei 0:03b5121a232e 13469 * @user_data: The user data returned on SAX callbacks (possibly NULL)
pcercuei 0:03b5121a232e 13470 * @depth: Used for loop detection, use 0
pcercuei 0:03b5121a232e 13471 * @URL: the URL for the entity to load
pcercuei 0:03b5121a232e 13472 * @ID: the System ID for the entity to load
pcercuei 0:03b5121a232e 13473 * @lst: the return value for the set of parsed nodes
pcercuei 0:03b5121a232e 13474 *
pcercuei 0:03b5121a232e 13475 * Parse an external general entity
pcercuei 0:03b5121a232e 13476 * An external general parsed entity is well-formed if it matches the
pcercuei 0:03b5121a232e 13477 * production labeled extParsedEnt.
pcercuei 0:03b5121a232e 13478 *
pcercuei 0:03b5121a232e 13479 * [78] extParsedEnt ::= TextDecl? content
pcercuei 0:03b5121a232e 13480 *
pcercuei 0:03b5121a232e 13481 * Returns 0 if the entity is well formed, -1 in case of args problem and
pcercuei 0:03b5121a232e 13482 * the parser error code otherwise
pcercuei 0:03b5121a232e 13483 */
pcercuei 0:03b5121a232e 13484
pcercuei 0:03b5121a232e 13485 int
pcercuei 0:03b5121a232e 13486 xmlParseExternalEntity(xmlDocPtr doc, xmlSAXHandlerPtr sax, void *user_data,
pcercuei 0:03b5121a232e 13487 int depth, const xmlChar *URL, const xmlChar *ID, xmlNodePtr *lst) {
pcercuei 0:03b5121a232e 13488 return(xmlParseExternalEntityPrivate(doc, NULL, sax, user_data, depth, URL,
pcercuei 0:03b5121a232e 13489 ID, lst));
pcercuei 0:03b5121a232e 13490 }
pcercuei 0:03b5121a232e 13491
pcercuei 0:03b5121a232e 13492 /**
pcercuei 0:03b5121a232e 13493 * xmlParseBalancedChunkMemory:
pcercuei 0:03b5121a232e 13494 * @doc: the document the chunk pertains to
pcercuei 0:03b5121a232e 13495 * @sax: the SAX handler bloc (possibly NULL)
pcercuei 0:03b5121a232e 13496 * @user_data: The user data returned on SAX callbacks (possibly NULL)
pcercuei 0:03b5121a232e 13497 * @depth: Used for loop detection, use 0
pcercuei 0:03b5121a232e 13498 * @string: the input string in UTF8 or ISO-Latin (zero terminated)
pcercuei 0:03b5121a232e 13499 * @lst: the return value for the set of parsed nodes
pcercuei 0:03b5121a232e 13500 *
pcercuei 0:03b5121a232e 13501 * Parse a well-balanced chunk of an XML document
pcercuei 0:03b5121a232e 13502 * called by the parser
pcercuei 0:03b5121a232e 13503 * The allowed sequence for the Well Balanced Chunk is the one defined by
pcercuei 0:03b5121a232e 13504 * the content production in the XML grammar:
pcercuei 0:03b5121a232e 13505 *
pcercuei 0:03b5121a232e 13506 * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
pcercuei 0:03b5121a232e 13507 *
pcercuei 0:03b5121a232e 13508 * Returns 0 if the chunk is well balanced, -1 in case of args problem and
pcercuei 0:03b5121a232e 13509 * the parser error code otherwise
pcercuei 0:03b5121a232e 13510 */
pcercuei 0:03b5121a232e 13511
pcercuei 0:03b5121a232e 13512 int
pcercuei 0:03b5121a232e 13513 xmlParseBalancedChunkMemory(xmlDocPtr doc, xmlSAXHandlerPtr sax,
pcercuei 0:03b5121a232e 13514 void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst) {
pcercuei 0:03b5121a232e 13515 return xmlParseBalancedChunkMemoryRecover( doc, sax, user_data,
pcercuei 0:03b5121a232e 13516 depth, string, lst, 0 );
pcercuei 0:03b5121a232e 13517 }
pcercuei 0:03b5121a232e 13518 #endif /* LIBXML_SAX1_ENABLED */
pcercuei 0:03b5121a232e 13519
pcercuei 0:03b5121a232e 13520 /**
pcercuei 0:03b5121a232e 13521 * xmlParseBalancedChunkMemoryInternal:
pcercuei 0:03b5121a232e 13522 * @oldctxt: the existing parsing context
pcercuei 0:03b5121a232e 13523 * @string: the input string in UTF8 or ISO-Latin (zero terminated)
pcercuei 0:03b5121a232e 13524 * @user_data: the user data field for the parser context
pcercuei 0:03b5121a232e 13525 * @lst: the return value for the set of parsed nodes
pcercuei 0:03b5121a232e 13526 *
pcercuei 0:03b5121a232e 13527 *
pcercuei 0:03b5121a232e 13528 * Parse a well-balanced chunk of an XML document
pcercuei 0:03b5121a232e 13529 * called by the parser
pcercuei 0:03b5121a232e 13530 * The allowed sequence for the Well Balanced Chunk is the one defined by
pcercuei 0:03b5121a232e 13531 * the content production in the XML grammar:
pcercuei 0:03b5121a232e 13532 *
pcercuei 0:03b5121a232e 13533 * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
pcercuei 0:03b5121a232e 13534 *
pcercuei 0:03b5121a232e 13535 * Returns XML_ERR_OK if the chunk is well balanced, and the parser
pcercuei 0:03b5121a232e 13536 * error code otherwise
pcercuei 0:03b5121a232e 13537 *
pcercuei 0:03b5121a232e 13538 * In case recover is set to 1, the nodelist will not be empty even if
pcercuei 0:03b5121a232e 13539 * the parsed chunk is not well balanced.
pcercuei 0:03b5121a232e 13540 */
pcercuei 0:03b5121a232e 13541 static xmlParserErrors
pcercuei 0:03b5121a232e 13542 xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
pcercuei 0:03b5121a232e 13543 const xmlChar *string, void *user_data, xmlNodePtr *lst) {
pcercuei 0:03b5121a232e 13544 xmlParserCtxtPtr ctxt;
pcercuei 0:03b5121a232e 13545 xmlDocPtr newDoc = NULL;
pcercuei 0:03b5121a232e 13546 xmlNodePtr newRoot;
pcercuei 0:03b5121a232e 13547 xmlSAXHandlerPtr oldsax = NULL;
pcercuei 0:03b5121a232e 13548 xmlNodePtr content = NULL;
pcercuei 0:03b5121a232e 13549 xmlNodePtr last = NULL;
pcercuei 0:03b5121a232e 13550 int size;
pcercuei 0:03b5121a232e 13551 xmlParserErrors ret = XML_ERR_OK;
pcercuei 0:03b5121a232e 13552 #ifdef SAX2
pcercuei 0:03b5121a232e 13553 int i;
pcercuei 0:03b5121a232e 13554 #endif
pcercuei 0:03b5121a232e 13555
pcercuei 0:03b5121a232e 13556 if (((oldctxt->depth > 40) && ((oldctxt->options & XML_PARSE_HUGE) == 0)) ||
pcercuei 0:03b5121a232e 13557 (oldctxt->depth > 1024)) {
pcercuei 0:03b5121a232e 13558 return(XML_ERR_ENTITY_LOOP);
pcercuei 0:03b5121a232e 13559 }
pcercuei 0:03b5121a232e 13560
pcercuei 0:03b5121a232e 13561
pcercuei 0:03b5121a232e 13562 if (lst != NULL)
pcercuei 0:03b5121a232e 13563 *lst = NULL;
pcercuei 0:03b5121a232e 13564 if (string == NULL)
pcercuei 0:03b5121a232e 13565 return(XML_ERR_INTERNAL_ERROR);
pcercuei 0:03b5121a232e 13566
pcercuei 0:03b5121a232e 13567 size = xmlStrlen(string);
pcercuei 0:03b5121a232e 13568
pcercuei 0:03b5121a232e 13569 ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
pcercuei 0:03b5121a232e 13570 if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
pcercuei 0:03b5121a232e 13571 if (user_data != NULL)
pcercuei 0:03b5121a232e 13572 ctxt->userData = user_data;
pcercuei 0:03b5121a232e 13573 else
pcercuei 0:03b5121a232e 13574 ctxt->userData = ctxt;
pcercuei 0:03b5121a232e 13575 if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
pcercuei 0:03b5121a232e 13576 ctxt->dict = oldctxt->dict;
pcercuei 0:03b5121a232e 13577 ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
pcercuei 0:03b5121a232e 13578 ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
pcercuei 0:03b5121a232e 13579 ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
pcercuei 0:03b5121a232e 13580
pcercuei 0:03b5121a232e 13581 #ifdef SAX2
pcercuei 0:03b5121a232e 13582 /* propagate namespaces down the entity */
pcercuei 0:03b5121a232e 13583 for (i = 0;i < oldctxt->nsNr;i += 2) {
pcercuei 0:03b5121a232e 13584 nsPush(ctxt, oldctxt->nsTab[i], oldctxt->nsTab[i+1]);
pcercuei 0:03b5121a232e 13585 }
pcercuei 0:03b5121a232e 13586 #endif
pcercuei 0:03b5121a232e 13587
pcercuei 0:03b5121a232e 13588 oldsax = ctxt->sax;
pcercuei 0:03b5121a232e 13589 ctxt->sax = oldctxt->sax;
pcercuei 0:03b5121a232e 13590 xmlDetectSAX2(ctxt);
pcercuei 0:03b5121a232e 13591 ctxt->replaceEntities = oldctxt->replaceEntities;
pcercuei 0:03b5121a232e 13592 ctxt->options = oldctxt->options;
pcercuei 0:03b5121a232e 13593
pcercuei 0:03b5121a232e 13594 ctxt->_private = oldctxt->_private;
pcercuei 0:03b5121a232e 13595 if (oldctxt->myDoc == NULL) {
pcercuei 0:03b5121a232e 13596 newDoc = xmlNewDoc(BAD_CAST "1.0");
pcercuei 0:03b5121a232e 13597 if (newDoc == NULL) {
pcercuei 0:03b5121a232e 13598 ctxt->sax = oldsax;
pcercuei 0:03b5121a232e 13599 ctxt->dict = NULL;
pcercuei 0:03b5121a232e 13600 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 13601 return(XML_ERR_INTERNAL_ERROR);
pcercuei 0:03b5121a232e 13602 }
pcercuei 0:03b5121a232e 13603 newDoc->properties = XML_DOC_INTERNAL;
pcercuei 0:03b5121a232e 13604 newDoc->dict = ctxt->dict;
pcercuei 0:03b5121a232e 13605 xmlDictReference(newDoc->dict);
pcercuei 0:03b5121a232e 13606 ctxt->myDoc = newDoc;
pcercuei 0:03b5121a232e 13607 } else {
pcercuei 0:03b5121a232e 13608 ctxt->myDoc = oldctxt->myDoc;
pcercuei 0:03b5121a232e 13609 content = ctxt->myDoc->children;
pcercuei 0:03b5121a232e 13610 last = ctxt->myDoc->last;
pcercuei 0:03b5121a232e 13611 }
pcercuei 0:03b5121a232e 13612 newRoot = xmlNewDocNode(ctxt->myDoc, NULL, BAD_CAST "pseudoroot", NULL);
pcercuei 0:03b5121a232e 13613 if (newRoot == NULL) {
pcercuei 0:03b5121a232e 13614 ctxt->sax = oldsax;
pcercuei 0:03b5121a232e 13615 ctxt->dict = NULL;
pcercuei 0:03b5121a232e 13616 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 13617 if (newDoc != NULL) {
pcercuei 0:03b5121a232e 13618 xmlFreeDoc(newDoc);
pcercuei 0:03b5121a232e 13619 }
pcercuei 0:03b5121a232e 13620 return(XML_ERR_INTERNAL_ERROR);
pcercuei 0:03b5121a232e 13621 }
pcercuei 0:03b5121a232e 13622 ctxt->myDoc->children = NULL;
pcercuei 0:03b5121a232e 13623 ctxt->myDoc->last = NULL;
pcercuei 0:03b5121a232e 13624 xmlAddChild((xmlNodePtr) ctxt->myDoc, newRoot);
pcercuei 0:03b5121a232e 13625 nodePush(ctxt, ctxt->myDoc->children);
pcercuei 0:03b5121a232e 13626 ctxt->instate = XML_PARSER_CONTENT;
pcercuei 0:03b5121a232e 13627 ctxt->depth = oldctxt->depth + 1;
pcercuei 0:03b5121a232e 13628
pcercuei 0:03b5121a232e 13629 ctxt->validate = 0;
pcercuei 0:03b5121a232e 13630 ctxt->loadsubset = oldctxt->loadsubset;
pcercuei 0:03b5121a232e 13631 if ((oldctxt->validate) || (oldctxt->replaceEntities != 0)) {
pcercuei 0:03b5121a232e 13632 /*
pcercuei 0:03b5121a232e 13633 * ID/IDREF registration will be done in xmlValidateElement below
pcercuei 0:03b5121a232e 13634 */
pcercuei 0:03b5121a232e 13635 ctxt->loadsubset |= XML_SKIP_IDS;
pcercuei 0:03b5121a232e 13636 }
pcercuei 0:03b5121a232e 13637 ctxt->dictNames = oldctxt->dictNames;
pcercuei 0:03b5121a232e 13638 ctxt->attsDefault = oldctxt->attsDefault;
pcercuei 0:03b5121a232e 13639 ctxt->attsSpecial = oldctxt->attsSpecial;
pcercuei 0:03b5121a232e 13640
pcercuei 0:03b5121a232e 13641 xmlParseContent(ctxt);
pcercuei 0:03b5121a232e 13642 if ((RAW == '<') && (NXT(1) == '/')) {
pcercuei 0:03b5121a232e 13643 xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
pcercuei 0:03b5121a232e 13644 } else if (RAW != 0) {
pcercuei 0:03b5121a232e 13645 xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
pcercuei 0:03b5121a232e 13646 }
pcercuei 0:03b5121a232e 13647 if (ctxt->node != ctxt->myDoc->children) {
pcercuei 0:03b5121a232e 13648 xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
pcercuei 0:03b5121a232e 13649 }
pcercuei 0:03b5121a232e 13650
pcercuei 0:03b5121a232e 13651 if (!ctxt->wellFormed) {
pcercuei 0:03b5121a232e 13652 if (ctxt->errNo == 0)
pcercuei 0:03b5121a232e 13653 ret = XML_ERR_INTERNAL_ERROR;
pcercuei 0:03b5121a232e 13654 else
pcercuei 0:03b5121a232e 13655 ret = (xmlParserErrors)ctxt->errNo;
pcercuei 0:03b5121a232e 13656 } else {
pcercuei 0:03b5121a232e 13657 ret = XML_ERR_OK;
pcercuei 0:03b5121a232e 13658 }
pcercuei 0:03b5121a232e 13659
pcercuei 0:03b5121a232e 13660 if ((lst != NULL) && (ret == XML_ERR_OK)) {
pcercuei 0:03b5121a232e 13661 xmlNodePtr cur;
pcercuei 0:03b5121a232e 13662
pcercuei 0:03b5121a232e 13663 /*
pcercuei 0:03b5121a232e 13664 * Return the newly created nodeset after unlinking it from
pcercuei 0:03b5121a232e 13665 * they pseudo parent.
pcercuei 0:03b5121a232e 13666 */
pcercuei 0:03b5121a232e 13667 cur = ctxt->myDoc->children->children;
pcercuei 0:03b5121a232e 13668 *lst = cur;
pcercuei 0:03b5121a232e 13669 while (cur != NULL) {
pcercuei 0:03b5121a232e 13670 #ifdef LIBXML_VALID_ENABLED
pcercuei 0:03b5121a232e 13671 if ((oldctxt->validate) && (oldctxt->wellFormed) &&
pcercuei 0:03b5121a232e 13672 (oldctxt->myDoc) && (oldctxt->myDoc->intSubset) &&
pcercuei 0:03b5121a232e 13673 (cur->type == XML_ELEMENT_NODE)) {
pcercuei 0:03b5121a232e 13674 oldctxt->valid &= xmlValidateElement(&oldctxt->vctxt,
pcercuei 0:03b5121a232e 13675 oldctxt->myDoc, cur);
pcercuei 0:03b5121a232e 13676 }
pcercuei 0:03b5121a232e 13677 #endif /* LIBXML_VALID_ENABLED */
pcercuei 0:03b5121a232e 13678 cur->parent = NULL;
pcercuei 0:03b5121a232e 13679 cur = cur->next;
pcercuei 0:03b5121a232e 13680 }
pcercuei 0:03b5121a232e 13681 ctxt->myDoc->children->children = NULL;
pcercuei 0:03b5121a232e 13682 }
pcercuei 0:03b5121a232e 13683 if (ctxt->myDoc != NULL) {
pcercuei 0:03b5121a232e 13684 xmlFreeNode(ctxt->myDoc->children);
pcercuei 0:03b5121a232e 13685 ctxt->myDoc->children = content;
pcercuei 0:03b5121a232e 13686 ctxt->myDoc->last = last;
pcercuei 0:03b5121a232e 13687 }
pcercuei 0:03b5121a232e 13688
pcercuei 0:03b5121a232e 13689 /*
pcercuei 0:03b5121a232e 13690 * Record in the parent context the number of entities replacement
pcercuei 0:03b5121a232e 13691 * done when parsing that reference.
pcercuei 0:03b5121a232e 13692 */
pcercuei 0:03b5121a232e 13693 if (oldctxt != NULL)
pcercuei 0:03b5121a232e 13694 oldctxt->nbentities += ctxt->nbentities;
pcercuei 0:03b5121a232e 13695
pcercuei 0:03b5121a232e 13696 /*
pcercuei 0:03b5121a232e 13697 * Also record the last error if any
pcercuei 0:03b5121a232e 13698 */
pcercuei 0:03b5121a232e 13699 if (ctxt->lastError.code != XML_ERR_OK)
pcercuei 0:03b5121a232e 13700 xmlCopyError(&ctxt->lastError, &oldctxt->lastError);
pcercuei 0:03b5121a232e 13701
pcercuei 0:03b5121a232e 13702 ctxt->sax = oldsax;
pcercuei 0:03b5121a232e 13703 ctxt->dict = NULL;
pcercuei 0:03b5121a232e 13704 ctxt->attsDefault = NULL;
pcercuei 0:03b5121a232e 13705 ctxt->attsSpecial = NULL;
pcercuei 0:03b5121a232e 13706 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 13707 if (newDoc != NULL) {
pcercuei 0:03b5121a232e 13708 xmlFreeDoc(newDoc);
pcercuei 0:03b5121a232e 13709 }
pcercuei 0:03b5121a232e 13710
pcercuei 0:03b5121a232e 13711 return(ret);
pcercuei 0:03b5121a232e 13712 }
pcercuei 0:03b5121a232e 13713
pcercuei 0:03b5121a232e 13714 /**
pcercuei 0:03b5121a232e 13715 * xmlParseInNodeContext:
pcercuei 0:03b5121a232e 13716 * @node: the context node
pcercuei 0:03b5121a232e 13717 * @data: the input string
pcercuei 0:03b5121a232e 13718 * @datalen: the input string length in bytes
pcercuei 0:03b5121a232e 13719 * @options: a combination of xmlParserOption
pcercuei 0:03b5121a232e 13720 * @lst: the return value for the set of parsed nodes
pcercuei 0:03b5121a232e 13721 *
pcercuei 0:03b5121a232e 13722 * Parse a well-balanced chunk of an XML document
pcercuei 0:03b5121a232e 13723 * within the context (DTD, namespaces, etc ...) of the given node.
pcercuei 0:03b5121a232e 13724 *
pcercuei 0:03b5121a232e 13725 * The allowed sequence for the data is a Well Balanced Chunk defined by
pcercuei 0:03b5121a232e 13726 * the content production in the XML grammar:
pcercuei 0:03b5121a232e 13727 *
pcercuei 0:03b5121a232e 13728 * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
pcercuei 0:03b5121a232e 13729 *
pcercuei 0:03b5121a232e 13730 * Returns XML_ERR_OK if the chunk is well balanced, and the parser
pcercuei 0:03b5121a232e 13731 * error code otherwise
pcercuei 0:03b5121a232e 13732 */
pcercuei 0:03b5121a232e 13733 xmlParserErrors
pcercuei 0:03b5121a232e 13734 xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen,
pcercuei 0:03b5121a232e 13735 int options, xmlNodePtr *lst) {
pcercuei 0:03b5121a232e 13736 #ifdef SAX2
pcercuei 0:03b5121a232e 13737 xmlParserCtxtPtr ctxt;
pcercuei 0:03b5121a232e 13738 xmlDocPtr doc = NULL;
pcercuei 0:03b5121a232e 13739 xmlNodePtr fake, cur;
pcercuei 0:03b5121a232e 13740 int nsnr = 0;
pcercuei 0:03b5121a232e 13741
pcercuei 0:03b5121a232e 13742 xmlParserErrors ret = XML_ERR_OK;
pcercuei 0:03b5121a232e 13743
pcercuei 0:03b5121a232e 13744 /*
pcercuei 0:03b5121a232e 13745 * check all input parameters, grab the document
pcercuei 0:03b5121a232e 13746 */
pcercuei 0:03b5121a232e 13747 if ((lst == NULL) || (node == NULL) || (data == NULL) || (datalen < 0))
pcercuei 0:03b5121a232e 13748 return(XML_ERR_INTERNAL_ERROR);
pcercuei 0:03b5121a232e 13749 switch (node->type) {
pcercuei 0:03b5121a232e 13750 case XML_ELEMENT_NODE:
pcercuei 0:03b5121a232e 13751 case XML_ATTRIBUTE_NODE:
pcercuei 0:03b5121a232e 13752 case XML_TEXT_NODE:
pcercuei 0:03b5121a232e 13753 case XML_CDATA_SECTION_NODE:
pcercuei 0:03b5121a232e 13754 case XML_ENTITY_REF_NODE:
pcercuei 0:03b5121a232e 13755 case XML_PI_NODE:
pcercuei 0:03b5121a232e 13756 case XML_COMMENT_NODE:
pcercuei 0:03b5121a232e 13757 case XML_DOCUMENT_NODE:
pcercuei 0:03b5121a232e 13758 case XML_HTML_DOCUMENT_NODE:
pcercuei 0:03b5121a232e 13759 break;
pcercuei 0:03b5121a232e 13760 default:
pcercuei 0:03b5121a232e 13761 return(XML_ERR_INTERNAL_ERROR);
pcercuei 0:03b5121a232e 13762
pcercuei 0:03b5121a232e 13763 }
pcercuei 0:03b5121a232e 13764 while ((node != NULL) && (node->type != XML_ELEMENT_NODE) &&
pcercuei 0:03b5121a232e 13765 (node->type != XML_DOCUMENT_NODE) &&
pcercuei 0:03b5121a232e 13766 (node->type != XML_HTML_DOCUMENT_NODE))
pcercuei 0:03b5121a232e 13767 node = node->parent;
pcercuei 0:03b5121a232e 13768 if (node == NULL)
pcercuei 0:03b5121a232e 13769 return(XML_ERR_INTERNAL_ERROR);
pcercuei 0:03b5121a232e 13770 if (node->type == XML_ELEMENT_NODE)
pcercuei 0:03b5121a232e 13771 doc = node->doc;
pcercuei 0:03b5121a232e 13772 else
pcercuei 0:03b5121a232e 13773 doc = (xmlDocPtr) node;
pcercuei 0:03b5121a232e 13774 if (doc == NULL)
pcercuei 0:03b5121a232e 13775 return(XML_ERR_INTERNAL_ERROR);
pcercuei 0:03b5121a232e 13776
pcercuei 0:03b5121a232e 13777 /*
pcercuei 0:03b5121a232e 13778 * allocate a context and set-up everything not related to the
pcercuei 0:03b5121a232e 13779 * node position in the tree
pcercuei 0:03b5121a232e 13780 */
pcercuei 0:03b5121a232e 13781 if (doc->type == XML_DOCUMENT_NODE)
pcercuei 0:03b5121a232e 13782 ctxt = xmlCreateMemoryParserCtxt((char *) data, datalen);
pcercuei 0:03b5121a232e 13783 #ifdef LIBXML_HTML_ENABLED
pcercuei 0:03b5121a232e 13784 else if (doc->type == XML_HTML_DOCUMENT_NODE) {
pcercuei 0:03b5121a232e 13785 ctxt = htmlCreateMemoryParserCtxt((char *) data, datalen);
pcercuei 0:03b5121a232e 13786 /*
pcercuei 0:03b5121a232e 13787 * When parsing in context, it makes no sense to add implied
pcercuei 0:03b5121a232e 13788 * elements like html/body/etc...
pcercuei 0:03b5121a232e 13789 */
pcercuei 0:03b5121a232e 13790 options |= HTML_PARSE_NOIMPLIED;
pcercuei 0:03b5121a232e 13791 }
pcercuei 0:03b5121a232e 13792 #endif
pcercuei 0:03b5121a232e 13793 else
pcercuei 0:03b5121a232e 13794 return(XML_ERR_INTERNAL_ERROR);
pcercuei 0:03b5121a232e 13795
pcercuei 0:03b5121a232e 13796 if (ctxt == NULL)
pcercuei 0:03b5121a232e 13797 return(XML_ERR_NO_MEMORY);
pcercuei 0:03b5121a232e 13798
pcercuei 0:03b5121a232e 13799 /*
pcercuei 0:03b5121a232e 13800 * Use input doc's dict if present, else assure XML_PARSE_NODICT is set.
pcercuei 0:03b5121a232e 13801 * We need a dictionary for xmlDetectSAX2, so if there's no doc dict
pcercuei 0:03b5121a232e 13802 * we must wait until the last moment to free the original one.
pcercuei 0:03b5121a232e 13803 */
pcercuei 0:03b5121a232e 13804 if (doc->dict != NULL) {
pcercuei 0:03b5121a232e 13805 if (ctxt->dict != NULL)
pcercuei 0:03b5121a232e 13806 xmlDictFree(ctxt->dict);
pcercuei 0:03b5121a232e 13807 ctxt->dict = doc->dict;
pcercuei 0:03b5121a232e 13808 } else
pcercuei 0:03b5121a232e 13809 options |= XML_PARSE_NODICT;
pcercuei 0:03b5121a232e 13810
pcercuei 0:03b5121a232e 13811 if (doc->encoding != NULL) {
pcercuei 0:03b5121a232e 13812 xmlCharEncodingHandlerPtr hdlr;
pcercuei 0:03b5121a232e 13813
pcercuei 0:03b5121a232e 13814 if (ctxt->encoding != NULL)
pcercuei 0:03b5121a232e 13815 xmlFree((xmlChar *) ctxt->encoding);
pcercuei 0:03b5121a232e 13816 ctxt->encoding = xmlStrdup((const xmlChar *) doc->encoding);
pcercuei 0:03b5121a232e 13817
pcercuei 0:03b5121a232e 13818 hdlr = xmlFindCharEncodingHandler((const char *) doc->encoding);
pcercuei 0:03b5121a232e 13819 if (hdlr != NULL) {
pcercuei 0:03b5121a232e 13820 xmlSwitchToEncoding(ctxt, hdlr);
pcercuei 0:03b5121a232e 13821 } else {
pcercuei 0:03b5121a232e 13822 return(XML_ERR_UNSUPPORTED_ENCODING);
pcercuei 0:03b5121a232e 13823 }
pcercuei 0:03b5121a232e 13824 }
pcercuei 0:03b5121a232e 13825
pcercuei 0:03b5121a232e 13826 xmlCtxtUseOptionsInternal(ctxt, options, NULL);
pcercuei 0:03b5121a232e 13827 xmlDetectSAX2(ctxt);
pcercuei 0:03b5121a232e 13828 ctxt->myDoc = doc;
pcercuei 0:03b5121a232e 13829 /* parsing in context, i.e. as within existing content */
pcercuei 0:03b5121a232e 13830 ctxt->instate = XML_PARSER_CONTENT;
pcercuei 0:03b5121a232e 13831
pcercuei 0:03b5121a232e 13832 fake = xmlNewComment(NULL);
pcercuei 0:03b5121a232e 13833 if (fake == NULL) {
pcercuei 0:03b5121a232e 13834 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 13835 return(XML_ERR_NO_MEMORY);
pcercuei 0:03b5121a232e 13836 }
pcercuei 0:03b5121a232e 13837 xmlAddChild(node, fake);
pcercuei 0:03b5121a232e 13838
pcercuei 0:03b5121a232e 13839 if (node->type == XML_ELEMENT_NODE) {
pcercuei 0:03b5121a232e 13840 nodePush(ctxt, node);
pcercuei 0:03b5121a232e 13841 /*
pcercuei 0:03b5121a232e 13842 * initialize the SAX2 namespaces stack
pcercuei 0:03b5121a232e 13843 */
pcercuei 0:03b5121a232e 13844 cur = node;
pcercuei 0:03b5121a232e 13845 while ((cur != NULL) && (cur->type == XML_ELEMENT_NODE)) {
pcercuei 0:03b5121a232e 13846 xmlNsPtr ns = cur->nsDef;
pcercuei 0:03b5121a232e 13847 const xmlChar *iprefix, *ihref;
pcercuei 0:03b5121a232e 13848
pcercuei 0:03b5121a232e 13849 while (ns != NULL) {
pcercuei 0:03b5121a232e 13850 if (ctxt->dict) {
pcercuei 0:03b5121a232e 13851 iprefix = xmlDictLookup(ctxt->dict, ns->prefix, -1);
pcercuei 0:03b5121a232e 13852 ihref = xmlDictLookup(ctxt->dict, ns->href, -1);
pcercuei 0:03b5121a232e 13853 } else {
pcercuei 0:03b5121a232e 13854 iprefix = ns->prefix;
pcercuei 0:03b5121a232e 13855 ihref = ns->href;
pcercuei 0:03b5121a232e 13856 }
pcercuei 0:03b5121a232e 13857
pcercuei 0:03b5121a232e 13858 if (xmlGetNamespace(ctxt, iprefix) == NULL) {
pcercuei 0:03b5121a232e 13859 nsPush(ctxt, iprefix, ihref);
pcercuei 0:03b5121a232e 13860 nsnr++;
pcercuei 0:03b5121a232e 13861 }
pcercuei 0:03b5121a232e 13862 ns = ns->next;
pcercuei 0:03b5121a232e 13863 }
pcercuei 0:03b5121a232e 13864 cur = cur->parent;
pcercuei 0:03b5121a232e 13865 }
pcercuei 0:03b5121a232e 13866 }
pcercuei 0:03b5121a232e 13867
pcercuei 0:03b5121a232e 13868 if ((ctxt->validate) || (ctxt->replaceEntities != 0)) {
pcercuei 0:03b5121a232e 13869 /*
pcercuei 0:03b5121a232e 13870 * ID/IDREF registration will be done in xmlValidateElement below
pcercuei 0:03b5121a232e 13871 */
pcercuei 0:03b5121a232e 13872 ctxt->loadsubset |= XML_SKIP_IDS;
pcercuei 0:03b5121a232e 13873 }
pcercuei 0:03b5121a232e 13874
pcercuei 0:03b5121a232e 13875 #ifdef LIBXML_HTML_ENABLED
pcercuei 0:03b5121a232e 13876 if (doc->type == XML_HTML_DOCUMENT_NODE)
pcercuei 0:03b5121a232e 13877 __htmlParseContent(ctxt);
pcercuei 0:03b5121a232e 13878 else
pcercuei 0:03b5121a232e 13879 #endif
pcercuei 0:03b5121a232e 13880 xmlParseContent(ctxt);
pcercuei 0:03b5121a232e 13881
pcercuei 0:03b5121a232e 13882 nsPop(ctxt, nsnr);
pcercuei 0:03b5121a232e 13883 if ((RAW == '<') && (NXT(1) == '/')) {
pcercuei 0:03b5121a232e 13884 xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
pcercuei 0:03b5121a232e 13885 } else if (RAW != 0) {
pcercuei 0:03b5121a232e 13886 xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
pcercuei 0:03b5121a232e 13887 }
pcercuei 0:03b5121a232e 13888 if ((ctxt->node != NULL) && (ctxt->node != node)) {
pcercuei 0:03b5121a232e 13889 xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
pcercuei 0:03b5121a232e 13890 ctxt->wellFormed = 0;
pcercuei 0:03b5121a232e 13891 }
pcercuei 0:03b5121a232e 13892
pcercuei 0:03b5121a232e 13893 if (!ctxt->wellFormed) {
pcercuei 0:03b5121a232e 13894 if (ctxt->errNo == 0)
pcercuei 0:03b5121a232e 13895 ret = XML_ERR_INTERNAL_ERROR;
pcercuei 0:03b5121a232e 13896 else
pcercuei 0:03b5121a232e 13897 ret = (xmlParserErrors)ctxt->errNo;
pcercuei 0:03b5121a232e 13898 } else {
pcercuei 0:03b5121a232e 13899 ret = XML_ERR_OK;
pcercuei 0:03b5121a232e 13900 }
pcercuei 0:03b5121a232e 13901
pcercuei 0:03b5121a232e 13902 /*
pcercuei 0:03b5121a232e 13903 * Return the newly created nodeset after unlinking it from
pcercuei 0:03b5121a232e 13904 * the pseudo sibling.
pcercuei 0:03b5121a232e 13905 */
pcercuei 0:03b5121a232e 13906
pcercuei 0:03b5121a232e 13907 cur = fake->next;
pcercuei 0:03b5121a232e 13908 fake->next = NULL;
pcercuei 0:03b5121a232e 13909 node->last = fake;
pcercuei 0:03b5121a232e 13910
pcercuei 0:03b5121a232e 13911 if (cur != NULL) {
pcercuei 0:03b5121a232e 13912 cur->prev = NULL;
pcercuei 0:03b5121a232e 13913 }
pcercuei 0:03b5121a232e 13914
pcercuei 0:03b5121a232e 13915 *lst = cur;
pcercuei 0:03b5121a232e 13916
pcercuei 0:03b5121a232e 13917 while (cur != NULL) {
pcercuei 0:03b5121a232e 13918 cur->parent = NULL;
pcercuei 0:03b5121a232e 13919 cur = cur->next;
pcercuei 0:03b5121a232e 13920 }
pcercuei 0:03b5121a232e 13921
pcercuei 0:03b5121a232e 13922 xmlUnlinkNode(fake);
pcercuei 0:03b5121a232e 13923 xmlFreeNode(fake);
pcercuei 0:03b5121a232e 13924
pcercuei 0:03b5121a232e 13925
pcercuei 0:03b5121a232e 13926 if (ret != XML_ERR_OK) {
pcercuei 0:03b5121a232e 13927 xmlFreeNodeList(*lst);
pcercuei 0:03b5121a232e 13928 *lst = NULL;
pcercuei 0:03b5121a232e 13929 }
pcercuei 0:03b5121a232e 13930
pcercuei 0:03b5121a232e 13931 if (doc->dict != NULL)
pcercuei 0:03b5121a232e 13932 ctxt->dict = NULL;
pcercuei 0:03b5121a232e 13933 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 13934
pcercuei 0:03b5121a232e 13935 return(ret);
pcercuei 0:03b5121a232e 13936 #else /* !SAX2 */
pcercuei 0:03b5121a232e 13937 return(XML_ERR_INTERNAL_ERROR);
pcercuei 0:03b5121a232e 13938 #endif
pcercuei 0:03b5121a232e 13939 }
pcercuei 0:03b5121a232e 13940
pcercuei 0:03b5121a232e 13941 #ifdef LIBXML_SAX1_ENABLED
pcercuei 0:03b5121a232e 13942 /**
pcercuei 0:03b5121a232e 13943 * xmlParseBalancedChunkMemoryRecover:
pcercuei 0:03b5121a232e 13944 * @doc: the document the chunk pertains to
pcercuei 0:03b5121a232e 13945 * @sax: the SAX handler bloc (possibly NULL)
pcercuei 0:03b5121a232e 13946 * @user_data: The user data returned on SAX callbacks (possibly NULL)
pcercuei 0:03b5121a232e 13947 * @depth: Used for loop detection, use 0
pcercuei 0:03b5121a232e 13948 * @string: the input string in UTF8 or ISO-Latin (zero terminated)
pcercuei 0:03b5121a232e 13949 * @lst: the return value for the set of parsed nodes
pcercuei 0:03b5121a232e 13950 * @recover: return nodes even if the data is broken (use 0)
pcercuei 0:03b5121a232e 13951 *
pcercuei 0:03b5121a232e 13952 *
pcercuei 0:03b5121a232e 13953 * Parse a well-balanced chunk of an XML document
pcercuei 0:03b5121a232e 13954 * called by the parser
pcercuei 0:03b5121a232e 13955 * The allowed sequence for the Well Balanced Chunk is the one defined by
pcercuei 0:03b5121a232e 13956 * the content production in the XML grammar:
pcercuei 0:03b5121a232e 13957 *
pcercuei 0:03b5121a232e 13958 * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
pcercuei 0:03b5121a232e 13959 *
pcercuei 0:03b5121a232e 13960 * Returns 0 if the chunk is well balanced, -1 in case of args problem and
pcercuei 0:03b5121a232e 13961 * the parser error code otherwise
pcercuei 0:03b5121a232e 13962 *
pcercuei 0:03b5121a232e 13963 * In case recover is set to 1, the nodelist will not be empty even if
pcercuei 0:03b5121a232e 13964 * the parsed chunk is not well balanced, assuming the parsing succeeded to
pcercuei 0:03b5121a232e 13965 * some extent.
pcercuei 0:03b5121a232e 13966 */
pcercuei 0:03b5121a232e 13967 int
pcercuei 0:03b5121a232e 13968 xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax,
pcercuei 0:03b5121a232e 13969 void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst,
pcercuei 0:03b5121a232e 13970 int recover) {
pcercuei 0:03b5121a232e 13971 xmlParserCtxtPtr ctxt;
pcercuei 0:03b5121a232e 13972 xmlDocPtr newDoc;
pcercuei 0:03b5121a232e 13973 xmlSAXHandlerPtr oldsax = NULL;
pcercuei 0:03b5121a232e 13974 xmlNodePtr content, newRoot;
pcercuei 0:03b5121a232e 13975 int size;
pcercuei 0:03b5121a232e 13976 int ret = 0;
pcercuei 0:03b5121a232e 13977
pcercuei 0:03b5121a232e 13978 if (depth > 40) {
pcercuei 0:03b5121a232e 13979 return(XML_ERR_ENTITY_LOOP);
pcercuei 0:03b5121a232e 13980 }
pcercuei 0:03b5121a232e 13981
pcercuei 0:03b5121a232e 13982
pcercuei 0:03b5121a232e 13983 if (lst != NULL)
pcercuei 0:03b5121a232e 13984 *lst = NULL;
pcercuei 0:03b5121a232e 13985 if (string == NULL)
pcercuei 0:03b5121a232e 13986 return(-1);
pcercuei 0:03b5121a232e 13987
pcercuei 0:03b5121a232e 13988 size = xmlStrlen(string);
pcercuei 0:03b5121a232e 13989
pcercuei 0:03b5121a232e 13990 ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
pcercuei 0:03b5121a232e 13991 if (ctxt == NULL) return(-1);
pcercuei 0:03b5121a232e 13992 ctxt->userData = ctxt;
pcercuei 0:03b5121a232e 13993 if (sax != NULL) {
pcercuei 0:03b5121a232e 13994 oldsax = ctxt->sax;
pcercuei 0:03b5121a232e 13995 ctxt->sax = sax;
pcercuei 0:03b5121a232e 13996 if (user_data != NULL)
pcercuei 0:03b5121a232e 13997 ctxt->userData = user_data;
pcercuei 0:03b5121a232e 13998 }
pcercuei 0:03b5121a232e 13999 newDoc = xmlNewDoc(BAD_CAST "1.0");
pcercuei 0:03b5121a232e 14000 if (newDoc == NULL) {
pcercuei 0:03b5121a232e 14001 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 14002 return(-1);
pcercuei 0:03b5121a232e 14003 }
pcercuei 0:03b5121a232e 14004 newDoc->properties = XML_DOC_INTERNAL;
pcercuei 0:03b5121a232e 14005 if ((doc != NULL) && (doc->dict != NULL)) {
pcercuei 0:03b5121a232e 14006 xmlDictFree(ctxt->dict);
pcercuei 0:03b5121a232e 14007 ctxt->dict = doc->dict;
pcercuei 0:03b5121a232e 14008 xmlDictReference(ctxt->dict);
pcercuei 0:03b5121a232e 14009 ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
pcercuei 0:03b5121a232e 14010 ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
pcercuei 0:03b5121a232e 14011 ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
pcercuei 0:03b5121a232e 14012 ctxt->dictNames = 1;
pcercuei 0:03b5121a232e 14013 } else {
pcercuei 0:03b5121a232e 14014 xmlCtxtUseOptionsInternal(ctxt, XML_PARSE_NODICT, NULL);
pcercuei 0:03b5121a232e 14015 }
pcercuei 0:03b5121a232e 14016 if (doc != NULL) {
pcercuei 0:03b5121a232e 14017 newDoc->intSubset = doc->intSubset;
pcercuei 0:03b5121a232e 14018 newDoc->extSubset = doc->extSubset;
pcercuei 0:03b5121a232e 14019 }
pcercuei 0:03b5121a232e 14020 newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
pcercuei 0:03b5121a232e 14021 if (newRoot == NULL) {
pcercuei 0:03b5121a232e 14022 if (sax != NULL)
pcercuei 0:03b5121a232e 14023 ctxt->sax = oldsax;
pcercuei 0:03b5121a232e 14024 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 14025 newDoc->intSubset = NULL;
pcercuei 0:03b5121a232e 14026 newDoc->extSubset = NULL;
pcercuei 0:03b5121a232e 14027 xmlFreeDoc(newDoc);
pcercuei 0:03b5121a232e 14028 return(-1);
pcercuei 0:03b5121a232e 14029 }
pcercuei 0:03b5121a232e 14030 xmlAddChild((xmlNodePtr) newDoc, newRoot);
pcercuei 0:03b5121a232e 14031 nodePush(ctxt, newRoot);
pcercuei 0:03b5121a232e 14032 if (doc == NULL) {
pcercuei 0:03b5121a232e 14033 ctxt->myDoc = newDoc;
pcercuei 0:03b5121a232e 14034 } else {
pcercuei 0:03b5121a232e 14035 ctxt->myDoc = newDoc;
pcercuei 0:03b5121a232e 14036 newDoc->children->doc = doc;
pcercuei 0:03b5121a232e 14037 /* Ensure that doc has XML spec namespace */
pcercuei 0:03b5121a232e 14038 xmlSearchNsByHref(doc, (xmlNodePtr)doc, XML_XML_NAMESPACE);
pcercuei 0:03b5121a232e 14039 newDoc->oldNs = doc->oldNs;
pcercuei 0:03b5121a232e 14040 }
pcercuei 0:03b5121a232e 14041 ctxt->instate = XML_PARSER_CONTENT;
pcercuei 0:03b5121a232e 14042 ctxt->depth = depth;
pcercuei 0:03b5121a232e 14043
pcercuei 0:03b5121a232e 14044 /*
pcercuei 0:03b5121a232e 14045 * Doing validity checking on chunk doesn't make sense
pcercuei 0:03b5121a232e 14046 */
pcercuei 0:03b5121a232e 14047 ctxt->validate = 0;
pcercuei 0:03b5121a232e 14048 ctxt->loadsubset = 0;
pcercuei 0:03b5121a232e 14049 xmlDetectSAX2(ctxt);
pcercuei 0:03b5121a232e 14050
pcercuei 0:03b5121a232e 14051 if ( doc != NULL ){
pcercuei 0:03b5121a232e 14052 content = doc->children;
pcercuei 0:03b5121a232e 14053 doc->children = NULL;
pcercuei 0:03b5121a232e 14054 xmlParseContent(ctxt);
pcercuei 0:03b5121a232e 14055 doc->children = content;
pcercuei 0:03b5121a232e 14056 }
pcercuei 0:03b5121a232e 14057 else {
pcercuei 0:03b5121a232e 14058 xmlParseContent(ctxt);
pcercuei 0:03b5121a232e 14059 }
pcercuei 0:03b5121a232e 14060 if ((RAW == '<') && (NXT(1) == '/')) {
pcercuei 0:03b5121a232e 14061 xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
pcercuei 0:03b5121a232e 14062 } else if (RAW != 0) {
pcercuei 0:03b5121a232e 14063 xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
pcercuei 0:03b5121a232e 14064 }
pcercuei 0:03b5121a232e 14065 if (ctxt->node != newDoc->children) {
pcercuei 0:03b5121a232e 14066 xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
pcercuei 0:03b5121a232e 14067 }
pcercuei 0:03b5121a232e 14068
pcercuei 0:03b5121a232e 14069 if (!ctxt->wellFormed) {
pcercuei 0:03b5121a232e 14070 if (ctxt->errNo == 0)
pcercuei 0:03b5121a232e 14071 ret = 1;
pcercuei 0:03b5121a232e 14072 else
pcercuei 0:03b5121a232e 14073 ret = ctxt->errNo;
pcercuei 0:03b5121a232e 14074 } else {
pcercuei 0:03b5121a232e 14075 ret = 0;
pcercuei 0:03b5121a232e 14076 }
pcercuei 0:03b5121a232e 14077
pcercuei 0:03b5121a232e 14078 if ((lst != NULL) && ((ret == 0) || (recover == 1))) {
pcercuei 0:03b5121a232e 14079 xmlNodePtr cur;
pcercuei 0:03b5121a232e 14080
pcercuei 0:03b5121a232e 14081 /*
pcercuei 0:03b5121a232e 14082 * Return the newly created nodeset after unlinking it from
pcercuei 0:03b5121a232e 14083 * they pseudo parent.
pcercuei 0:03b5121a232e 14084 */
pcercuei 0:03b5121a232e 14085 cur = newDoc->children->children;
pcercuei 0:03b5121a232e 14086 *lst = cur;
pcercuei 0:03b5121a232e 14087 while (cur != NULL) {
pcercuei 0:03b5121a232e 14088 xmlSetTreeDoc(cur, doc);
pcercuei 0:03b5121a232e 14089 cur->parent = NULL;
pcercuei 0:03b5121a232e 14090 cur = cur->next;
pcercuei 0:03b5121a232e 14091 }
pcercuei 0:03b5121a232e 14092 newDoc->children->children = NULL;
pcercuei 0:03b5121a232e 14093 }
pcercuei 0:03b5121a232e 14094
pcercuei 0:03b5121a232e 14095 if (sax != NULL)
pcercuei 0:03b5121a232e 14096 ctxt->sax = oldsax;
pcercuei 0:03b5121a232e 14097 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 14098 newDoc->intSubset = NULL;
pcercuei 0:03b5121a232e 14099 newDoc->extSubset = NULL;
pcercuei 0:03b5121a232e 14100 newDoc->oldNs = NULL;
pcercuei 0:03b5121a232e 14101 xmlFreeDoc(newDoc);
pcercuei 0:03b5121a232e 14102
pcercuei 0:03b5121a232e 14103 return(ret);
pcercuei 0:03b5121a232e 14104 }
pcercuei 0:03b5121a232e 14105
pcercuei 0:03b5121a232e 14106 /**
pcercuei 0:03b5121a232e 14107 * xmlSAXParseEntity:
pcercuei 0:03b5121a232e 14108 * @sax: the SAX handler block
pcercuei 0:03b5121a232e 14109 * @filename: the filename
pcercuei 0:03b5121a232e 14110 *
pcercuei 0:03b5121a232e 14111 * parse an XML external entity out of context and build a tree.
pcercuei 0:03b5121a232e 14112 * It use the given SAX function block to handle the parsing callback.
pcercuei 0:03b5121a232e 14113 * If sax is NULL, fallback to the default DOM tree building routines.
pcercuei 0:03b5121a232e 14114 *
pcercuei 0:03b5121a232e 14115 * [78] extParsedEnt ::= TextDecl? content
pcercuei 0:03b5121a232e 14116 *
pcercuei 0:03b5121a232e 14117 * This correspond to a "Well Balanced" chunk
pcercuei 0:03b5121a232e 14118 *
pcercuei 0:03b5121a232e 14119 * Returns the resulting document tree
pcercuei 0:03b5121a232e 14120 */
pcercuei 0:03b5121a232e 14121
pcercuei 0:03b5121a232e 14122 xmlDocPtr
pcercuei 0:03b5121a232e 14123 xmlSAXParseEntity(xmlSAXHandlerPtr sax, const char *filename) {
pcercuei 0:03b5121a232e 14124 xmlDocPtr ret;
pcercuei 0:03b5121a232e 14125 xmlParserCtxtPtr ctxt;
pcercuei 0:03b5121a232e 14126
pcercuei 0:03b5121a232e 14127 ctxt = xmlCreateFileParserCtxt(filename);
pcercuei 0:03b5121a232e 14128 if (ctxt == NULL) {
pcercuei 0:03b5121a232e 14129 return(NULL);
pcercuei 0:03b5121a232e 14130 }
pcercuei 0:03b5121a232e 14131 if (sax != NULL) {
pcercuei 0:03b5121a232e 14132 if (ctxt->sax != NULL)
pcercuei 0:03b5121a232e 14133 xmlFree(ctxt->sax);
pcercuei 0:03b5121a232e 14134 ctxt->sax = sax;
pcercuei 0:03b5121a232e 14135 ctxt->userData = NULL;
pcercuei 0:03b5121a232e 14136 }
pcercuei 0:03b5121a232e 14137
pcercuei 0:03b5121a232e 14138 xmlParseExtParsedEnt(ctxt);
pcercuei 0:03b5121a232e 14139
pcercuei 0:03b5121a232e 14140 if (ctxt->wellFormed)
pcercuei 0:03b5121a232e 14141 ret = ctxt->myDoc;
pcercuei 0:03b5121a232e 14142 else {
pcercuei 0:03b5121a232e 14143 ret = NULL;
pcercuei 0:03b5121a232e 14144 xmlFreeDoc(ctxt->myDoc);
pcercuei 0:03b5121a232e 14145 ctxt->myDoc = NULL;
pcercuei 0:03b5121a232e 14146 }
pcercuei 0:03b5121a232e 14147 if (sax != NULL)
pcercuei 0:03b5121a232e 14148 ctxt->sax = NULL;
pcercuei 0:03b5121a232e 14149 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 14150
pcercuei 0:03b5121a232e 14151 return(ret);
pcercuei 0:03b5121a232e 14152 }
pcercuei 0:03b5121a232e 14153
pcercuei 0:03b5121a232e 14154 /**
pcercuei 0:03b5121a232e 14155 * xmlParseEntity:
pcercuei 0:03b5121a232e 14156 * @filename: the filename
pcercuei 0:03b5121a232e 14157 *
pcercuei 0:03b5121a232e 14158 * parse an XML external entity out of context and build a tree.
pcercuei 0:03b5121a232e 14159 *
pcercuei 0:03b5121a232e 14160 * [78] extParsedEnt ::= TextDecl? content
pcercuei 0:03b5121a232e 14161 *
pcercuei 0:03b5121a232e 14162 * This correspond to a "Well Balanced" chunk
pcercuei 0:03b5121a232e 14163 *
pcercuei 0:03b5121a232e 14164 * Returns the resulting document tree
pcercuei 0:03b5121a232e 14165 */
pcercuei 0:03b5121a232e 14166
pcercuei 0:03b5121a232e 14167 xmlDocPtr
pcercuei 0:03b5121a232e 14168 xmlParseEntity(const char *filename) {
pcercuei 0:03b5121a232e 14169 return(xmlSAXParseEntity(NULL, filename));
pcercuei 0:03b5121a232e 14170 }
pcercuei 0:03b5121a232e 14171 #endif /* LIBXML_SAX1_ENABLED */
pcercuei 0:03b5121a232e 14172
pcercuei 0:03b5121a232e 14173 /**
pcercuei 0:03b5121a232e 14174 * xmlCreateEntityParserCtxtInternal:
pcercuei 0:03b5121a232e 14175 * @URL: the entity URL
pcercuei 0:03b5121a232e 14176 * @ID: the entity PUBLIC ID
pcercuei 0:03b5121a232e 14177 * @base: a possible base for the target URI
pcercuei 0:03b5121a232e 14178 * @pctx: parser context used to set options on new context
pcercuei 0:03b5121a232e 14179 *
pcercuei 0:03b5121a232e 14180 * Create a parser context for an external entity
pcercuei 0:03b5121a232e 14181 * Automatic support for ZLIB/Compress compressed document is provided
pcercuei 0:03b5121a232e 14182 * by default if found at compile-time.
pcercuei 0:03b5121a232e 14183 *
pcercuei 0:03b5121a232e 14184 * Returns the new parser context or NULL
pcercuei 0:03b5121a232e 14185 */
pcercuei 0:03b5121a232e 14186 static xmlParserCtxtPtr
pcercuei 0:03b5121a232e 14187 xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
pcercuei 0:03b5121a232e 14188 const xmlChar *base, xmlParserCtxtPtr pctx) {
pcercuei 0:03b5121a232e 14189 xmlParserCtxtPtr ctxt;
pcercuei 0:03b5121a232e 14190 xmlParserInputPtr inputStream;
pcercuei 0:03b5121a232e 14191 char *directory = NULL;
pcercuei 0:03b5121a232e 14192 xmlChar *uri;
pcercuei 0:03b5121a232e 14193
pcercuei 0:03b5121a232e 14194 ctxt = xmlNewParserCtxt();
pcercuei 0:03b5121a232e 14195 if (ctxt == NULL) {
pcercuei 0:03b5121a232e 14196 return(NULL);
pcercuei 0:03b5121a232e 14197 }
pcercuei 0:03b5121a232e 14198
pcercuei 0:03b5121a232e 14199 if (pctx != NULL) {
pcercuei 0:03b5121a232e 14200 ctxt->options = pctx->options;
pcercuei 0:03b5121a232e 14201 ctxt->_private = pctx->_private;
pcercuei 0:03b5121a232e 14202 }
pcercuei 0:03b5121a232e 14203
pcercuei 0:03b5121a232e 14204 uri = xmlBuildURI(URL, base);
pcercuei 0:03b5121a232e 14205
pcercuei 0:03b5121a232e 14206 if (uri == NULL) {
pcercuei 0:03b5121a232e 14207 inputStream = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt);
pcercuei 0:03b5121a232e 14208 if (inputStream == NULL) {
pcercuei 0:03b5121a232e 14209 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 14210 return(NULL);
pcercuei 0:03b5121a232e 14211 }
pcercuei 0:03b5121a232e 14212
pcercuei 0:03b5121a232e 14213 inputPush(ctxt, inputStream);
pcercuei 0:03b5121a232e 14214
pcercuei 0:03b5121a232e 14215 if ((ctxt->directory == NULL) && (directory == NULL))
pcercuei 0:03b5121a232e 14216 directory = xmlParserGetDirectory((char *)URL);
pcercuei 0:03b5121a232e 14217 if ((ctxt->directory == NULL) && (directory != NULL))
pcercuei 0:03b5121a232e 14218 ctxt->directory = directory;
pcercuei 0:03b5121a232e 14219 } else {
pcercuei 0:03b5121a232e 14220 inputStream = xmlLoadExternalEntity((char *)uri, (char *)ID, ctxt);
pcercuei 0:03b5121a232e 14221 if (inputStream == NULL) {
pcercuei 0:03b5121a232e 14222 xmlFree(uri);
pcercuei 0:03b5121a232e 14223 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 14224 return(NULL);
pcercuei 0:03b5121a232e 14225 }
pcercuei 0:03b5121a232e 14226
pcercuei 0:03b5121a232e 14227 inputPush(ctxt, inputStream);
pcercuei 0:03b5121a232e 14228
pcercuei 0:03b5121a232e 14229 if ((ctxt->directory == NULL) && (directory == NULL))
pcercuei 0:03b5121a232e 14230 directory = xmlParserGetDirectory((char *)uri);
pcercuei 0:03b5121a232e 14231 if ((ctxt->directory == NULL) && (directory != NULL))
pcercuei 0:03b5121a232e 14232 ctxt->directory = directory;
pcercuei 0:03b5121a232e 14233 xmlFree(uri);
pcercuei 0:03b5121a232e 14234 }
pcercuei 0:03b5121a232e 14235 return(ctxt);
pcercuei 0:03b5121a232e 14236 }
pcercuei 0:03b5121a232e 14237
pcercuei 0:03b5121a232e 14238 /**
pcercuei 0:03b5121a232e 14239 * xmlCreateEntityParserCtxt:
pcercuei 0:03b5121a232e 14240 * @URL: the entity URL
pcercuei 0:03b5121a232e 14241 * @ID: the entity PUBLIC ID
pcercuei 0:03b5121a232e 14242 * @base: a possible base for the target URI
pcercuei 0:03b5121a232e 14243 *
pcercuei 0:03b5121a232e 14244 * Create a parser context for an external entity
pcercuei 0:03b5121a232e 14245 * Automatic support for ZLIB/Compress compressed document is provided
pcercuei 0:03b5121a232e 14246 * by default if found at compile-time.
pcercuei 0:03b5121a232e 14247 *
pcercuei 0:03b5121a232e 14248 * Returns the new parser context or NULL
pcercuei 0:03b5121a232e 14249 */
pcercuei 0:03b5121a232e 14250 xmlParserCtxtPtr
pcercuei 0:03b5121a232e 14251 xmlCreateEntityParserCtxt(const xmlChar *URL, const xmlChar *ID,
pcercuei 0:03b5121a232e 14252 const xmlChar *base) {
pcercuei 0:03b5121a232e 14253 return xmlCreateEntityParserCtxtInternal(URL, ID, base, NULL);
pcercuei 0:03b5121a232e 14254
pcercuei 0:03b5121a232e 14255 }
pcercuei 0:03b5121a232e 14256
pcercuei 0:03b5121a232e 14257 /************************************************************************
pcercuei 0:03b5121a232e 14258 * *
pcercuei 0:03b5121a232e 14259 * Front ends when parsing from a file *
pcercuei 0:03b5121a232e 14260 * *
pcercuei 0:03b5121a232e 14261 ************************************************************************/
pcercuei 0:03b5121a232e 14262
pcercuei 0:03b5121a232e 14263 /**
pcercuei 0:03b5121a232e 14264 * xmlCreateURLParserCtxt:
pcercuei 0:03b5121a232e 14265 * @filename: the filename or URL
pcercuei 0:03b5121a232e 14266 * @options: a combination of xmlParserOption
pcercuei 0:03b5121a232e 14267 *
pcercuei 0:03b5121a232e 14268 * Create a parser context for a file or URL content.
pcercuei 0:03b5121a232e 14269 * Automatic support for ZLIB/Compress compressed document is provided
pcercuei 0:03b5121a232e 14270 * by default if found at compile-time and for file accesses
pcercuei 0:03b5121a232e 14271 *
pcercuei 0:03b5121a232e 14272 * Returns the new parser context or NULL
pcercuei 0:03b5121a232e 14273 */
pcercuei 0:03b5121a232e 14274 xmlParserCtxtPtr
pcercuei 0:03b5121a232e 14275 xmlCreateURLParserCtxt(const char *filename, int options)
pcercuei 0:03b5121a232e 14276 {
pcercuei 0:03b5121a232e 14277 xmlParserCtxtPtr ctxt;
pcercuei 0:03b5121a232e 14278 xmlParserInputPtr inputStream;
pcercuei 0:03b5121a232e 14279 char *directory = NULL;
pcercuei 0:03b5121a232e 14280
pcercuei 0:03b5121a232e 14281 ctxt = xmlNewParserCtxt();
pcercuei 0:03b5121a232e 14282 if (ctxt == NULL) {
pcercuei 0:03b5121a232e 14283 xmlErrMemory(NULL, "cannot allocate parser context");
pcercuei 0:03b5121a232e 14284 return(NULL);
pcercuei 0:03b5121a232e 14285 }
pcercuei 0:03b5121a232e 14286
pcercuei 0:03b5121a232e 14287 if (options)
pcercuei 0:03b5121a232e 14288 xmlCtxtUseOptionsInternal(ctxt, options, NULL);
pcercuei 0:03b5121a232e 14289 ctxt->linenumbers = 1;
pcercuei 0:03b5121a232e 14290
pcercuei 0:03b5121a232e 14291 inputStream = xmlLoadExternalEntity(filename, NULL, ctxt);
pcercuei 0:03b5121a232e 14292 if (inputStream == NULL) {
pcercuei 0:03b5121a232e 14293 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 14294 return(NULL);
pcercuei 0:03b5121a232e 14295 }
pcercuei 0:03b5121a232e 14296
pcercuei 0:03b5121a232e 14297 inputPush(ctxt, inputStream);
pcercuei 0:03b5121a232e 14298 if ((ctxt->directory == NULL) && (directory == NULL))
pcercuei 0:03b5121a232e 14299 directory = xmlParserGetDirectory(filename);
pcercuei 0:03b5121a232e 14300 if ((ctxt->directory == NULL) && (directory != NULL))
pcercuei 0:03b5121a232e 14301 ctxt->directory = directory;
pcercuei 0:03b5121a232e 14302
pcercuei 0:03b5121a232e 14303 return(ctxt);
pcercuei 0:03b5121a232e 14304 }
pcercuei 0:03b5121a232e 14305
pcercuei 0:03b5121a232e 14306 /**
pcercuei 0:03b5121a232e 14307 * xmlCreateFileParserCtxt:
pcercuei 0:03b5121a232e 14308 * @filename: the filename
pcercuei 0:03b5121a232e 14309 *
pcercuei 0:03b5121a232e 14310 * Create a parser context for a file content.
pcercuei 0:03b5121a232e 14311 * Automatic support for ZLIB/Compress compressed document is provided
pcercuei 0:03b5121a232e 14312 * by default if found at compile-time.
pcercuei 0:03b5121a232e 14313 *
pcercuei 0:03b5121a232e 14314 * Returns the new parser context or NULL
pcercuei 0:03b5121a232e 14315 */
pcercuei 0:03b5121a232e 14316 xmlParserCtxtPtr
pcercuei 0:03b5121a232e 14317 xmlCreateFileParserCtxt(const char *filename)
pcercuei 0:03b5121a232e 14318 {
pcercuei 0:03b5121a232e 14319 return(xmlCreateURLParserCtxt(filename, 0));
pcercuei 0:03b5121a232e 14320 }
pcercuei 0:03b5121a232e 14321
pcercuei 0:03b5121a232e 14322 #ifdef LIBXML_SAX1_ENABLED
pcercuei 0:03b5121a232e 14323 /**
pcercuei 0:03b5121a232e 14324 * xmlSAXParseFileWithData:
pcercuei 0:03b5121a232e 14325 * @sax: the SAX handler block
pcercuei 0:03b5121a232e 14326 * @filename: the filename
pcercuei 0:03b5121a232e 14327 * @recovery: work in recovery mode, i.e. tries to read no Well Formed
pcercuei 0:03b5121a232e 14328 * documents
pcercuei 0:03b5121a232e 14329 * @data: the userdata
pcercuei 0:03b5121a232e 14330 *
pcercuei 0:03b5121a232e 14331 * parse an XML file and build a tree. Automatic support for ZLIB/Compress
pcercuei 0:03b5121a232e 14332 * compressed document is provided by default if found at compile-time.
pcercuei 0:03b5121a232e 14333 * It use the given SAX function block to handle the parsing callback.
pcercuei 0:03b5121a232e 14334 * If sax is NULL, fallback to the default DOM tree building routines.
pcercuei 0:03b5121a232e 14335 *
pcercuei 0:03b5121a232e 14336 * User data (void *) is stored within the parser context in the
pcercuei 0:03b5121a232e 14337 * context's _private member, so it is available nearly everywhere in libxml
pcercuei 0:03b5121a232e 14338 *
pcercuei 0:03b5121a232e 14339 * Returns the resulting document tree
pcercuei 0:03b5121a232e 14340 */
pcercuei 0:03b5121a232e 14341
pcercuei 0:03b5121a232e 14342 xmlDocPtr
pcercuei 0:03b5121a232e 14343 xmlSAXParseFileWithData(xmlSAXHandlerPtr sax, const char *filename,
pcercuei 0:03b5121a232e 14344 int recovery, void *data) {
pcercuei 0:03b5121a232e 14345 xmlDocPtr ret;
pcercuei 0:03b5121a232e 14346 xmlParserCtxtPtr ctxt;
pcercuei 0:03b5121a232e 14347
pcercuei 0:03b5121a232e 14348 xmlInitParser();
pcercuei 0:03b5121a232e 14349
pcercuei 0:03b5121a232e 14350 ctxt = xmlCreateFileParserCtxt(filename);
pcercuei 0:03b5121a232e 14351 if (ctxt == NULL) {
pcercuei 0:03b5121a232e 14352 return(NULL);
pcercuei 0:03b5121a232e 14353 }
pcercuei 0:03b5121a232e 14354 if (sax != NULL) {
pcercuei 0:03b5121a232e 14355 if (ctxt->sax != NULL)
pcercuei 0:03b5121a232e 14356 xmlFree(ctxt->sax);
pcercuei 0:03b5121a232e 14357 ctxt->sax = sax;
pcercuei 0:03b5121a232e 14358 }
pcercuei 0:03b5121a232e 14359 xmlDetectSAX2(ctxt);
pcercuei 0:03b5121a232e 14360 if (data!=NULL) {
pcercuei 0:03b5121a232e 14361 ctxt->_private = data;
pcercuei 0:03b5121a232e 14362 }
pcercuei 0:03b5121a232e 14363
pcercuei 0:03b5121a232e 14364 if (ctxt->directory == NULL)
pcercuei 0:03b5121a232e 14365 ctxt->directory = xmlParserGetDirectory(filename);
pcercuei 0:03b5121a232e 14366
pcercuei 0:03b5121a232e 14367 ctxt->recovery = recovery;
pcercuei 0:03b5121a232e 14368
pcercuei 0:03b5121a232e 14369 xmlParseDocument(ctxt);
pcercuei 0:03b5121a232e 14370
pcercuei 0:03b5121a232e 14371 if ((ctxt->wellFormed) || recovery) {
pcercuei 0:03b5121a232e 14372 ret = ctxt->myDoc;
pcercuei 0:03b5121a232e 14373 if (ret != NULL) {
pcercuei 0:03b5121a232e 14374 if (ctxt->input->buf->compressed > 0)
pcercuei 0:03b5121a232e 14375 ret->compression = 9;
pcercuei 0:03b5121a232e 14376 else
pcercuei 0:03b5121a232e 14377 ret->compression = ctxt->input->buf->compressed;
pcercuei 0:03b5121a232e 14378 }
pcercuei 0:03b5121a232e 14379 }
pcercuei 0:03b5121a232e 14380 else {
pcercuei 0:03b5121a232e 14381 ret = NULL;
pcercuei 0:03b5121a232e 14382 xmlFreeDoc(ctxt->myDoc);
pcercuei 0:03b5121a232e 14383 ctxt->myDoc = NULL;
pcercuei 0:03b5121a232e 14384 }
pcercuei 0:03b5121a232e 14385 if (sax != NULL)
pcercuei 0:03b5121a232e 14386 ctxt->sax = NULL;
pcercuei 0:03b5121a232e 14387 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 14388
pcercuei 0:03b5121a232e 14389 return(ret);
pcercuei 0:03b5121a232e 14390 }
pcercuei 0:03b5121a232e 14391
pcercuei 0:03b5121a232e 14392 /**
pcercuei 0:03b5121a232e 14393 * xmlSAXParseFile:
pcercuei 0:03b5121a232e 14394 * @sax: the SAX handler block
pcercuei 0:03b5121a232e 14395 * @filename: the filename
pcercuei 0:03b5121a232e 14396 * @recovery: work in recovery mode, i.e. tries to read no Well Formed
pcercuei 0:03b5121a232e 14397 * documents
pcercuei 0:03b5121a232e 14398 *
pcercuei 0:03b5121a232e 14399 * parse an XML file and build a tree. Automatic support for ZLIB/Compress
pcercuei 0:03b5121a232e 14400 * compressed document is provided by default if found at compile-time.
pcercuei 0:03b5121a232e 14401 * It use the given SAX function block to handle the parsing callback.
pcercuei 0:03b5121a232e 14402 * If sax is NULL, fallback to the default DOM tree building routines.
pcercuei 0:03b5121a232e 14403 *
pcercuei 0:03b5121a232e 14404 * Returns the resulting document tree
pcercuei 0:03b5121a232e 14405 */
pcercuei 0:03b5121a232e 14406
pcercuei 0:03b5121a232e 14407 xmlDocPtr
pcercuei 0:03b5121a232e 14408 xmlSAXParseFile(xmlSAXHandlerPtr sax, const char *filename,
pcercuei 0:03b5121a232e 14409 int recovery) {
pcercuei 0:03b5121a232e 14410 return(xmlSAXParseFileWithData(sax,filename,recovery,NULL));
pcercuei 0:03b5121a232e 14411 }
pcercuei 0:03b5121a232e 14412
pcercuei 0:03b5121a232e 14413 /**
pcercuei 0:03b5121a232e 14414 * xmlRecoverDoc:
pcercuei 0:03b5121a232e 14415 * @cur: a pointer to an array of xmlChar
pcercuei 0:03b5121a232e 14416 *
pcercuei 0:03b5121a232e 14417 * parse an XML in-memory document and build a tree.
pcercuei 0:03b5121a232e 14418 * In the case the document is not Well Formed, a attempt to build a
pcercuei 0:03b5121a232e 14419 * tree is tried anyway
pcercuei 0:03b5121a232e 14420 *
pcercuei 0:03b5121a232e 14421 * Returns the resulting document tree or NULL in case of failure
pcercuei 0:03b5121a232e 14422 */
pcercuei 0:03b5121a232e 14423
pcercuei 0:03b5121a232e 14424 xmlDocPtr
pcercuei 0:03b5121a232e 14425 xmlRecoverDoc(const xmlChar *cur) {
pcercuei 0:03b5121a232e 14426 return(xmlSAXParseDoc(NULL, cur, 1));
pcercuei 0:03b5121a232e 14427 }
pcercuei 0:03b5121a232e 14428
pcercuei 0:03b5121a232e 14429 /**
pcercuei 0:03b5121a232e 14430 * xmlParseFile:
pcercuei 0:03b5121a232e 14431 * @filename: the filename
pcercuei 0:03b5121a232e 14432 *
pcercuei 0:03b5121a232e 14433 * parse an XML file and build a tree. Automatic support for ZLIB/Compress
pcercuei 0:03b5121a232e 14434 * compressed document is provided by default if found at compile-time.
pcercuei 0:03b5121a232e 14435 *
pcercuei 0:03b5121a232e 14436 * Returns the resulting document tree if the file was wellformed,
pcercuei 0:03b5121a232e 14437 * NULL otherwise.
pcercuei 0:03b5121a232e 14438 */
pcercuei 0:03b5121a232e 14439
pcercuei 0:03b5121a232e 14440 xmlDocPtr
pcercuei 0:03b5121a232e 14441 xmlParseFile(const char *filename) {
pcercuei 0:03b5121a232e 14442 return(xmlSAXParseFile(NULL, filename, 0));
pcercuei 0:03b5121a232e 14443 }
pcercuei 0:03b5121a232e 14444
pcercuei 0:03b5121a232e 14445 /**
pcercuei 0:03b5121a232e 14446 * xmlRecoverFile:
pcercuei 0:03b5121a232e 14447 * @filename: the filename
pcercuei 0:03b5121a232e 14448 *
pcercuei 0:03b5121a232e 14449 * parse an XML file and build a tree. Automatic support for ZLIB/Compress
pcercuei 0:03b5121a232e 14450 * compressed document is provided by default if found at compile-time.
pcercuei 0:03b5121a232e 14451 * In the case the document is not Well Formed, it attempts to build
pcercuei 0:03b5121a232e 14452 * a tree anyway
pcercuei 0:03b5121a232e 14453 *
pcercuei 0:03b5121a232e 14454 * Returns the resulting document tree or NULL in case of failure
pcercuei 0:03b5121a232e 14455 */
pcercuei 0:03b5121a232e 14456
pcercuei 0:03b5121a232e 14457 xmlDocPtr
pcercuei 0:03b5121a232e 14458 xmlRecoverFile(const char *filename) {
pcercuei 0:03b5121a232e 14459 return(xmlSAXParseFile(NULL, filename, 1));
pcercuei 0:03b5121a232e 14460 }
pcercuei 0:03b5121a232e 14461
pcercuei 0:03b5121a232e 14462
pcercuei 0:03b5121a232e 14463 /**
pcercuei 0:03b5121a232e 14464 * xmlSetupParserForBuffer:
pcercuei 0:03b5121a232e 14465 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 14466 * @buffer: a xmlChar * buffer
pcercuei 0:03b5121a232e 14467 * @filename: a file name
pcercuei 0:03b5121a232e 14468 *
pcercuei 0:03b5121a232e 14469 * Setup the parser context to parse a new buffer; Clears any prior
pcercuei 0:03b5121a232e 14470 * contents from the parser context. The buffer parameter must not be
pcercuei 0:03b5121a232e 14471 * NULL, but the filename parameter can be
pcercuei 0:03b5121a232e 14472 */
pcercuei 0:03b5121a232e 14473 void
pcercuei 0:03b5121a232e 14474 xmlSetupParserForBuffer(xmlParserCtxtPtr ctxt, const xmlChar* buffer,
pcercuei 0:03b5121a232e 14475 const char* filename)
pcercuei 0:03b5121a232e 14476 {
pcercuei 0:03b5121a232e 14477 xmlParserInputPtr input;
pcercuei 0:03b5121a232e 14478
pcercuei 0:03b5121a232e 14479 if ((ctxt == NULL) || (buffer == NULL))
pcercuei 0:03b5121a232e 14480 return;
pcercuei 0:03b5121a232e 14481
pcercuei 0:03b5121a232e 14482 input = xmlNewInputStream(ctxt);
pcercuei 0:03b5121a232e 14483 if (input == NULL) {
pcercuei 0:03b5121a232e 14484 xmlErrMemory(NULL, "parsing new buffer: out of memory\n");
pcercuei 0:03b5121a232e 14485 xmlClearParserCtxt(ctxt);
pcercuei 0:03b5121a232e 14486 return;
pcercuei 0:03b5121a232e 14487 }
pcercuei 0:03b5121a232e 14488
pcercuei 0:03b5121a232e 14489 xmlClearParserCtxt(ctxt);
pcercuei 0:03b5121a232e 14490 if (filename != NULL)
pcercuei 0:03b5121a232e 14491 input->filename = (char *) xmlCanonicPath((const xmlChar *)filename);
pcercuei 0:03b5121a232e 14492 input->base = buffer;
pcercuei 0:03b5121a232e 14493 input->cur = buffer;
pcercuei 0:03b5121a232e 14494 input->end = &buffer[xmlStrlen(buffer)];
pcercuei 0:03b5121a232e 14495 inputPush(ctxt, input);
pcercuei 0:03b5121a232e 14496 }
pcercuei 0:03b5121a232e 14497
pcercuei 0:03b5121a232e 14498 /**
pcercuei 0:03b5121a232e 14499 * xmlSAXUserParseFile:
pcercuei 0:03b5121a232e 14500 * @sax: a SAX handler
pcercuei 0:03b5121a232e 14501 * @user_data: The user data returned on SAX callbacks
pcercuei 0:03b5121a232e 14502 * @filename: a file name
pcercuei 0:03b5121a232e 14503 *
pcercuei 0:03b5121a232e 14504 * parse an XML file and call the given SAX handler routines.
pcercuei 0:03b5121a232e 14505 * Automatic support for ZLIB/Compress compressed document is provided
pcercuei 0:03b5121a232e 14506 *
pcercuei 0:03b5121a232e 14507 * Returns 0 in case of success or a error number otherwise
pcercuei 0:03b5121a232e 14508 */
pcercuei 0:03b5121a232e 14509 int
pcercuei 0:03b5121a232e 14510 xmlSAXUserParseFile(xmlSAXHandlerPtr sax, void *user_data,
pcercuei 0:03b5121a232e 14511 const char *filename) {
pcercuei 0:03b5121a232e 14512 int ret = 0;
pcercuei 0:03b5121a232e 14513 xmlParserCtxtPtr ctxt;
pcercuei 0:03b5121a232e 14514
pcercuei 0:03b5121a232e 14515 ctxt = xmlCreateFileParserCtxt(filename);
pcercuei 0:03b5121a232e 14516 if (ctxt == NULL) return -1;
pcercuei 0:03b5121a232e 14517 if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
pcercuei 0:03b5121a232e 14518 xmlFree(ctxt->sax);
pcercuei 0:03b5121a232e 14519 ctxt->sax = sax;
pcercuei 0:03b5121a232e 14520 xmlDetectSAX2(ctxt);
pcercuei 0:03b5121a232e 14521
pcercuei 0:03b5121a232e 14522 if (user_data != NULL)
pcercuei 0:03b5121a232e 14523 ctxt->userData = user_data;
pcercuei 0:03b5121a232e 14524
pcercuei 0:03b5121a232e 14525 xmlParseDocument(ctxt);
pcercuei 0:03b5121a232e 14526
pcercuei 0:03b5121a232e 14527 if (ctxt->wellFormed)
pcercuei 0:03b5121a232e 14528 ret = 0;
pcercuei 0:03b5121a232e 14529 else {
pcercuei 0:03b5121a232e 14530 if (ctxt->errNo != 0)
pcercuei 0:03b5121a232e 14531 ret = ctxt->errNo;
pcercuei 0:03b5121a232e 14532 else
pcercuei 0:03b5121a232e 14533 ret = -1;
pcercuei 0:03b5121a232e 14534 }
pcercuei 0:03b5121a232e 14535 if (sax != NULL)
pcercuei 0:03b5121a232e 14536 ctxt->sax = NULL;
pcercuei 0:03b5121a232e 14537 if (ctxt->myDoc != NULL) {
pcercuei 0:03b5121a232e 14538 xmlFreeDoc(ctxt->myDoc);
pcercuei 0:03b5121a232e 14539 ctxt->myDoc = NULL;
pcercuei 0:03b5121a232e 14540 }
pcercuei 0:03b5121a232e 14541 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 14542
pcercuei 0:03b5121a232e 14543 return ret;
pcercuei 0:03b5121a232e 14544 }
pcercuei 0:03b5121a232e 14545 #endif /* LIBXML_SAX1_ENABLED */
pcercuei 0:03b5121a232e 14546
pcercuei 0:03b5121a232e 14547 /************************************************************************
pcercuei 0:03b5121a232e 14548 * *
pcercuei 0:03b5121a232e 14549 * Front ends when parsing from memory *
pcercuei 0:03b5121a232e 14550 * *
pcercuei 0:03b5121a232e 14551 ************************************************************************/
pcercuei 0:03b5121a232e 14552
pcercuei 0:03b5121a232e 14553 /**
pcercuei 0:03b5121a232e 14554 * xmlCreateMemoryParserCtxt:
pcercuei 0:03b5121a232e 14555 * @buffer: a pointer to a char array
pcercuei 0:03b5121a232e 14556 * @size: the size of the array
pcercuei 0:03b5121a232e 14557 *
pcercuei 0:03b5121a232e 14558 * Create a parser context for an XML in-memory document.
pcercuei 0:03b5121a232e 14559 *
pcercuei 0:03b5121a232e 14560 * Returns the new parser context or NULL
pcercuei 0:03b5121a232e 14561 */
pcercuei 0:03b5121a232e 14562 xmlParserCtxtPtr
pcercuei 0:03b5121a232e 14563 xmlCreateMemoryParserCtxt(const char *buffer, int size) {
pcercuei 0:03b5121a232e 14564 xmlParserCtxtPtr ctxt;
pcercuei 0:03b5121a232e 14565 xmlParserInputPtr input;
pcercuei 0:03b5121a232e 14566 xmlParserInputBufferPtr buf;
pcercuei 0:03b5121a232e 14567
pcercuei 0:03b5121a232e 14568 if (buffer == NULL)
pcercuei 0:03b5121a232e 14569 return(NULL);
pcercuei 0:03b5121a232e 14570 if (size <= 0)
pcercuei 0:03b5121a232e 14571 return(NULL);
pcercuei 0:03b5121a232e 14572
pcercuei 0:03b5121a232e 14573 ctxt = xmlNewParserCtxt();
pcercuei 0:03b5121a232e 14574 if (ctxt == NULL)
pcercuei 0:03b5121a232e 14575 return(NULL);
pcercuei 0:03b5121a232e 14576
pcercuei 0:03b5121a232e 14577 /* TODO: xmlParserInputBufferCreateStatic, requires some serious changes */
pcercuei 0:03b5121a232e 14578 buf = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
pcercuei 0:03b5121a232e 14579 if (buf == NULL) {
pcercuei 0:03b5121a232e 14580 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 14581 return(NULL);
pcercuei 0:03b5121a232e 14582 }
pcercuei 0:03b5121a232e 14583
pcercuei 0:03b5121a232e 14584 input = xmlNewInputStream(ctxt);
pcercuei 0:03b5121a232e 14585 if (input == NULL) {
pcercuei 0:03b5121a232e 14586 xmlFreeParserInputBuffer(buf);
pcercuei 0:03b5121a232e 14587 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 14588 return(NULL);
pcercuei 0:03b5121a232e 14589 }
pcercuei 0:03b5121a232e 14590
pcercuei 0:03b5121a232e 14591 input->filename = NULL;
pcercuei 0:03b5121a232e 14592 input->buf = buf;
pcercuei 0:03b5121a232e 14593 xmlBufResetInput(input->buf->buffer, input);
pcercuei 0:03b5121a232e 14594
pcercuei 0:03b5121a232e 14595 inputPush(ctxt, input);
pcercuei 0:03b5121a232e 14596 return(ctxt);
pcercuei 0:03b5121a232e 14597 }
pcercuei 0:03b5121a232e 14598
pcercuei 0:03b5121a232e 14599 #ifdef LIBXML_SAX1_ENABLED
pcercuei 0:03b5121a232e 14600 /**
pcercuei 0:03b5121a232e 14601 * xmlSAXParseMemoryWithData:
pcercuei 0:03b5121a232e 14602 * @sax: the SAX handler block
pcercuei 0:03b5121a232e 14603 * @buffer: an pointer to a char array
pcercuei 0:03b5121a232e 14604 * @size: the size of the array
pcercuei 0:03b5121a232e 14605 * @recovery: work in recovery mode, i.e. tries to read no Well Formed
pcercuei 0:03b5121a232e 14606 * documents
pcercuei 0:03b5121a232e 14607 * @data: the userdata
pcercuei 0:03b5121a232e 14608 *
pcercuei 0:03b5121a232e 14609 * parse an XML in-memory block and use the given SAX function block
pcercuei 0:03b5121a232e 14610 * to handle the parsing callback. If sax is NULL, fallback to the default
pcercuei 0:03b5121a232e 14611 * DOM tree building routines.
pcercuei 0:03b5121a232e 14612 *
pcercuei 0:03b5121a232e 14613 * User data (void *) is stored within the parser context in the
pcercuei 0:03b5121a232e 14614 * context's _private member, so it is available nearly everywhere in libxml
pcercuei 0:03b5121a232e 14615 *
pcercuei 0:03b5121a232e 14616 * Returns the resulting document tree
pcercuei 0:03b5121a232e 14617 */
pcercuei 0:03b5121a232e 14618
pcercuei 0:03b5121a232e 14619 xmlDocPtr
pcercuei 0:03b5121a232e 14620 xmlSAXParseMemoryWithData(xmlSAXHandlerPtr sax, const char *buffer,
pcercuei 0:03b5121a232e 14621 int size, int recovery, void *data) {
pcercuei 0:03b5121a232e 14622 xmlDocPtr ret;
pcercuei 0:03b5121a232e 14623 xmlParserCtxtPtr ctxt;
pcercuei 0:03b5121a232e 14624
pcercuei 0:03b5121a232e 14625 xmlInitParser();
pcercuei 0:03b5121a232e 14626
pcercuei 0:03b5121a232e 14627 ctxt = xmlCreateMemoryParserCtxt(buffer, size);
pcercuei 0:03b5121a232e 14628 if (ctxt == NULL) return(NULL);
pcercuei 0:03b5121a232e 14629 if (sax != NULL) {
pcercuei 0:03b5121a232e 14630 if (ctxt->sax != NULL)
pcercuei 0:03b5121a232e 14631 xmlFree(ctxt->sax);
pcercuei 0:03b5121a232e 14632 ctxt->sax = sax;
pcercuei 0:03b5121a232e 14633 }
pcercuei 0:03b5121a232e 14634 xmlDetectSAX2(ctxt);
pcercuei 0:03b5121a232e 14635 if (data!=NULL) {
pcercuei 0:03b5121a232e 14636 ctxt->_private=data;
pcercuei 0:03b5121a232e 14637 }
pcercuei 0:03b5121a232e 14638
pcercuei 0:03b5121a232e 14639 ctxt->recovery = recovery;
pcercuei 0:03b5121a232e 14640
pcercuei 0:03b5121a232e 14641 xmlParseDocument(ctxt);
pcercuei 0:03b5121a232e 14642
pcercuei 0:03b5121a232e 14643 if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
pcercuei 0:03b5121a232e 14644 else {
pcercuei 0:03b5121a232e 14645 ret = NULL;
pcercuei 0:03b5121a232e 14646 xmlFreeDoc(ctxt->myDoc);
pcercuei 0:03b5121a232e 14647 ctxt->myDoc = NULL;
pcercuei 0:03b5121a232e 14648 }
pcercuei 0:03b5121a232e 14649 if (sax != NULL)
pcercuei 0:03b5121a232e 14650 ctxt->sax = NULL;
pcercuei 0:03b5121a232e 14651 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 14652
pcercuei 0:03b5121a232e 14653 return(ret);
pcercuei 0:03b5121a232e 14654 }
pcercuei 0:03b5121a232e 14655
pcercuei 0:03b5121a232e 14656 /**
pcercuei 0:03b5121a232e 14657 * xmlSAXParseMemory:
pcercuei 0:03b5121a232e 14658 * @sax: the SAX handler block
pcercuei 0:03b5121a232e 14659 * @buffer: an pointer to a char array
pcercuei 0:03b5121a232e 14660 * @size: the size of the array
pcercuei 0:03b5121a232e 14661 * @recovery: work in recovery mode, i.e. tries to read not Well Formed
pcercuei 0:03b5121a232e 14662 * documents
pcercuei 0:03b5121a232e 14663 *
pcercuei 0:03b5121a232e 14664 * parse an XML in-memory block and use the given SAX function block
pcercuei 0:03b5121a232e 14665 * to handle the parsing callback. If sax is NULL, fallback to the default
pcercuei 0:03b5121a232e 14666 * DOM tree building routines.
pcercuei 0:03b5121a232e 14667 *
pcercuei 0:03b5121a232e 14668 * Returns the resulting document tree
pcercuei 0:03b5121a232e 14669 */
pcercuei 0:03b5121a232e 14670 xmlDocPtr
pcercuei 0:03b5121a232e 14671 xmlSAXParseMemory(xmlSAXHandlerPtr sax, const char *buffer,
pcercuei 0:03b5121a232e 14672 int size, int recovery) {
pcercuei 0:03b5121a232e 14673 return xmlSAXParseMemoryWithData(sax, buffer, size, recovery, NULL);
pcercuei 0:03b5121a232e 14674 }
pcercuei 0:03b5121a232e 14675
pcercuei 0:03b5121a232e 14676 /**
pcercuei 0:03b5121a232e 14677 * xmlParseMemory:
pcercuei 0:03b5121a232e 14678 * @buffer: an pointer to a char array
pcercuei 0:03b5121a232e 14679 * @size: the size of the array
pcercuei 0:03b5121a232e 14680 *
pcercuei 0:03b5121a232e 14681 * parse an XML in-memory block and build a tree.
pcercuei 0:03b5121a232e 14682 *
pcercuei 0:03b5121a232e 14683 * Returns the resulting document tree
pcercuei 0:03b5121a232e 14684 */
pcercuei 0:03b5121a232e 14685
pcercuei 0:03b5121a232e 14686 xmlDocPtr xmlParseMemory(const char *buffer, int size) {
pcercuei 0:03b5121a232e 14687 return(xmlSAXParseMemory(NULL, buffer, size, 0));
pcercuei 0:03b5121a232e 14688 }
pcercuei 0:03b5121a232e 14689
pcercuei 0:03b5121a232e 14690 /**
pcercuei 0:03b5121a232e 14691 * xmlRecoverMemory:
pcercuei 0:03b5121a232e 14692 * @buffer: an pointer to a char array
pcercuei 0:03b5121a232e 14693 * @size: the size of the array
pcercuei 0:03b5121a232e 14694 *
pcercuei 0:03b5121a232e 14695 * parse an XML in-memory block and build a tree.
pcercuei 0:03b5121a232e 14696 * In the case the document is not Well Formed, an attempt to
pcercuei 0:03b5121a232e 14697 * build a tree is tried anyway
pcercuei 0:03b5121a232e 14698 *
pcercuei 0:03b5121a232e 14699 * Returns the resulting document tree or NULL in case of error
pcercuei 0:03b5121a232e 14700 */
pcercuei 0:03b5121a232e 14701
pcercuei 0:03b5121a232e 14702 xmlDocPtr xmlRecoverMemory(const char *buffer, int size) {
pcercuei 0:03b5121a232e 14703 return(xmlSAXParseMemory(NULL, buffer, size, 1));
pcercuei 0:03b5121a232e 14704 }
pcercuei 0:03b5121a232e 14705
pcercuei 0:03b5121a232e 14706 /**
pcercuei 0:03b5121a232e 14707 * xmlSAXUserParseMemory:
pcercuei 0:03b5121a232e 14708 * @sax: a SAX handler
pcercuei 0:03b5121a232e 14709 * @user_data: The user data returned on SAX callbacks
pcercuei 0:03b5121a232e 14710 * @buffer: an in-memory XML document input
pcercuei 0:03b5121a232e 14711 * @size: the length of the XML document in bytes
pcercuei 0:03b5121a232e 14712 *
pcercuei 0:03b5121a232e 14713 * A better SAX parsing routine.
pcercuei 0:03b5121a232e 14714 * parse an XML in-memory buffer and call the given SAX handler routines.
pcercuei 0:03b5121a232e 14715 *
pcercuei 0:03b5121a232e 14716 * Returns 0 in case of success or a error number otherwise
pcercuei 0:03b5121a232e 14717 */
pcercuei 0:03b5121a232e 14718 int xmlSAXUserParseMemory(xmlSAXHandlerPtr sax, void *user_data,
pcercuei 0:03b5121a232e 14719 const char *buffer, int size) {
pcercuei 0:03b5121a232e 14720 int ret = 0;
pcercuei 0:03b5121a232e 14721 xmlParserCtxtPtr ctxt;
pcercuei 0:03b5121a232e 14722
pcercuei 0:03b5121a232e 14723 xmlInitParser();
pcercuei 0:03b5121a232e 14724
pcercuei 0:03b5121a232e 14725 ctxt = xmlCreateMemoryParserCtxt(buffer, size);
pcercuei 0:03b5121a232e 14726 if (ctxt == NULL) return -1;
pcercuei 0:03b5121a232e 14727 if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
pcercuei 0:03b5121a232e 14728 xmlFree(ctxt->sax);
pcercuei 0:03b5121a232e 14729 ctxt->sax = sax;
pcercuei 0:03b5121a232e 14730 xmlDetectSAX2(ctxt);
pcercuei 0:03b5121a232e 14731
pcercuei 0:03b5121a232e 14732 if (user_data != NULL)
pcercuei 0:03b5121a232e 14733 ctxt->userData = user_data;
pcercuei 0:03b5121a232e 14734
pcercuei 0:03b5121a232e 14735 xmlParseDocument(ctxt);
pcercuei 0:03b5121a232e 14736
pcercuei 0:03b5121a232e 14737 if (ctxt->wellFormed)
pcercuei 0:03b5121a232e 14738 ret = 0;
pcercuei 0:03b5121a232e 14739 else {
pcercuei 0:03b5121a232e 14740 if (ctxt->errNo != 0)
pcercuei 0:03b5121a232e 14741 ret = ctxt->errNo;
pcercuei 0:03b5121a232e 14742 else
pcercuei 0:03b5121a232e 14743 ret = -1;
pcercuei 0:03b5121a232e 14744 }
pcercuei 0:03b5121a232e 14745 if (sax != NULL)
pcercuei 0:03b5121a232e 14746 ctxt->sax = NULL;
pcercuei 0:03b5121a232e 14747 if (ctxt->myDoc != NULL) {
pcercuei 0:03b5121a232e 14748 xmlFreeDoc(ctxt->myDoc);
pcercuei 0:03b5121a232e 14749 ctxt->myDoc = NULL;
pcercuei 0:03b5121a232e 14750 }
pcercuei 0:03b5121a232e 14751 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 14752
pcercuei 0:03b5121a232e 14753 return ret;
pcercuei 0:03b5121a232e 14754 }
pcercuei 0:03b5121a232e 14755 #endif /* LIBXML_SAX1_ENABLED */
pcercuei 0:03b5121a232e 14756
pcercuei 0:03b5121a232e 14757 /**
pcercuei 0:03b5121a232e 14758 * xmlCreateDocParserCtxt:
pcercuei 0:03b5121a232e 14759 * @cur: a pointer to an array of xmlChar
pcercuei 0:03b5121a232e 14760 *
pcercuei 0:03b5121a232e 14761 * Creates a parser context for an XML in-memory document.
pcercuei 0:03b5121a232e 14762 *
pcercuei 0:03b5121a232e 14763 * Returns the new parser context or NULL
pcercuei 0:03b5121a232e 14764 */
pcercuei 0:03b5121a232e 14765 xmlParserCtxtPtr
pcercuei 0:03b5121a232e 14766 xmlCreateDocParserCtxt(const xmlChar *cur) {
pcercuei 0:03b5121a232e 14767 int len;
pcercuei 0:03b5121a232e 14768
pcercuei 0:03b5121a232e 14769 if (cur == NULL)
pcercuei 0:03b5121a232e 14770 return(NULL);
pcercuei 0:03b5121a232e 14771 len = xmlStrlen(cur);
pcercuei 0:03b5121a232e 14772 return(xmlCreateMemoryParserCtxt((const char *)cur, len));
pcercuei 0:03b5121a232e 14773 }
pcercuei 0:03b5121a232e 14774
pcercuei 0:03b5121a232e 14775 #ifdef LIBXML_SAX1_ENABLED
pcercuei 0:03b5121a232e 14776 /**
pcercuei 0:03b5121a232e 14777 * xmlSAXParseDoc:
pcercuei 0:03b5121a232e 14778 * @sax: the SAX handler block
pcercuei 0:03b5121a232e 14779 * @cur: a pointer to an array of xmlChar
pcercuei 0:03b5121a232e 14780 * @recovery: work in recovery mode, i.e. tries to read no Well Formed
pcercuei 0:03b5121a232e 14781 * documents
pcercuei 0:03b5121a232e 14782 *
pcercuei 0:03b5121a232e 14783 * parse an XML in-memory document and build a tree.
pcercuei 0:03b5121a232e 14784 * It use the given SAX function block to handle the parsing callback.
pcercuei 0:03b5121a232e 14785 * If sax is NULL, fallback to the default DOM tree building routines.
pcercuei 0:03b5121a232e 14786 *
pcercuei 0:03b5121a232e 14787 * Returns the resulting document tree
pcercuei 0:03b5121a232e 14788 */
pcercuei 0:03b5121a232e 14789
pcercuei 0:03b5121a232e 14790 xmlDocPtr
pcercuei 0:03b5121a232e 14791 xmlSAXParseDoc(xmlSAXHandlerPtr sax, const xmlChar *cur, int recovery) {
pcercuei 0:03b5121a232e 14792 xmlDocPtr ret;
pcercuei 0:03b5121a232e 14793 xmlParserCtxtPtr ctxt;
pcercuei 0:03b5121a232e 14794 xmlSAXHandlerPtr oldsax = NULL;
pcercuei 0:03b5121a232e 14795
pcercuei 0:03b5121a232e 14796 if (cur == NULL) return(NULL);
pcercuei 0:03b5121a232e 14797
pcercuei 0:03b5121a232e 14798
pcercuei 0:03b5121a232e 14799 ctxt = xmlCreateDocParserCtxt(cur);
pcercuei 0:03b5121a232e 14800 if (ctxt == NULL) return(NULL);
pcercuei 0:03b5121a232e 14801 if (sax != NULL) {
pcercuei 0:03b5121a232e 14802 oldsax = ctxt->sax;
pcercuei 0:03b5121a232e 14803 ctxt->sax = sax;
pcercuei 0:03b5121a232e 14804 ctxt->userData = NULL;
pcercuei 0:03b5121a232e 14805 }
pcercuei 0:03b5121a232e 14806 xmlDetectSAX2(ctxt);
pcercuei 0:03b5121a232e 14807
pcercuei 0:03b5121a232e 14808 xmlParseDocument(ctxt);
pcercuei 0:03b5121a232e 14809 if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
pcercuei 0:03b5121a232e 14810 else {
pcercuei 0:03b5121a232e 14811 ret = NULL;
pcercuei 0:03b5121a232e 14812 xmlFreeDoc(ctxt->myDoc);
pcercuei 0:03b5121a232e 14813 ctxt->myDoc = NULL;
pcercuei 0:03b5121a232e 14814 }
pcercuei 0:03b5121a232e 14815 if (sax != NULL)
pcercuei 0:03b5121a232e 14816 ctxt->sax = oldsax;
pcercuei 0:03b5121a232e 14817 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 14818
pcercuei 0:03b5121a232e 14819 return(ret);
pcercuei 0:03b5121a232e 14820 }
pcercuei 0:03b5121a232e 14821
pcercuei 0:03b5121a232e 14822 /**
pcercuei 0:03b5121a232e 14823 * xmlParseDoc:
pcercuei 0:03b5121a232e 14824 * @cur: a pointer to an array of xmlChar
pcercuei 0:03b5121a232e 14825 *
pcercuei 0:03b5121a232e 14826 * parse an XML in-memory document and build a tree.
pcercuei 0:03b5121a232e 14827 *
pcercuei 0:03b5121a232e 14828 * Returns the resulting document tree
pcercuei 0:03b5121a232e 14829 */
pcercuei 0:03b5121a232e 14830
pcercuei 0:03b5121a232e 14831 xmlDocPtr
pcercuei 0:03b5121a232e 14832 xmlParseDoc(const xmlChar *cur) {
pcercuei 0:03b5121a232e 14833 return(xmlSAXParseDoc(NULL, cur, 0));
pcercuei 0:03b5121a232e 14834 }
pcercuei 0:03b5121a232e 14835 #endif /* LIBXML_SAX1_ENABLED */
pcercuei 0:03b5121a232e 14836
pcercuei 0:03b5121a232e 14837 #ifdef LIBXML_LEGACY_ENABLED
pcercuei 0:03b5121a232e 14838 /************************************************************************
pcercuei 0:03b5121a232e 14839 * *
pcercuei 0:03b5121a232e 14840 * Specific function to keep track of entities references *
pcercuei 0:03b5121a232e 14841 * and used by the XSLT debugger *
pcercuei 0:03b5121a232e 14842 * *
pcercuei 0:03b5121a232e 14843 ************************************************************************/
pcercuei 0:03b5121a232e 14844
pcercuei 0:03b5121a232e 14845 static xmlEntityReferenceFunc xmlEntityRefFunc = NULL;
pcercuei 0:03b5121a232e 14846
pcercuei 0:03b5121a232e 14847 /**
pcercuei 0:03b5121a232e 14848 * xmlAddEntityReference:
pcercuei 0:03b5121a232e 14849 * @ent : A valid entity
pcercuei 0:03b5121a232e 14850 * @firstNode : A valid first node for children of entity
pcercuei 0:03b5121a232e 14851 * @lastNode : A valid last node of children entity
pcercuei 0:03b5121a232e 14852 *
pcercuei 0:03b5121a232e 14853 * Notify of a reference to an entity of type XML_EXTERNAL_GENERAL_PARSED_ENTITY
pcercuei 0:03b5121a232e 14854 */
pcercuei 0:03b5121a232e 14855 static void
pcercuei 0:03b5121a232e 14856 xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
pcercuei 0:03b5121a232e 14857 xmlNodePtr lastNode)
pcercuei 0:03b5121a232e 14858 {
pcercuei 0:03b5121a232e 14859 if (xmlEntityRefFunc != NULL) {
pcercuei 0:03b5121a232e 14860 (*xmlEntityRefFunc) (ent, firstNode, lastNode);
pcercuei 0:03b5121a232e 14861 }
pcercuei 0:03b5121a232e 14862 }
pcercuei 0:03b5121a232e 14863
pcercuei 0:03b5121a232e 14864
pcercuei 0:03b5121a232e 14865 /**
pcercuei 0:03b5121a232e 14866 * xmlSetEntityReferenceFunc:
pcercuei 0:03b5121a232e 14867 * @func: A valid function
pcercuei 0:03b5121a232e 14868 *
pcercuei 0:03b5121a232e 14869 * Set the function to call call back when a xml reference has been made
pcercuei 0:03b5121a232e 14870 */
pcercuei 0:03b5121a232e 14871 void
pcercuei 0:03b5121a232e 14872 xmlSetEntityReferenceFunc(xmlEntityReferenceFunc func)
pcercuei 0:03b5121a232e 14873 {
pcercuei 0:03b5121a232e 14874 xmlEntityRefFunc = func;
pcercuei 0:03b5121a232e 14875 }
pcercuei 0:03b5121a232e 14876 #endif /* LIBXML_LEGACY_ENABLED */
pcercuei 0:03b5121a232e 14877
pcercuei 0:03b5121a232e 14878 /************************************************************************
pcercuei 0:03b5121a232e 14879 * *
pcercuei 0:03b5121a232e 14880 * Miscellaneous *
pcercuei 0:03b5121a232e 14881 * *
pcercuei 0:03b5121a232e 14882 ************************************************************************/
pcercuei 0:03b5121a232e 14883
pcercuei 0:03b5121a232e 14884 #ifdef LIBXML_XPATH_ENABLED
pcercuei 0:03b5121a232e 14885 #include <libxml/xpath.h>
pcercuei 0:03b5121a232e 14886 #endif
pcercuei 0:03b5121a232e 14887
pcercuei 0:03b5121a232e 14888 extern void XMLCDECL xmlGenericErrorDefaultFunc(void *ctx, const char *msg, ...);
pcercuei 0:03b5121a232e 14889 static int xmlParserInitialized = 0;
pcercuei 0:03b5121a232e 14890
pcercuei 0:03b5121a232e 14891 /**
pcercuei 0:03b5121a232e 14892 * xmlInitParser:
pcercuei 0:03b5121a232e 14893 *
pcercuei 0:03b5121a232e 14894 * Initialization function for the XML parser.
pcercuei 0:03b5121a232e 14895 * This is not reentrant. Call once before processing in case of
pcercuei 0:03b5121a232e 14896 * use in multithreaded programs.
pcercuei 0:03b5121a232e 14897 */
pcercuei 0:03b5121a232e 14898
pcercuei 0:03b5121a232e 14899 void
pcercuei 0:03b5121a232e 14900 xmlInitParser(void) {
pcercuei 0:03b5121a232e 14901 if (xmlParserInitialized != 0)
pcercuei 0:03b5121a232e 14902 return;
pcercuei 0:03b5121a232e 14903
pcercuei 0:03b5121a232e 14904 #ifdef LIBXML_THREAD_ENABLED
pcercuei 0:03b5121a232e 14905 __xmlGlobalInitMutexLock();
pcercuei 0:03b5121a232e 14906 if (xmlParserInitialized == 0) {
pcercuei 0:03b5121a232e 14907 #endif
pcercuei 0:03b5121a232e 14908 xmlInitThreads();
pcercuei 0:03b5121a232e 14909 xmlInitGlobals();
pcercuei 0:03b5121a232e 14910 if ((xmlGenericError == xmlGenericErrorDefaultFunc) ||
pcercuei 0:03b5121a232e 14911 (xmlGenericError == NULL))
pcercuei 0:03b5121a232e 14912 initGenericErrorDefaultFunc(NULL);
pcercuei 0:03b5121a232e 14913 xmlInitMemory();
pcercuei 0:03b5121a232e 14914 xmlInitializeDict();
pcercuei 0:03b5121a232e 14915 xmlInitCharEncodingHandlers();
pcercuei 0:03b5121a232e 14916 xmlDefaultSAXHandlerInit();
pcercuei 0:03b5121a232e 14917 xmlRegisterDefaultInputCallbacks();
pcercuei 0:03b5121a232e 14918 #ifdef LIBXML_OUTPUT_ENABLED
pcercuei 0:03b5121a232e 14919 xmlRegisterDefaultOutputCallbacks();
pcercuei 0:03b5121a232e 14920 #endif /* LIBXML_OUTPUT_ENABLED */
pcercuei 0:03b5121a232e 14921 #ifdef LIBXML_HTML_ENABLED
pcercuei 0:03b5121a232e 14922 htmlInitAutoClose();
pcercuei 0:03b5121a232e 14923 htmlDefaultSAXHandlerInit();
pcercuei 0:03b5121a232e 14924 #endif
pcercuei 0:03b5121a232e 14925 #ifdef LIBXML_XPATH_ENABLED
pcercuei 0:03b5121a232e 14926 xmlXPathInit();
pcercuei 0:03b5121a232e 14927 #endif
pcercuei 0:03b5121a232e 14928 xmlParserInitialized = 1;
pcercuei 0:03b5121a232e 14929 #ifdef LIBXML_THREAD_ENABLED
pcercuei 0:03b5121a232e 14930 }
pcercuei 0:03b5121a232e 14931 __xmlGlobalInitMutexUnlock();
pcercuei 0:03b5121a232e 14932 #endif
pcercuei 0:03b5121a232e 14933 }
pcercuei 0:03b5121a232e 14934
pcercuei 0:03b5121a232e 14935 /**
pcercuei 0:03b5121a232e 14936 * xmlCleanupParser:
pcercuei 0:03b5121a232e 14937 *
pcercuei 0:03b5121a232e 14938 * This function name is somewhat misleading. It does not clean up
pcercuei 0:03b5121a232e 14939 * parser state, it cleans up memory allocated by the library itself.
pcercuei 0:03b5121a232e 14940 * It is a cleanup function for the XML library. It tries to reclaim all
pcercuei 0:03b5121a232e 14941 * related global memory allocated for the library processing.
pcercuei 0:03b5121a232e 14942 * It doesn't deallocate any document related memory. One should
pcercuei 0:03b5121a232e 14943 * call xmlCleanupParser() only when the process has finished using
pcercuei 0:03b5121a232e 14944 * the library and all XML/HTML documents built with it.
pcercuei 0:03b5121a232e 14945 * See also xmlInitParser() which has the opposite function of preparing
pcercuei 0:03b5121a232e 14946 * the library for operations.
pcercuei 0:03b5121a232e 14947 *
pcercuei 0:03b5121a232e 14948 * WARNING: if your application is multithreaded or has plugin support
pcercuei 0:03b5121a232e 14949 * calling this may crash the application if another thread or
pcercuei 0:03b5121a232e 14950 * a plugin is still using libxml2. It's sometimes very hard to
pcercuei 0:03b5121a232e 14951 * guess if libxml2 is in use in the application, some libraries
pcercuei 0:03b5121a232e 14952 * or plugins may use it without notice. In case of doubt abstain
pcercuei 0:03b5121a232e 14953 * from calling this function or do it just before calling exit()
pcercuei 0:03b5121a232e 14954 * to avoid leak reports from valgrind !
pcercuei 0:03b5121a232e 14955 */
pcercuei 0:03b5121a232e 14956
pcercuei 0:03b5121a232e 14957 void
pcercuei 0:03b5121a232e 14958 xmlCleanupParser(void) {
pcercuei 0:03b5121a232e 14959 if (!xmlParserInitialized)
pcercuei 0:03b5121a232e 14960 return;
pcercuei 0:03b5121a232e 14961
pcercuei 0:03b5121a232e 14962 xmlCleanupCharEncodingHandlers();
pcercuei 0:03b5121a232e 14963 #ifdef LIBXML_CATALOG_ENABLED
pcercuei 0:03b5121a232e 14964 xmlCatalogCleanup();
pcercuei 0:03b5121a232e 14965 #endif
pcercuei 0:03b5121a232e 14966 xmlDictCleanup();
pcercuei 0:03b5121a232e 14967 xmlCleanupInputCallbacks();
pcercuei 0:03b5121a232e 14968 #ifdef LIBXML_OUTPUT_ENABLED
pcercuei 0:03b5121a232e 14969 xmlCleanupOutputCallbacks();
pcercuei 0:03b5121a232e 14970 #endif
pcercuei 0:03b5121a232e 14971 #ifdef LIBXML_SCHEMAS_ENABLED
pcercuei 0:03b5121a232e 14972 xmlSchemaCleanupTypes();
pcercuei 0:03b5121a232e 14973 xmlRelaxNGCleanupTypes();
pcercuei 0:03b5121a232e 14974 #endif
pcercuei 0:03b5121a232e 14975 xmlResetLastError();
pcercuei 0:03b5121a232e 14976 xmlCleanupGlobals();
pcercuei 0:03b5121a232e 14977 xmlCleanupThreads(); /* must be last if called not from the main thread */
pcercuei 0:03b5121a232e 14978 xmlCleanupMemory();
pcercuei 0:03b5121a232e 14979 xmlParserInitialized = 0;
pcercuei 0:03b5121a232e 14980 }
pcercuei 0:03b5121a232e 14981
pcercuei 0:03b5121a232e 14982 /************************************************************************
pcercuei 0:03b5121a232e 14983 * *
pcercuei 0:03b5121a232e 14984 * New set (2.6.0) of simpler and more flexible APIs *
pcercuei 0:03b5121a232e 14985 * *
pcercuei 0:03b5121a232e 14986 ************************************************************************/
pcercuei 0:03b5121a232e 14987
pcercuei 0:03b5121a232e 14988 /**
pcercuei 0:03b5121a232e 14989 * DICT_FREE:
pcercuei 0:03b5121a232e 14990 * @str: a string
pcercuei 0:03b5121a232e 14991 *
pcercuei 0:03b5121a232e 14992 * Free a string if it is not owned by the "dict" dictionnary in the
pcercuei 0:03b5121a232e 14993 * current scope
pcercuei 0:03b5121a232e 14994 */
pcercuei 0:03b5121a232e 14995 #define DICT_FREE(str) \
pcercuei 0:03b5121a232e 14996 if ((str) && ((!dict) || \
pcercuei 0:03b5121a232e 14997 (xmlDictOwns(dict, (const xmlChar *)(str)) == 0))) \
pcercuei 0:03b5121a232e 14998 xmlFree((char *)(str));
pcercuei 0:03b5121a232e 14999
pcercuei 0:03b5121a232e 15000 /**
pcercuei 0:03b5121a232e 15001 * xmlCtxtReset:
pcercuei 0:03b5121a232e 15002 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 15003 *
pcercuei 0:03b5121a232e 15004 * Reset a parser context
pcercuei 0:03b5121a232e 15005 */
pcercuei 0:03b5121a232e 15006 void
pcercuei 0:03b5121a232e 15007 xmlCtxtReset(xmlParserCtxtPtr ctxt)
pcercuei 0:03b5121a232e 15008 {
pcercuei 0:03b5121a232e 15009 xmlParserInputPtr input;
pcercuei 0:03b5121a232e 15010 xmlDictPtr dict;
pcercuei 0:03b5121a232e 15011
pcercuei 0:03b5121a232e 15012 if (ctxt == NULL)
pcercuei 0:03b5121a232e 15013 return;
pcercuei 0:03b5121a232e 15014
pcercuei 0:03b5121a232e 15015 dict = ctxt->dict;
pcercuei 0:03b5121a232e 15016
pcercuei 0:03b5121a232e 15017 while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
pcercuei 0:03b5121a232e 15018 xmlFreeInputStream(input);
pcercuei 0:03b5121a232e 15019 }
pcercuei 0:03b5121a232e 15020 ctxt->inputNr = 0;
pcercuei 0:03b5121a232e 15021 ctxt->input = NULL;
pcercuei 0:03b5121a232e 15022
pcercuei 0:03b5121a232e 15023 ctxt->spaceNr = 0;
pcercuei 0:03b5121a232e 15024 if (ctxt->spaceTab != NULL) {
pcercuei 0:03b5121a232e 15025 ctxt->spaceTab[0] = -1;
pcercuei 0:03b5121a232e 15026 ctxt->space = &ctxt->spaceTab[0];
pcercuei 0:03b5121a232e 15027 } else {
pcercuei 0:03b5121a232e 15028 ctxt->space = NULL;
pcercuei 0:03b5121a232e 15029 }
pcercuei 0:03b5121a232e 15030
pcercuei 0:03b5121a232e 15031
pcercuei 0:03b5121a232e 15032 ctxt->nodeNr = 0;
pcercuei 0:03b5121a232e 15033 ctxt->node = NULL;
pcercuei 0:03b5121a232e 15034
pcercuei 0:03b5121a232e 15035 ctxt->nameNr = 0;
pcercuei 0:03b5121a232e 15036 ctxt->name = NULL;
pcercuei 0:03b5121a232e 15037
pcercuei 0:03b5121a232e 15038 DICT_FREE(ctxt->version);
pcercuei 0:03b5121a232e 15039 ctxt->version = NULL;
pcercuei 0:03b5121a232e 15040 DICT_FREE(ctxt->encoding);
pcercuei 0:03b5121a232e 15041 ctxt->encoding = NULL;
pcercuei 0:03b5121a232e 15042 DICT_FREE(ctxt->directory);
pcercuei 0:03b5121a232e 15043 ctxt->directory = NULL;
pcercuei 0:03b5121a232e 15044 DICT_FREE(ctxt->extSubURI);
pcercuei 0:03b5121a232e 15045 ctxt->extSubURI = NULL;
pcercuei 0:03b5121a232e 15046 DICT_FREE(ctxt->extSubSystem);
pcercuei 0:03b5121a232e 15047 ctxt->extSubSystem = NULL;
pcercuei 0:03b5121a232e 15048 if (ctxt->myDoc != NULL)
pcercuei 0:03b5121a232e 15049 xmlFreeDoc(ctxt->myDoc);
pcercuei 0:03b5121a232e 15050 ctxt->myDoc = NULL;
pcercuei 0:03b5121a232e 15051
pcercuei 0:03b5121a232e 15052 ctxt->standalone = -1;
pcercuei 0:03b5121a232e 15053 ctxt->hasExternalSubset = 0;
pcercuei 0:03b5121a232e 15054 ctxt->hasPErefs = 0;
pcercuei 0:03b5121a232e 15055 ctxt->html = 0;
pcercuei 0:03b5121a232e 15056 ctxt->external = 0;
pcercuei 0:03b5121a232e 15057 ctxt->instate = XML_PARSER_START;
pcercuei 0:03b5121a232e 15058 ctxt->token = 0;
pcercuei 0:03b5121a232e 15059
pcercuei 0:03b5121a232e 15060 ctxt->wellFormed = 1;
pcercuei 0:03b5121a232e 15061 ctxt->nsWellFormed = 1;
pcercuei 0:03b5121a232e 15062 ctxt->disableSAX = 0;
pcercuei 0:03b5121a232e 15063 ctxt->valid = 1;
pcercuei 0:03b5121a232e 15064 #if 0
pcercuei 0:03b5121a232e 15065 ctxt->vctxt.userData = ctxt;
pcercuei 0:03b5121a232e 15066 ctxt->vctxt.error = xmlParserValidityError;
pcercuei 0:03b5121a232e 15067 ctxt->vctxt.warning = xmlParserValidityWarning;
pcercuei 0:03b5121a232e 15068 #endif
pcercuei 0:03b5121a232e 15069 ctxt->record_info = 0;
pcercuei 0:03b5121a232e 15070 ctxt->nbChars = 0;
pcercuei 0:03b5121a232e 15071 ctxt->checkIndex = 0;
pcercuei 0:03b5121a232e 15072 ctxt->inSubset = 0;
pcercuei 0:03b5121a232e 15073 ctxt->errNo = XML_ERR_OK;
pcercuei 0:03b5121a232e 15074 ctxt->depth = 0;
pcercuei 0:03b5121a232e 15075 ctxt->charset = XML_CHAR_ENCODING_UTF8;
pcercuei 0:03b5121a232e 15076 ctxt->catalogs = NULL;
pcercuei 0:03b5121a232e 15077 ctxt->nbentities = 0;
pcercuei 0:03b5121a232e 15078 ctxt->sizeentities = 0;
pcercuei 0:03b5121a232e 15079 ctxt->sizeentcopy = 0;
pcercuei 0:03b5121a232e 15080 xmlInitNodeInfoSeq(&ctxt->node_seq);
pcercuei 0:03b5121a232e 15081
pcercuei 0:03b5121a232e 15082 if (ctxt->attsDefault != NULL) {
pcercuei 0:03b5121a232e 15083 xmlHashFree(ctxt->attsDefault, (xmlHashDeallocator) xmlFree);
pcercuei 0:03b5121a232e 15084 ctxt->attsDefault = NULL;
pcercuei 0:03b5121a232e 15085 }
pcercuei 0:03b5121a232e 15086 if (ctxt->attsSpecial != NULL) {
pcercuei 0:03b5121a232e 15087 xmlHashFree(ctxt->attsSpecial, NULL);
pcercuei 0:03b5121a232e 15088 ctxt->attsSpecial = NULL;
pcercuei 0:03b5121a232e 15089 }
pcercuei 0:03b5121a232e 15090
pcercuei 0:03b5121a232e 15091 #ifdef LIBXML_CATALOG_ENABLED
pcercuei 0:03b5121a232e 15092 if (ctxt->catalogs != NULL)
pcercuei 0:03b5121a232e 15093 xmlCatalogFreeLocal(ctxt->catalogs);
pcercuei 0:03b5121a232e 15094 #endif
pcercuei 0:03b5121a232e 15095 if (ctxt->lastError.code != XML_ERR_OK)
pcercuei 0:03b5121a232e 15096 xmlResetError(&ctxt->lastError);
pcercuei 0:03b5121a232e 15097 }
pcercuei 0:03b5121a232e 15098
pcercuei 0:03b5121a232e 15099 /**
pcercuei 0:03b5121a232e 15100 * xmlCtxtResetPush:
pcercuei 0:03b5121a232e 15101 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 15102 * @chunk: a pointer to an array of chars
pcercuei 0:03b5121a232e 15103 * @size: number of chars in the array
pcercuei 0:03b5121a232e 15104 * @filename: an optional file name or URI
pcercuei 0:03b5121a232e 15105 * @encoding: the document encoding, or NULL
pcercuei 0:03b5121a232e 15106 *
pcercuei 0:03b5121a232e 15107 * Reset a push parser context
pcercuei 0:03b5121a232e 15108 *
pcercuei 0:03b5121a232e 15109 * Returns 0 in case of success and 1 in case of error
pcercuei 0:03b5121a232e 15110 */
pcercuei 0:03b5121a232e 15111 int
pcercuei 0:03b5121a232e 15112 xmlCtxtResetPush(xmlParserCtxtPtr ctxt, const char *chunk,
pcercuei 0:03b5121a232e 15113 int size, const char *filename, const char *encoding)
pcercuei 0:03b5121a232e 15114 {
pcercuei 0:03b5121a232e 15115 xmlParserInputPtr inputStream;
pcercuei 0:03b5121a232e 15116 xmlParserInputBufferPtr buf;
pcercuei 0:03b5121a232e 15117 xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
pcercuei 0:03b5121a232e 15118
pcercuei 0:03b5121a232e 15119 if (ctxt == NULL)
pcercuei 0:03b5121a232e 15120 return(1);
pcercuei 0:03b5121a232e 15121
pcercuei 0:03b5121a232e 15122 if ((encoding == NULL) && (chunk != NULL) && (size >= 4))
pcercuei 0:03b5121a232e 15123 enc = xmlDetectCharEncoding((const xmlChar *) chunk, size);
pcercuei 0:03b5121a232e 15124
pcercuei 0:03b5121a232e 15125 buf = xmlAllocParserInputBuffer(enc);
pcercuei 0:03b5121a232e 15126 if (buf == NULL)
pcercuei 0:03b5121a232e 15127 return(1);
pcercuei 0:03b5121a232e 15128
pcercuei 0:03b5121a232e 15129 if (ctxt == NULL) {
pcercuei 0:03b5121a232e 15130 xmlFreeParserInputBuffer(buf);
pcercuei 0:03b5121a232e 15131 return(1);
pcercuei 0:03b5121a232e 15132 }
pcercuei 0:03b5121a232e 15133
pcercuei 0:03b5121a232e 15134 xmlCtxtReset(ctxt);
pcercuei 0:03b5121a232e 15135
pcercuei 0:03b5121a232e 15136 if (ctxt->pushTab == NULL) {
pcercuei 0:03b5121a232e 15137 ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 *
pcercuei 0:03b5121a232e 15138 sizeof(xmlChar *));
pcercuei 0:03b5121a232e 15139 if (ctxt->pushTab == NULL) {
pcercuei 0:03b5121a232e 15140 xmlErrMemory(ctxt, NULL);
pcercuei 0:03b5121a232e 15141 xmlFreeParserInputBuffer(buf);
pcercuei 0:03b5121a232e 15142 return(1);
pcercuei 0:03b5121a232e 15143 }
pcercuei 0:03b5121a232e 15144 }
pcercuei 0:03b5121a232e 15145
pcercuei 0:03b5121a232e 15146 if (filename == NULL) {
pcercuei 0:03b5121a232e 15147 ctxt->directory = NULL;
pcercuei 0:03b5121a232e 15148 } else {
pcercuei 0:03b5121a232e 15149 ctxt->directory = xmlParserGetDirectory(filename);
pcercuei 0:03b5121a232e 15150 }
pcercuei 0:03b5121a232e 15151
pcercuei 0:03b5121a232e 15152 inputStream = xmlNewInputStream(ctxt);
pcercuei 0:03b5121a232e 15153 if (inputStream == NULL) {
pcercuei 0:03b5121a232e 15154 xmlFreeParserInputBuffer(buf);
pcercuei 0:03b5121a232e 15155 return(1);
pcercuei 0:03b5121a232e 15156 }
pcercuei 0:03b5121a232e 15157
pcercuei 0:03b5121a232e 15158 if (filename == NULL)
pcercuei 0:03b5121a232e 15159 inputStream->filename = NULL;
pcercuei 0:03b5121a232e 15160 else
pcercuei 0:03b5121a232e 15161 inputStream->filename = (char *)
pcercuei 0:03b5121a232e 15162 xmlCanonicPath((const xmlChar *) filename);
pcercuei 0:03b5121a232e 15163 inputStream->buf = buf;
pcercuei 0:03b5121a232e 15164 xmlBufResetInput(buf->buffer, inputStream);
pcercuei 0:03b5121a232e 15165
pcercuei 0:03b5121a232e 15166 inputPush(ctxt, inputStream);
pcercuei 0:03b5121a232e 15167
pcercuei 0:03b5121a232e 15168 if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
pcercuei 0:03b5121a232e 15169 (ctxt->input->buf != NULL)) {
pcercuei 0:03b5121a232e 15170 size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer, ctxt->input);
pcercuei 0:03b5121a232e 15171 size_t cur = ctxt->input->cur - ctxt->input->base;
pcercuei 0:03b5121a232e 15172
pcercuei 0:03b5121a232e 15173 xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
pcercuei 0:03b5121a232e 15174
pcercuei 0:03b5121a232e 15175 xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur);
pcercuei 0:03b5121a232e 15176 #ifdef DEBUG_PUSH
pcercuei 0:03b5121a232e 15177 xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
pcercuei 0:03b5121a232e 15178 #endif
pcercuei 0:03b5121a232e 15179 }
pcercuei 0:03b5121a232e 15180
pcercuei 0:03b5121a232e 15181 if (encoding != NULL) {
pcercuei 0:03b5121a232e 15182 xmlCharEncodingHandlerPtr hdlr;
pcercuei 0:03b5121a232e 15183
pcercuei 0:03b5121a232e 15184 if (ctxt->encoding != NULL)
pcercuei 0:03b5121a232e 15185 xmlFree((xmlChar *) ctxt->encoding);
pcercuei 0:03b5121a232e 15186 ctxt->encoding = xmlStrdup((const xmlChar *) encoding);
pcercuei 0:03b5121a232e 15187
pcercuei 0:03b5121a232e 15188 hdlr = xmlFindCharEncodingHandler(encoding);
pcercuei 0:03b5121a232e 15189 if (hdlr != NULL) {
pcercuei 0:03b5121a232e 15190 xmlSwitchToEncoding(ctxt, hdlr);
pcercuei 0:03b5121a232e 15191 } else {
pcercuei 0:03b5121a232e 15192 xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
pcercuei 0:03b5121a232e 15193 "Unsupported encoding %s\n", BAD_CAST encoding);
pcercuei 0:03b5121a232e 15194 }
pcercuei 0:03b5121a232e 15195 } else if (enc != XML_CHAR_ENCODING_NONE) {
pcercuei 0:03b5121a232e 15196 xmlSwitchEncoding(ctxt, enc);
pcercuei 0:03b5121a232e 15197 }
pcercuei 0:03b5121a232e 15198
pcercuei 0:03b5121a232e 15199 return(0);
pcercuei 0:03b5121a232e 15200 }
pcercuei 0:03b5121a232e 15201
pcercuei 0:03b5121a232e 15202
pcercuei 0:03b5121a232e 15203 /**
pcercuei 0:03b5121a232e 15204 * xmlCtxtUseOptionsInternal:
pcercuei 0:03b5121a232e 15205 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 15206 * @options: a combination of xmlParserOption
pcercuei 0:03b5121a232e 15207 * @encoding: the user provided encoding to use
pcercuei 0:03b5121a232e 15208 *
pcercuei 0:03b5121a232e 15209 * Applies the options to the parser context
pcercuei 0:03b5121a232e 15210 *
pcercuei 0:03b5121a232e 15211 * Returns 0 in case of success, the set of unknown or unimplemented options
pcercuei 0:03b5121a232e 15212 * in case of error.
pcercuei 0:03b5121a232e 15213 */
pcercuei 0:03b5121a232e 15214 static int
pcercuei 0:03b5121a232e 15215 xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options, const char *encoding)
pcercuei 0:03b5121a232e 15216 {
pcercuei 0:03b5121a232e 15217 if (ctxt == NULL)
pcercuei 0:03b5121a232e 15218 return(-1);
pcercuei 0:03b5121a232e 15219 if (encoding != NULL) {
pcercuei 0:03b5121a232e 15220 if (ctxt->encoding != NULL)
pcercuei 0:03b5121a232e 15221 xmlFree((xmlChar *) ctxt->encoding);
pcercuei 0:03b5121a232e 15222 ctxt->encoding = xmlStrdup((const xmlChar *) encoding);
pcercuei 0:03b5121a232e 15223 }
pcercuei 0:03b5121a232e 15224 if (options & XML_PARSE_RECOVER) {
pcercuei 0:03b5121a232e 15225 ctxt->recovery = 1;
pcercuei 0:03b5121a232e 15226 options -= XML_PARSE_RECOVER;
pcercuei 0:03b5121a232e 15227 ctxt->options |= XML_PARSE_RECOVER;
pcercuei 0:03b5121a232e 15228 } else
pcercuei 0:03b5121a232e 15229 ctxt->recovery = 0;
pcercuei 0:03b5121a232e 15230 if (options & XML_PARSE_DTDLOAD) {
pcercuei 0:03b5121a232e 15231 ctxt->loadsubset = XML_DETECT_IDS;
pcercuei 0:03b5121a232e 15232 options -= XML_PARSE_DTDLOAD;
pcercuei 0:03b5121a232e 15233 ctxt->options |= XML_PARSE_DTDLOAD;
pcercuei 0:03b5121a232e 15234 } else
pcercuei 0:03b5121a232e 15235 ctxt->loadsubset = 0;
pcercuei 0:03b5121a232e 15236 if (options & XML_PARSE_DTDATTR) {
pcercuei 0:03b5121a232e 15237 ctxt->loadsubset |= XML_COMPLETE_ATTRS;
pcercuei 0:03b5121a232e 15238 options -= XML_PARSE_DTDATTR;
pcercuei 0:03b5121a232e 15239 ctxt->options |= XML_PARSE_DTDATTR;
pcercuei 0:03b5121a232e 15240 }
pcercuei 0:03b5121a232e 15241 if (options & XML_PARSE_NOENT) {
pcercuei 0:03b5121a232e 15242 ctxt->replaceEntities = 1;
pcercuei 0:03b5121a232e 15243 /* ctxt->loadsubset |= XML_DETECT_IDS; */
pcercuei 0:03b5121a232e 15244 options -= XML_PARSE_NOENT;
pcercuei 0:03b5121a232e 15245 ctxt->options |= XML_PARSE_NOENT;
pcercuei 0:03b5121a232e 15246 } else
pcercuei 0:03b5121a232e 15247 ctxt->replaceEntities = 0;
pcercuei 0:03b5121a232e 15248 if (options & XML_PARSE_PEDANTIC) {
pcercuei 0:03b5121a232e 15249 ctxt->pedantic = 1;
pcercuei 0:03b5121a232e 15250 options -= XML_PARSE_PEDANTIC;
pcercuei 0:03b5121a232e 15251 ctxt->options |= XML_PARSE_PEDANTIC;
pcercuei 0:03b5121a232e 15252 } else
pcercuei 0:03b5121a232e 15253 ctxt->pedantic = 0;
pcercuei 0:03b5121a232e 15254 if (options & XML_PARSE_NOBLANKS) {
pcercuei 0:03b5121a232e 15255 ctxt->keepBlanks = 0;
pcercuei 0:03b5121a232e 15256 ctxt->sax->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
pcercuei 0:03b5121a232e 15257 options -= XML_PARSE_NOBLANKS;
pcercuei 0:03b5121a232e 15258 ctxt->options |= XML_PARSE_NOBLANKS;
pcercuei 0:03b5121a232e 15259 } else
pcercuei 0:03b5121a232e 15260 ctxt->keepBlanks = 1;
pcercuei 0:03b5121a232e 15261 if (options & XML_PARSE_DTDVALID) {
pcercuei 0:03b5121a232e 15262 ctxt->validate = 1;
pcercuei 0:03b5121a232e 15263 if (options & XML_PARSE_NOWARNING)
pcercuei 0:03b5121a232e 15264 ctxt->vctxt.warning = NULL;
pcercuei 0:03b5121a232e 15265 if (options & XML_PARSE_NOERROR)
pcercuei 0:03b5121a232e 15266 ctxt->vctxt.error = NULL;
pcercuei 0:03b5121a232e 15267 options -= XML_PARSE_DTDVALID;
pcercuei 0:03b5121a232e 15268 ctxt->options |= XML_PARSE_DTDVALID;
pcercuei 0:03b5121a232e 15269 } else
pcercuei 0:03b5121a232e 15270 ctxt->validate = 0;
pcercuei 0:03b5121a232e 15271 if (options & XML_PARSE_NOWARNING) {
pcercuei 0:03b5121a232e 15272 ctxt->sax->warning = NULL;
pcercuei 0:03b5121a232e 15273 options -= XML_PARSE_NOWARNING;
pcercuei 0:03b5121a232e 15274 }
pcercuei 0:03b5121a232e 15275 if (options & XML_PARSE_NOERROR) {
pcercuei 0:03b5121a232e 15276 ctxt->sax->error = NULL;
pcercuei 0:03b5121a232e 15277 ctxt->sax->fatalError = NULL;
pcercuei 0:03b5121a232e 15278 options -= XML_PARSE_NOERROR;
pcercuei 0:03b5121a232e 15279 }
pcercuei 0:03b5121a232e 15280 #ifdef LIBXML_SAX1_ENABLED
pcercuei 0:03b5121a232e 15281 if (options & XML_PARSE_SAX1) {
pcercuei 0:03b5121a232e 15282 ctxt->sax->startElement = xmlSAX2StartElement;
pcercuei 0:03b5121a232e 15283 ctxt->sax->endElement = xmlSAX2EndElement;
pcercuei 0:03b5121a232e 15284 ctxt->sax->startElementNs = NULL;
pcercuei 0:03b5121a232e 15285 ctxt->sax->endElementNs = NULL;
pcercuei 0:03b5121a232e 15286 ctxt->sax->initialized = 1;
pcercuei 0:03b5121a232e 15287 options -= XML_PARSE_SAX1;
pcercuei 0:03b5121a232e 15288 ctxt->options |= XML_PARSE_SAX1;
pcercuei 0:03b5121a232e 15289 }
pcercuei 0:03b5121a232e 15290 #endif /* LIBXML_SAX1_ENABLED */
pcercuei 0:03b5121a232e 15291 if (options & XML_PARSE_NODICT) {
pcercuei 0:03b5121a232e 15292 ctxt->dictNames = 0;
pcercuei 0:03b5121a232e 15293 options -= XML_PARSE_NODICT;
pcercuei 0:03b5121a232e 15294 ctxt->options |= XML_PARSE_NODICT;
pcercuei 0:03b5121a232e 15295 } else {
pcercuei 0:03b5121a232e 15296 ctxt->dictNames = 1;
pcercuei 0:03b5121a232e 15297 }
pcercuei 0:03b5121a232e 15298 if (options & XML_PARSE_NOCDATA) {
pcercuei 0:03b5121a232e 15299 ctxt->sax->cdataBlock = NULL;
pcercuei 0:03b5121a232e 15300 options -= XML_PARSE_NOCDATA;
pcercuei 0:03b5121a232e 15301 ctxt->options |= XML_PARSE_NOCDATA;
pcercuei 0:03b5121a232e 15302 }
pcercuei 0:03b5121a232e 15303 if (options & XML_PARSE_NSCLEAN) {
pcercuei 0:03b5121a232e 15304 ctxt->options |= XML_PARSE_NSCLEAN;
pcercuei 0:03b5121a232e 15305 options -= XML_PARSE_NSCLEAN;
pcercuei 0:03b5121a232e 15306 }
pcercuei 0:03b5121a232e 15307 if (options & XML_PARSE_NONET) {
pcercuei 0:03b5121a232e 15308 ctxt->options |= XML_PARSE_NONET;
pcercuei 0:03b5121a232e 15309 options -= XML_PARSE_NONET;
pcercuei 0:03b5121a232e 15310 }
pcercuei 0:03b5121a232e 15311 if (options & XML_PARSE_COMPACT) {
pcercuei 0:03b5121a232e 15312 ctxt->options |= XML_PARSE_COMPACT;
pcercuei 0:03b5121a232e 15313 options -= XML_PARSE_COMPACT;
pcercuei 0:03b5121a232e 15314 }
pcercuei 0:03b5121a232e 15315 if (options & XML_PARSE_OLD10) {
pcercuei 0:03b5121a232e 15316 ctxt->options |= XML_PARSE_OLD10;
pcercuei 0:03b5121a232e 15317 options -= XML_PARSE_OLD10;
pcercuei 0:03b5121a232e 15318 }
pcercuei 0:03b5121a232e 15319 if (options & XML_PARSE_NOBASEFIX) {
pcercuei 0:03b5121a232e 15320 ctxt->options |= XML_PARSE_NOBASEFIX;
pcercuei 0:03b5121a232e 15321 options -= XML_PARSE_NOBASEFIX;
pcercuei 0:03b5121a232e 15322 }
pcercuei 0:03b5121a232e 15323 if (options & XML_PARSE_HUGE) {
pcercuei 0:03b5121a232e 15324 ctxt->options |= XML_PARSE_HUGE;
pcercuei 0:03b5121a232e 15325 options -= XML_PARSE_HUGE;
pcercuei 0:03b5121a232e 15326 if (ctxt->dict != NULL)
pcercuei 0:03b5121a232e 15327 xmlDictSetLimit(ctxt->dict, 0);
pcercuei 0:03b5121a232e 15328 }
pcercuei 0:03b5121a232e 15329 if (options & XML_PARSE_OLDSAX) {
pcercuei 0:03b5121a232e 15330 ctxt->options |= XML_PARSE_OLDSAX;
pcercuei 0:03b5121a232e 15331 options -= XML_PARSE_OLDSAX;
pcercuei 0:03b5121a232e 15332 }
pcercuei 0:03b5121a232e 15333 if (options & XML_PARSE_IGNORE_ENC) {
pcercuei 0:03b5121a232e 15334 ctxt->options |= XML_PARSE_IGNORE_ENC;
pcercuei 0:03b5121a232e 15335 options -= XML_PARSE_IGNORE_ENC;
pcercuei 0:03b5121a232e 15336 }
pcercuei 0:03b5121a232e 15337 if (options & XML_PARSE_BIG_LINES) {
pcercuei 0:03b5121a232e 15338 ctxt->options |= XML_PARSE_BIG_LINES;
pcercuei 0:03b5121a232e 15339 options -= XML_PARSE_BIG_LINES;
pcercuei 0:03b5121a232e 15340 }
pcercuei 0:03b5121a232e 15341 ctxt->linenumbers = 1;
pcercuei 0:03b5121a232e 15342 return (options);
pcercuei 0:03b5121a232e 15343 }
pcercuei 0:03b5121a232e 15344
pcercuei 0:03b5121a232e 15345 /**
pcercuei 0:03b5121a232e 15346 * xmlCtxtUseOptions:
pcercuei 0:03b5121a232e 15347 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 15348 * @options: a combination of xmlParserOption
pcercuei 0:03b5121a232e 15349 *
pcercuei 0:03b5121a232e 15350 * Applies the options to the parser context
pcercuei 0:03b5121a232e 15351 *
pcercuei 0:03b5121a232e 15352 * Returns 0 in case of success, the set of unknown or unimplemented options
pcercuei 0:03b5121a232e 15353 * in case of error.
pcercuei 0:03b5121a232e 15354 */
pcercuei 0:03b5121a232e 15355 int
pcercuei 0:03b5121a232e 15356 xmlCtxtUseOptions(xmlParserCtxtPtr ctxt, int options)
pcercuei 0:03b5121a232e 15357 {
pcercuei 0:03b5121a232e 15358 return(xmlCtxtUseOptionsInternal(ctxt, options, NULL));
pcercuei 0:03b5121a232e 15359 }
pcercuei 0:03b5121a232e 15360
pcercuei 0:03b5121a232e 15361 /**
pcercuei 0:03b5121a232e 15362 * xmlDoRead:
pcercuei 0:03b5121a232e 15363 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 15364 * @URL: the base URL to use for the document
pcercuei 0:03b5121a232e 15365 * @encoding: the document encoding, or NULL
pcercuei 0:03b5121a232e 15366 * @options: a combination of xmlParserOption
pcercuei 0:03b5121a232e 15367 * @reuse: keep the context for reuse
pcercuei 0:03b5121a232e 15368 *
pcercuei 0:03b5121a232e 15369 * Common front-end for the xmlRead functions
pcercuei 0:03b5121a232e 15370 *
pcercuei 0:03b5121a232e 15371 * Returns the resulting document tree or NULL
pcercuei 0:03b5121a232e 15372 */
pcercuei 0:03b5121a232e 15373 static xmlDocPtr
pcercuei 0:03b5121a232e 15374 xmlDoRead(xmlParserCtxtPtr ctxt, const char *URL, const char *encoding,
pcercuei 0:03b5121a232e 15375 int options, int reuse)
pcercuei 0:03b5121a232e 15376 {
pcercuei 0:03b5121a232e 15377 xmlDocPtr ret;
pcercuei 0:03b5121a232e 15378
pcercuei 0:03b5121a232e 15379 xmlCtxtUseOptionsInternal(ctxt, options, encoding);
pcercuei 0:03b5121a232e 15380 if (encoding != NULL) {
pcercuei 0:03b5121a232e 15381 xmlCharEncodingHandlerPtr hdlr;
pcercuei 0:03b5121a232e 15382
pcercuei 0:03b5121a232e 15383 hdlr = xmlFindCharEncodingHandler(encoding);
pcercuei 0:03b5121a232e 15384 if (hdlr != NULL)
pcercuei 0:03b5121a232e 15385 xmlSwitchToEncoding(ctxt, hdlr);
pcercuei 0:03b5121a232e 15386 }
pcercuei 0:03b5121a232e 15387 if ((URL != NULL) && (ctxt->input != NULL) &&
pcercuei 0:03b5121a232e 15388 (ctxt->input->filename == NULL))
pcercuei 0:03b5121a232e 15389 ctxt->input->filename = (char *) xmlStrdup((const xmlChar *) URL);
pcercuei 0:03b5121a232e 15390 xmlParseDocument(ctxt);
pcercuei 0:03b5121a232e 15391 if ((ctxt->wellFormed) || ctxt->recovery)
pcercuei 0:03b5121a232e 15392 ret = ctxt->myDoc;
pcercuei 0:03b5121a232e 15393 else {
pcercuei 0:03b5121a232e 15394 ret = NULL;
pcercuei 0:03b5121a232e 15395 if (ctxt->myDoc != NULL) {
pcercuei 0:03b5121a232e 15396 xmlFreeDoc(ctxt->myDoc);
pcercuei 0:03b5121a232e 15397 }
pcercuei 0:03b5121a232e 15398 }
pcercuei 0:03b5121a232e 15399 ctxt->myDoc = NULL;
pcercuei 0:03b5121a232e 15400 if (!reuse) {
pcercuei 0:03b5121a232e 15401 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 15402 }
pcercuei 0:03b5121a232e 15403
pcercuei 0:03b5121a232e 15404 return (ret);
pcercuei 0:03b5121a232e 15405 }
pcercuei 0:03b5121a232e 15406
pcercuei 0:03b5121a232e 15407 /**
pcercuei 0:03b5121a232e 15408 * xmlReadDoc:
pcercuei 0:03b5121a232e 15409 * @cur: a pointer to a zero terminated string
pcercuei 0:03b5121a232e 15410 * @URL: the base URL to use for the document
pcercuei 0:03b5121a232e 15411 * @encoding: the document encoding, or NULL
pcercuei 0:03b5121a232e 15412 * @options: a combination of xmlParserOption
pcercuei 0:03b5121a232e 15413 *
pcercuei 0:03b5121a232e 15414 * parse an XML in-memory document and build a tree.
pcercuei 0:03b5121a232e 15415 *
pcercuei 0:03b5121a232e 15416 * Returns the resulting document tree
pcercuei 0:03b5121a232e 15417 */
pcercuei 0:03b5121a232e 15418 xmlDocPtr
pcercuei 0:03b5121a232e 15419 xmlReadDoc(const xmlChar * cur, const char *URL, const char *encoding, int options)
pcercuei 0:03b5121a232e 15420 {
pcercuei 0:03b5121a232e 15421 xmlParserCtxtPtr ctxt;
pcercuei 0:03b5121a232e 15422
pcercuei 0:03b5121a232e 15423 if (cur == NULL)
pcercuei 0:03b5121a232e 15424 return (NULL);
pcercuei 0:03b5121a232e 15425 xmlInitParser();
pcercuei 0:03b5121a232e 15426
pcercuei 0:03b5121a232e 15427 ctxt = xmlCreateDocParserCtxt(cur);
pcercuei 0:03b5121a232e 15428 if (ctxt == NULL)
pcercuei 0:03b5121a232e 15429 return (NULL);
pcercuei 0:03b5121a232e 15430 return (xmlDoRead(ctxt, URL, encoding, options, 0));
pcercuei 0:03b5121a232e 15431 }
pcercuei 0:03b5121a232e 15432
pcercuei 0:03b5121a232e 15433 /**
pcercuei 0:03b5121a232e 15434 * xmlReadFile:
pcercuei 0:03b5121a232e 15435 * @filename: a file or URL
pcercuei 0:03b5121a232e 15436 * @encoding: the document encoding, or NULL
pcercuei 0:03b5121a232e 15437 * @options: a combination of xmlParserOption
pcercuei 0:03b5121a232e 15438 *
pcercuei 0:03b5121a232e 15439 * parse an XML file from the filesystem or the network.
pcercuei 0:03b5121a232e 15440 *
pcercuei 0:03b5121a232e 15441 * Returns the resulting document tree
pcercuei 0:03b5121a232e 15442 */
pcercuei 0:03b5121a232e 15443 xmlDocPtr
pcercuei 0:03b5121a232e 15444 xmlReadFile(const char *filename, const char *encoding, int options)
pcercuei 0:03b5121a232e 15445 {
pcercuei 0:03b5121a232e 15446 xmlParserCtxtPtr ctxt;
pcercuei 0:03b5121a232e 15447
pcercuei 0:03b5121a232e 15448 xmlInitParser();
pcercuei 0:03b5121a232e 15449 ctxt = xmlCreateURLParserCtxt(filename, options);
pcercuei 0:03b5121a232e 15450 if (ctxt == NULL)
pcercuei 0:03b5121a232e 15451 return (NULL);
pcercuei 0:03b5121a232e 15452 return (xmlDoRead(ctxt, NULL, encoding, options, 0));
pcercuei 0:03b5121a232e 15453 }
pcercuei 0:03b5121a232e 15454
pcercuei 0:03b5121a232e 15455 /**
pcercuei 0:03b5121a232e 15456 * xmlReadMemory:
pcercuei 0:03b5121a232e 15457 * @buffer: a pointer to a char array
pcercuei 0:03b5121a232e 15458 * @size: the size of the array
pcercuei 0:03b5121a232e 15459 * @URL: the base URL to use for the document
pcercuei 0:03b5121a232e 15460 * @encoding: the document encoding, or NULL
pcercuei 0:03b5121a232e 15461 * @options: a combination of xmlParserOption
pcercuei 0:03b5121a232e 15462 *
pcercuei 0:03b5121a232e 15463 * parse an XML in-memory document and build a tree.
pcercuei 0:03b5121a232e 15464 *
pcercuei 0:03b5121a232e 15465 * Returns the resulting document tree
pcercuei 0:03b5121a232e 15466 */
pcercuei 0:03b5121a232e 15467 xmlDocPtr
pcercuei 0:03b5121a232e 15468 xmlReadMemory(const char *buffer, int size, const char *URL, const char *encoding, int options)
pcercuei 0:03b5121a232e 15469 {
pcercuei 0:03b5121a232e 15470 xmlParserCtxtPtr ctxt;
pcercuei 0:03b5121a232e 15471
pcercuei 0:03b5121a232e 15472 xmlInitParser();
pcercuei 0:03b5121a232e 15473 ctxt = xmlCreateMemoryParserCtxt(buffer, size);
pcercuei 0:03b5121a232e 15474 if (ctxt == NULL)
pcercuei 0:03b5121a232e 15475 return (NULL);
pcercuei 0:03b5121a232e 15476 return (xmlDoRead(ctxt, URL, encoding, options, 0));
pcercuei 0:03b5121a232e 15477 }
pcercuei 0:03b5121a232e 15478
pcercuei 0:03b5121a232e 15479 /**
pcercuei 0:03b5121a232e 15480 * xmlReadFd:
pcercuei 0:03b5121a232e 15481 * @fd: an open file descriptor
pcercuei 0:03b5121a232e 15482 * @URL: the base URL to use for the document
pcercuei 0:03b5121a232e 15483 * @encoding: the document encoding, or NULL
pcercuei 0:03b5121a232e 15484 * @options: a combination of xmlParserOption
pcercuei 0:03b5121a232e 15485 *
pcercuei 0:03b5121a232e 15486 * parse an XML from a file descriptor and build a tree.
pcercuei 0:03b5121a232e 15487 * NOTE that the file descriptor will not be closed when the
pcercuei 0:03b5121a232e 15488 * reader is closed or reset.
pcercuei 0:03b5121a232e 15489 *
pcercuei 0:03b5121a232e 15490 * Returns the resulting document tree
pcercuei 0:03b5121a232e 15491 */
pcercuei 0:03b5121a232e 15492 xmlDocPtr
pcercuei 0:03b5121a232e 15493 xmlReadFd(int fd, const char *URL, const char *encoding, int options)
pcercuei 0:03b5121a232e 15494 {
pcercuei 0:03b5121a232e 15495 xmlParserCtxtPtr ctxt;
pcercuei 0:03b5121a232e 15496 xmlParserInputBufferPtr input;
pcercuei 0:03b5121a232e 15497 xmlParserInputPtr stream;
pcercuei 0:03b5121a232e 15498
pcercuei 0:03b5121a232e 15499 if (fd < 0)
pcercuei 0:03b5121a232e 15500 return (NULL);
pcercuei 0:03b5121a232e 15501 xmlInitParser();
pcercuei 0:03b5121a232e 15502
pcercuei 0:03b5121a232e 15503 input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
pcercuei 0:03b5121a232e 15504 if (input == NULL)
pcercuei 0:03b5121a232e 15505 return (NULL);
pcercuei 0:03b5121a232e 15506 input->closecallback = NULL;
pcercuei 0:03b5121a232e 15507 ctxt = xmlNewParserCtxt();
pcercuei 0:03b5121a232e 15508 if (ctxt == NULL) {
pcercuei 0:03b5121a232e 15509 xmlFreeParserInputBuffer(input);
pcercuei 0:03b5121a232e 15510 return (NULL);
pcercuei 0:03b5121a232e 15511 }
pcercuei 0:03b5121a232e 15512 stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
pcercuei 0:03b5121a232e 15513 if (stream == NULL) {
pcercuei 0:03b5121a232e 15514 xmlFreeParserInputBuffer(input);
pcercuei 0:03b5121a232e 15515 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 15516 return (NULL);
pcercuei 0:03b5121a232e 15517 }
pcercuei 0:03b5121a232e 15518 inputPush(ctxt, stream);
pcercuei 0:03b5121a232e 15519 return (xmlDoRead(ctxt, URL, encoding, options, 0));
pcercuei 0:03b5121a232e 15520 }
pcercuei 0:03b5121a232e 15521
pcercuei 0:03b5121a232e 15522 /**
pcercuei 0:03b5121a232e 15523 * xmlReadIO:
pcercuei 0:03b5121a232e 15524 * @ioread: an I/O read function
pcercuei 0:03b5121a232e 15525 * @ioclose: an I/O close function
pcercuei 0:03b5121a232e 15526 * @ioctx: an I/O handler
pcercuei 0:03b5121a232e 15527 * @URL: the base URL to use for the document
pcercuei 0:03b5121a232e 15528 * @encoding: the document encoding, or NULL
pcercuei 0:03b5121a232e 15529 * @options: a combination of xmlParserOption
pcercuei 0:03b5121a232e 15530 *
pcercuei 0:03b5121a232e 15531 * parse an XML document from I/O functions and source and build a tree.
pcercuei 0:03b5121a232e 15532 *
pcercuei 0:03b5121a232e 15533 * Returns the resulting document tree
pcercuei 0:03b5121a232e 15534 */
pcercuei 0:03b5121a232e 15535 xmlDocPtr
pcercuei 0:03b5121a232e 15536 xmlReadIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
pcercuei 0:03b5121a232e 15537 void *ioctx, const char *URL, const char *encoding, int options)
pcercuei 0:03b5121a232e 15538 {
pcercuei 0:03b5121a232e 15539 xmlParserCtxtPtr ctxt;
pcercuei 0:03b5121a232e 15540 xmlParserInputBufferPtr input;
pcercuei 0:03b5121a232e 15541 xmlParserInputPtr stream;
pcercuei 0:03b5121a232e 15542
pcercuei 0:03b5121a232e 15543 if (ioread == NULL)
pcercuei 0:03b5121a232e 15544 return (NULL);
pcercuei 0:03b5121a232e 15545 xmlInitParser();
pcercuei 0:03b5121a232e 15546
pcercuei 0:03b5121a232e 15547 input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
pcercuei 0:03b5121a232e 15548 XML_CHAR_ENCODING_NONE);
pcercuei 0:03b5121a232e 15549 if (input == NULL) {
pcercuei 0:03b5121a232e 15550 if (ioclose != NULL)
pcercuei 0:03b5121a232e 15551 ioclose(ioctx);
pcercuei 0:03b5121a232e 15552 return (NULL);
pcercuei 0:03b5121a232e 15553 }
pcercuei 0:03b5121a232e 15554 ctxt = xmlNewParserCtxt();
pcercuei 0:03b5121a232e 15555 if (ctxt == NULL) {
pcercuei 0:03b5121a232e 15556 xmlFreeParserInputBuffer(input);
pcercuei 0:03b5121a232e 15557 return (NULL);
pcercuei 0:03b5121a232e 15558 }
pcercuei 0:03b5121a232e 15559 stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
pcercuei 0:03b5121a232e 15560 if (stream == NULL) {
pcercuei 0:03b5121a232e 15561 xmlFreeParserInputBuffer(input);
pcercuei 0:03b5121a232e 15562 xmlFreeParserCtxt(ctxt);
pcercuei 0:03b5121a232e 15563 return (NULL);
pcercuei 0:03b5121a232e 15564 }
pcercuei 0:03b5121a232e 15565 inputPush(ctxt, stream);
pcercuei 0:03b5121a232e 15566 return (xmlDoRead(ctxt, URL, encoding, options, 0));
pcercuei 0:03b5121a232e 15567 }
pcercuei 0:03b5121a232e 15568
pcercuei 0:03b5121a232e 15569 /**
pcercuei 0:03b5121a232e 15570 * xmlCtxtReadDoc:
pcercuei 0:03b5121a232e 15571 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 15572 * @cur: a pointer to a zero terminated string
pcercuei 0:03b5121a232e 15573 * @URL: the base URL to use for the document
pcercuei 0:03b5121a232e 15574 * @encoding: the document encoding, or NULL
pcercuei 0:03b5121a232e 15575 * @options: a combination of xmlParserOption
pcercuei 0:03b5121a232e 15576 *
pcercuei 0:03b5121a232e 15577 * parse an XML in-memory document and build a tree.
pcercuei 0:03b5121a232e 15578 * This reuses the existing @ctxt parser context
pcercuei 0:03b5121a232e 15579 *
pcercuei 0:03b5121a232e 15580 * Returns the resulting document tree
pcercuei 0:03b5121a232e 15581 */
pcercuei 0:03b5121a232e 15582 xmlDocPtr
pcercuei 0:03b5121a232e 15583 xmlCtxtReadDoc(xmlParserCtxtPtr ctxt, const xmlChar * cur,
pcercuei 0:03b5121a232e 15584 const char *URL, const char *encoding, int options)
pcercuei 0:03b5121a232e 15585 {
pcercuei 0:03b5121a232e 15586 xmlParserInputPtr stream;
pcercuei 0:03b5121a232e 15587
pcercuei 0:03b5121a232e 15588 if (cur == NULL)
pcercuei 0:03b5121a232e 15589 return (NULL);
pcercuei 0:03b5121a232e 15590 if (ctxt == NULL)
pcercuei 0:03b5121a232e 15591 return (NULL);
pcercuei 0:03b5121a232e 15592 xmlInitParser();
pcercuei 0:03b5121a232e 15593
pcercuei 0:03b5121a232e 15594 xmlCtxtReset(ctxt);
pcercuei 0:03b5121a232e 15595
pcercuei 0:03b5121a232e 15596 stream = xmlNewStringInputStream(ctxt, cur);
pcercuei 0:03b5121a232e 15597 if (stream == NULL) {
pcercuei 0:03b5121a232e 15598 return (NULL);
pcercuei 0:03b5121a232e 15599 }
pcercuei 0:03b5121a232e 15600 inputPush(ctxt, stream);
pcercuei 0:03b5121a232e 15601 return (xmlDoRead(ctxt, URL, encoding, options, 1));
pcercuei 0:03b5121a232e 15602 }
pcercuei 0:03b5121a232e 15603
pcercuei 0:03b5121a232e 15604 /**
pcercuei 0:03b5121a232e 15605 * xmlCtxtReadFile:
pcercuei 0:03b5121a232e 15606 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 15607 * @filename: a file or URL
pcercuei 0:03b5121a232e 15608 * @encoding: the document encoding, or NULL
pcercuei 0:03b5121a232e 15609 * @options: a combination of xmlParserOption
pcercuei 0:03b5121a232e 15610 *
pcercuei 0:03b5121a232e 15611 * parse an XML file from the filesystem or the network.
pcercuei 0:03b5121a232e 15612 * This reuses the existing @ctxt parser context
pcercuei 0:03b5121a232e 15613 *
pcercuei 0:03b5121a232e 15614 * Returns the resulting document tree
pcercuei 0:03b5121a232e 15615 */
pcercuei 0:03b5121a232e 15616 xmlDocPtr
pcercuei 0:03b5121a232e 15617 xmlCtxtReadFile(xmlParserCtxtPtr ctxt, const char *filename,
pcercuei 0:03b5121a232e 15618 const char *encoding, int options)
pcercuei 0:03b5121a232e 15619 {
pcercuei 0:03b5121a232e 15620 xmlParserInputPtr stream;
pcercuei 0:03b5121a232e 15621
pcercuei 0:03b5121a232e 15622 if (filename == NULL)
pcercuei 0:03b5121a232e 15623 return (NULL);
pcercuei 0:03b5121a232e 15624 if (ctxt == NULL)
pcercuei 0:03b5121a232e 15625 return (NULL);
pcercuei 0:03b5121a232e 15626 xmlInitParser();
pcercuei 0:03b5121a232e 15627
pcercuei 0:03b5121a232e 15628 xmlCtxtReset(ctxt);
pcercuei 0:03b5121a232e 15629
pcercuei 0:03b5121a232e 15630 stream = xmlLoadExternalEntity(filename, NULL, ctxt);
pcercuei 0:03b5121a232e 15631 if (stream == NULL) {
pcercuei 0:03b5121a232e 15632 return (NULL);
pcercuei 0:03b5121a232e 15633 }
pcercuei 0:03b5121a232e 15634 inputPush(ctxt, stream);
pcercuei 0:03b5121a232e 15635 return (xmlDoRead(ctxt, NULL, encoding, options, 1));
pcercuei 0:03b5121a232e 15636 }
pcercuei 0:03b5121a232e 15637
pcercuei 0:03b5121a232e 15638 /**
pcercuei 0:03b5121a232e 15639 * xmlCtxtReadMemory:
pcercuei 0:03b5121a232e 15640 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 15641 * @buffer: a pointer to a char array
pcercuei 0:03b5121a232e 15642 * @size: the size of the array
pcercuei 0:03b5121a232e 15643 * @URL: the base URL to use for the document
pcercuei 0:03b5121a232e 15644 * @encoding: the document encoding, or NULL
pcercuei 0:03b5121a232e 15645 * @options: a combination of xmlParserOption
pcercuei 0:03b5121a232e 15646 *
pcercuei 0:03b5121a232e 15647 * parse an XML in-memory document and build a tree.
pcercuei 0:03b5121a232e 15648 * This reuses the existing @ctxt parser context
pcercuei 0:03b5121a232e 15649 *
pcercuei 0:03b5121a232e 15650 * Returns the resulting document tree
pcercuei 0:03b5121a232e 15651 */
pcercuei 0:03b5121a232e 15652 xmlDocPtr
pcercuei 0:03b5121a232e 15653 xmlCtxtReadMemory(xmlParserCtxtPtr ctxt, const char *buffer, int size,
pcercuei 0:03b5121a232e 15654 const char *URL, const char *encoding, int options)
pcercuei 0:03b5121a232e 15655 {
pcercuei 0:03b5121a232e 15656 xmlParserInputBufferPtr input;
pcercuei 0:03b5121a232e 15657 xmlParserInputPtr stream;
pcercuei 0:03b5121a232e 15658
pcercuei 0:03b5121a232e 15659 if (ctxt == NULL)
pcercuei 0:03b5121a232e 15660 return (NULL);
pcercuei 0:03b5121a232e 15661 if (buffer == NULL)
pcercuei 0:03b5121a232e 15662 return (NULL);
pcercuei 0:03b5121a232e 15663 xmlInitParser();
pcercuei 0:03b5121a232e 15664
pcercuei 0:03b5121a232e 15665 xmlCtxtReset(ctxt);
pcercuei 0:03b5121a232e 15666
pcercuei 0:03b5121a232e 15667 input = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
pcercuei 0:03b5121a232e 15668 if (input == NULL) {
pcercuei 0:03b5121a232e 15669 return(NULL);
pcercuei 0:03b5121a232e 15670 }
pcercuei 0:03b5121a232e 15671
pcercuei 0:03b5121a232e 15672 stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
pcercuei 0:03b5121a232e 15673 if (stream == NULL) {
pcercuei 0:03b5121a232e 15674 xmlFreeParserInputBuffer(input);
pcercuei 0:03b5121a232e 15675 return(NULL);
pcercuei 0:03b5121a232e 15676 }
pcercuei 0:03b5121a232e 15677
pcercuei 0:03b5121a232e 15678 inputPush(ctxt, stream);
pcercuei 0:03b5121a232e 15679 return (xmlDoRead(ctxt, URL, encoding, options, 1));
pcercuei 0:03b5121a232e 15680 }
pcercuei 0:03b5121a232e 15681
pcercuei 0:03b5121a232e 15682 /**
pcercuei 0:03b5121a232e 15683 * xmlCtxtReadFd:
pcercuei 0:03b5121a232e 15684 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 15685 * @fd: an open file descriptor
pcercuei 0:03b5121a232e 15686 * @URL: the base URL to use for the document
pcercuei 0:03b5121a232e 15687 * @encoding: the document encoding, or NULL
pcercuei 0:03b5121a232e 15688 * @options: a combination of xmlParserOption
pcercuei 0:03b5121a232e 15689 *
pcercuei 0:03b5121a232e 15690 * parse an XML from a file descriptor and build a tree.
pcercuei 0:03b5121a232e 15691 * This reuses the existing @ctxt parser context
pcercuei 0:03b5121a232e 15692 * NOTE that the file descriptor will not be closed when the
pcercuei 0:03b5121a232e 15693 * reader is closed or reset.
pcercuei 0:03b5121a232e 15694 *
pcercuei 0:03b5121a232e 15695 * Returns the resulting document tree
pcercuei 0:03b5121a232e 15696 */
pcercuei 0:03b5121a232e 15697 xmlDocPtr
pcercuei 0:03b5121a232e 15698 xmlCtxtReadFd(xmlParserCtxtPtr ctxt, int fd,
pcercuei 0:03b5121a232e 15699 const char *URL, const char *encoding, int options)
pcercuei 0:03b5121a232e 15700 {
pcercuei 0:03b5121a232e 15701 xmlParserInputBufferPtr input;
pcercuei 0:03b5121a232e 15702 xmlParserInputPtr stream;
pcercuei 0:03b5121a232e 15703
pcercuei 0:03b5121a232e 15704 if (fd < 0)
pcercuei 0:03b5121a232e 15705 return (NULL);
pcercuei 0:03b5121a232e 15706 if (ctxt == NULL)
pcercuei 0:03b5121a232e 15707 return (NULL);
pcercuei 0:03b5121a232e 15708 xmlInitParser();
pcercuei 0:03b5121a232e 15709
pcercuei 0:03b5121a232e 15710 xmlCtxtReset(ctxt);
pcercuei 0:03b5121a232e 15711
pcercuei 0:03b5121a232e 15712
pcercuei 0:03b5121a232e 15713 input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
pcercuei 0:03b5121a232e 15714 if (input == NULL)
pcercuei 0:03b5121a232e 15715 return (NULL);
pcercuei 0:03b5121a232e 15716 input->closecallback = NULL;
pcercuei 0:03b5121a232e 15717 stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
pcercuei 0:03b5121a232e 15718 if (stream == NULL) {
pcercuei 0:03b5121a232e 15719 xmlFreeParserInputBuffer(input);
pcercuei 0:03b5121a232e 15720 return (NULL);
pcercuei 0:03b5121a232e 15721 }
pcercuei 0:03b5121a232e 15722 inputPush(ctxt, stream);
pcercuei 0:03b5121a232e 15723 return (xmlDoRead(ctxt, URL, encoding, options, 1));
pcercuei 0:03b5121a232e 15724 }
pcercuei 0:03b5121a232e 15725
pcercuei 0:03b5121a232e 15726 /**
pcercuei 0:03b5121a232e 15727 * xmlCtxtReadIO:
pcercuei 0:03b5121a232e 15728 * @ctxt: an XML parser context
pcercuei 0:03b5121a232e 15729 * @ioread: an I/O read function
pcercuei 0:03b5121a232e 15730 * @ioclose: an I/O close function
pcercuei 0:03b5121a232e 15731 * @ioctx: an I/O handler
pcercuei 0:03b5121a232e 15732 * @URL: the base URL to use for the document
pcercuei 0:03b5121a232e 15733 * @encoding: the document encoding, or NULL
pcercuei 0:03b5121a232e 15734 * @options: a combination of xmlParserOption
pcercuei 0:03b5121a232e 15735 *
pcercuei 0:03b5121a232e 15736 * parse an XML document from I/O functions and source and build a tree.
pcercuei 0:03b5121a232e 15737 * This reuses the existing @ctxt parser context
pcercuei 0:03b5121a232e 15738 *
pcercuei 0:03b5121a232e 15739 * Returns the resulting document tree
pcercuei 0:03b5121a232e 15740 */
pcercuei 0:03b5121a232e 15741 xmlDocPtr
pcercuei 0:03b5121a232e 15742 xmlCtxtReadIO(xmlParserCtxtPtr ctxt, xmlInputReadCallback ioread,
pcercuei 0:03b5121a232e 15743 xmlInputCloseCallback ioclose, void *ioctx,
pcercuei 0:03b5121a232e 15744 const char *URL,
pcercuei 0:03b5121a232e 15745 const char *encoding, int options)
pcercuei 0:03b5121a232e 15746 {
pcercuei 0:03b5121a232e 15747 xmlParserInputBufferPtr input;
pcercuei 0:03b5121a232e 15748 xmlParserInputPtr stream;
pcercuei 0:03b5121a232e 15749
pcercuei 0:03b5121a232e 15750 if (ioread == NULL)
pcercuei 0:03b5121a232e 15751 return (NULL);
pcercuei 0:03b5121a232e 15752 if (ctxt == NULL)
pcercuei 0:03b5121a232e 15753 return (NULL);
pcercuei 0:03b5121a232e 15754 xmlInitParser();
pcercuei 0:03b5121a232e 15755
pcercuei 0:03b5121a232e 15756 xmlCtxtReset(ctxt);
pcercuei 0:03b5121a232e 15757
pcercuei 0:03b5121a232e 15758 input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
pcercuei 0:03b5121a232e 15759 XML_CHAR_ENCODING_NONE);
pcercuei 0:03b5121a232e 15760 if (input == NULL) {
pcercuei 0:03b5121a232e 15761 if (ioclose != NULL)
pcercuei 0:03b5121a232e 15762 ioclose(ioctx);
pcercuei 0:03b5121a232e 15763 return (NULL);
pcercuei 0:03b5121a232e 15764 }
pcercuei 0:03b5121a232e 15765 stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
pcercuei 0:03b5121a232e 15766 if (stream == NULL) {
pcercuei 0:03b5121a232e 15767 xmlFreeParserInputBuffer(input);
pcercuei 0:03b5121a232e 15768 return (NULL);
pcercuei 0:03b5121a232e 15769 }
pcercuei 0:03b5121a232e 15770 inputPush(ctxt, stream);
pcercuei 0:03b5121a232e 15771 return (xmlDoRead(ctxt, URL, encoding, options, 1));
pcercuei 0:03b5121a232e 15772 }
pcercuei 0:03b5121a232e 15773
pcercuei 0:03b5121a232e 15774 #define bottom_parser
pcercuei 0:03b5121a232e 15775 #include "elfgcchack.h"
pcercuei 0:03b5121a232e 15776