* NXT(n) returns the n'th next xmlChar. Same as CUR is should be used only
* to compare on ASCII based substring.
* SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
- * strings within the parser.
- *
+ * strings without newlines within the parser.
+ * NEXT1(l) Skip 1 xmlChar, and must also be used only to skip 1 non-newline ASCII
+ * defined char within the parser.
* Clean macros, not dependent of an ASCII context, expect UTF-8 encoding
*
* NEXT Skip to the next character, this does the proper decoding
* in UTF-8 mode. It also pop-up unfinished entities on the fly.
- * NEXTL(l) Skip l xmlChar in the input buffer
+ * NEXTL(l) Skip the current unicode character of l xmlChars long.
* CUR_CHAR(l) returns the current unicode character (int), set l
* to the number of xmlChars used for the encoding [0-5].
* CUR_SCHAR same but operate on a string instead of the context
#define CUR_PTR ctxt->input->cur
#define SKIP(val) do { \
- ctxt->nbChars += (val),ctxt->input->cur += (val); \
+ ctxt->nbChars += (val),ctxt->input->cur += (val),ctxt->input->col+=(val); \
if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt); \
if ((*ctxt->input->cur == 0) && \
(xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) \
xmlPopInput(ctxt); \
} while (0)
-#define SHRINK if (ctxt->input->cur - ctxt->input->base > INPUT_CHUNK) \
+#define SHRINK if ((ctxt->progressive == 0) && \
+ (ctxt->input->cur - ctxt->input->base > INPUT_CHUNK) && \
+ (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK)) \
xmlSHRINK (ctxt);
static void xmlSHRINK (xmlParserCtxtPtr ctxt) {
xmlPopInput(ctxt);
}
-#define GROW if (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK) \
+#define GROW if ((ctxt->progressive == 0) && \
+ (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK)) \
xmlGROW (ctxt);
static void xmlGROW (xmlParserCtxtPtr ctxt) {
if ((*ctxt->input->cur == 0) &&
(xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
xmlPopInput(ctxt);
- }
+}
#define SKIP_BLANKS xmlSkipBlankChars(ctxt)
#define NEXT xmlNextChar(ctxt)
#define NEXT1 { \
+ ctxt->input->col++; \
ctxt->input->cur++; \
ctxt->nbChars++; \
if (*ctxt->input->cur == 0) \
}
if (RAW == ';') {
/* on purpose to avoid reentrancy problems with NEXT and SKIP */
+ ctxt->input->col++;
ctxt->nbChars ++;
ctxt->input->cur++;
}
}
if (RAW == ';') {
/* on purpose to avoid reentrancy problems with NEXT and SKIP */
+ ctxt->input->col++;
ctxt->nbChars ++;
ctxt->input->cur++;
}
return(NULL);
}
length = xmlStrlen(entity->name) + 5;
- buffer = xmlMalloc(length);
+ buffer = xmlMallocAtomic(length);
if (buffer == NULL) {
return(NULL);
}
* allocate a translation buffer.
*/
buffer_size = XML_PARSER_BIG_BUFFER_SIZE;
- buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
+ buffer = (xmlChar *) xmlMallocAtomic(buffer_size * sizeof(xmlChar));
if (buffer == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlStringDecodeEntities: malloc failed");
xmlChar *ret;
if ((cur == NULL) || (len < 0)) return(NULL);
- ret = (xmlChar *) xmlMalloc((len + 1) * sizeof(xmlChar));
+ ret = (xmlChar *) xmlMallocAtomic((len + 1) * sizeof(xmlChar));
if (ret == NULL) {
xmlGenericError(xmlGenericErrorContext,
"malloc of %ld byte failed\n",
xmlChar *ret;
if ((cur == NULL) || (len < 0)) return(NULL);
- ret = (xmlChar *) xmlMalloc((len + 1) * sizeof(xmlChar));
+ ret = (xmlChar *) xmlMallocAtomic((len + 1) * sizeof(xmlChar));
if (ret == NULL) {
xmlGenericError(xmlGenericErrorContext, "malloc of %ld byte failed\n",
(len + 1) * (long)sizeof(xmlChar));
*prefix = NULL;
+ if (cur == NULL) return(NULL);
+
#ifndef XML_XML_NAMESPACE
/* xml: prefix is not really a namespace */
if ((cur[0] == 'x') && (cur[1] == 'm') &&
return(xmlStrdup(name));
#endif
- /* nasty but valid */
+ /* nasty but well=formed */
if (cur[0] == ':')
return(xmlStrdup(name));
*/
max = len * 2;
- buffer = (xmlChar *) xmlMalloc(max * sizeof(xmlChar));
+ buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
if (buffer == NULL) {
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
buffer[len] = 0;
}
+ /* nasty but well=formed
+ if ((c == ':') && (*cur == 0)) {
+ return(xmlStrdup(name));
+ } */
+
if (buffer == NULL)
ret = xmlStrndup(buf, len);
else {
if (c == ':') {
c = *cur;
- if (c == 0) return(ret);
*prefix = ret;
+ if (c == 0) {
+ return(xmlStrndup(BAD_CAST "", 0));
+ }
len = 0;
/*
*/
max = len * 2;
- buffer = (xmlChar *) xmlMalloc(max * sizeof(xmlChar));
+ buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
if (buffer == NULL) {
if ((ctxt != NULL) && (ctxt->sax != NULL) &&
(ctxt->sax->error != NULL))
count = in - ctxt->input->cur;
ret = xmlStrndup(ctxt->input->cur, count);
ctxt->input->cur = in;
+ ctxt->nbChars += count;
+ ctxt->input->col += count;
+ if (ret == NULL) {
+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
+ ctxt->sax->error(ctxt->userData,
+ "XML parser: out of memory\n");
+ ctxt->errNo = XML_ERR_NO_MEMORY;
+ ctxt->instate = XML_PARSER_EOF;
+ ctxt->disableSAX = 1;
+ }
return(ret);
}
}
xmlChar *buffer;
int max = len * 2;
- buffer = (xmlChar *) xmlMalloc(max * sizeof(xmlChar));
+ buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
if (buffer == NULL) {
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
xmlChar *buffer;
int max = len * 2;
- buffer = (xmlChar *) xmlMalloc(max * sizeof(xmlChar));
+ buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
if (buffer == NULL) {
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
xmlChar *buffer;
int max = len * 2;
- buffer = (xmlChar *) xmlMalloc(max * sizeof(xmlChar));
+ buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
if (buffer == NULL) {
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
if (ctxt->recovery == 0) ctxt->disableSAX = 1;
return(NULL);
}
- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
+ buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
if (buf == NULL) {
xmlGenericError(xmlGenericErrorContext,
"malloc of %d byte failed\n", size);
* allocate a translation buffer.
*/
buf_size = XML_PARSER_BUFFER_SIZE;
- buf = (xmlChar *) xmlMalloc(buf_size * sizeof(xmlChar));
+ buf = (xmlChar *) xmlMallocAtomic(buf_size * sizeof(xmlChar));
if (buf == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlParseAttValue: malloc failed");
return(NULL);
}
- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
+ buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
if (buf == NULL) {
xmlGenericError(xmlGenericErrorContext,
"malloc of %d byte failed\n", size);
if (ctxt->recovery == 0) ctxt->disableSAX = 1;
return(NULL);
}
- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
+ buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
if (buf == NULL) {
xmlGenericError(xmlGenericErrorContext,
"malloc of %d byte failed\n", size);
ctxt->instate = XML_PARSER_COMMENT;
SHRINK;
SKIP(4);
- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
+ buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
if (buf == NULL) {
xmlGenericError(xmlGenericErrorContext,
"malloc of %d byte failed\n", size);
xmlFree(target);
return;
}
- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
+ buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
if (buf == NULL) {
xmlGenericError(xmlGenericErrorContext,
"malloc of %d byte failed\n", size);
return(NULL);
}
cur = ret = xmlNewElementContent(elem, XML_ELEMENT_CONTENT_ELEMENT);
+ if (cur == NULL) {
+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
+ ctxt->sax->error(ctxt->userData,
+ "xmlParseElementChildrenContentDecl : out of memory\n");
+ ctxt->errNo = XML_ERR_NO_MEMORY;
+ if (ctxt->recovery == 0) ctxt->disableSAX = 1;
+ xmlFree(elem);
+ return(NULL);
+ }
GROW;
if (RAW == '?') {
cur->ocur = XML_ELEMENT_CONTENT_OPT;
while ((RAW != 0) && ((RAW != ']') || (NXT(1) != ']') ||
(NXT(2) != '>'))) {
const xmlChar *check = CUR_PTR;
- int cons = ctxt->input->consumed;
+ unsigned int cons = ctxt->input->consumed;
if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
xmlParseConditionalSections(ctxt);
} else if ((RAW == 'I') && (NXT(1) == 'G') && (NXT(2) == 'N') &&
(NXT(3) == 'O') && (NXT(4) == 'R') && (NXT(5) == 'E')) {
int state;
- int instate;
+ xmlParserInputState instate;
int depth = 0;
SKIP(6);
((RAW == '<') && (NXT(1) == '!')) ||
(RAW == '%') || IS_BLANK(CUR)) {
const xmlChar *check = CUR_PTR;
- int cons = ctxt->input->consumed;
+ unsigned int cons = ctxt->input->consumed;
GROW;
if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
* a simple tree copy for all references except the first
* In the first occurrence list contains the replacement
*/
- if (list == NULL) {
- xmlNodePtr new = NULL, cur, firstChild = NULL;
+ if ((list == NULL) && (ent->owner == 0)) {
+ xmlNodePtr nw = NULL, cur, firstChild = NULL;
cur = ent->children;
while (cur != NULL) {
- new = xmlCopyNode(cur, 1);
- if (new != NULL) {
- new->_private = cur->_private;
+ nw = xmlCopyNode(cur, 1);
+ if (nw != NULL) {
+ nw->_private = cur->_private;
if (firstChild == NULL){
- firstChild = new;
+ firstChild = nw;
}
- xmlAddChild(ctxt->node, new);
+ xmlAddChild(ctxt->node, nw);
}
if (cur == ent->last)
break;
cur = cur->next;
}
if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
- xmlAddEntityReference(ent, firstChild, new);
+ xmlAddEntityReference(ent, firstChild, nw);
+ } else if (list == NULL) {
+ xmlNodePtr nw = NULL, cur, next, last,
+ firstChild = NULL;
+ /*
+ * Copy the entity child list and make it the new
+ * entity child list. The goal is to make sure any
+ * ID or REF referenced will be the one from the
+ * document content and not the entity copy.
+ */
+ cur = ent->children;
+ ent->children = NULL;
+ last = ent->last;
+ ent->last = NULL;
+ while (cur != NULL) {
+ next = cur->next;
+ cur->next = NULL;
+ cur->parent = NULL;
+ nw = xmlCopyNode(cur, 1);
+ if (nw != NULL) {
+ nw->_private = cur->_private;
+ if (firstChild == NULL){
+ firstChild = cur;
+ }
+ xmlAddChild((xmlNodePtr) ent, nw);
+ xmlAddChild(ctxt->node, cur);
+ }
+ if (cur == last)
+ break;
+ cur = next;
+ }
+ ent->owner = 1;
+ if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
+ xmlAddEntityReference(ent, firstChild, nw);
} else {
/*
* the name change is to avoid coalescing of the
if (ctxt->sax != NULL) {
if (ctxt->sax->getEntity != NULL)
ent = ctxt->sax->getEntity(ctxt->userData, name);
- if (ent == NULL)
+ if ((ctxt->wellFormed == 1 ) && (ent == NULL))
ent = xmlGetPredefinedEntity(name);
- if ((ent == NULL) && (ctxt->userData==ctxt)) {
+ if ((ctxt->wellFormed == 1 ) && (ent == NULL) &&
+ (ctxt->userData==ctxt)) {
ent = getEntity(ctxt, name);
}
}
*/
while (RAW != ']') {
const xmlChar *check = CUR_PTR;
- int cons = ctxt->input->consumed;
+ unsigned int cons = ctxt->input->consumed;
SKIP_BLANKS;
xmlParseMarkupDecl(ctxt);
ctxt->errNo = XML_ERR_ATTRIBUTE_WITHOUT_VALUE;
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
-"Invalid value for xml:space : \"%s\", \"default\" or \"preserve\" expected\n",
+"Invalid value \"%s\" for xml:space : \"default\" or \"preserve\" expected\n",
val);
ctxt->wellFormed = 0;
if (ctxt->recovery == 0) ctxt->disableSAX = 1;
while ((RAW != '>') &&
((RAW != '/') || (NXT(1) != '>')) &&
- (IS_CHAR(RAW))) {
+ (IS_CHAR((unsigned int) RAW))) {
const xmlChar *q = CUR_PTR;
- int cons = ctxt->input->consumed;
+ unsigned int cons = ctxt->input->consumed;
attname = xmlParseAttribute(ctxt, &attvalue);
if ((attname != NULL) && (attvalue != NULL)) {
xmlGenericError(xmlGenericErrorContext,
"malloc of %ld byte failed\n",
maxatts * (long)sizeof(xmlChar *));
- return(NULL);
+ if (attname != NULL)
+ xmlFree(attname);
+ if (attvalue != NULL)
+ xmlFree(attvalue);
+ ctxt->errNo = XML_ERR_NO_MEMORY;
+ ctxt->instate = XML_PARSER_EOF;
+ ctxt->disableSAX = 1;
+ goto failed;
}
} else if (nbatts + 4 > maxatts) {
+ const xmlChar **n;
+
maxatts *= 2;
- atts = (const xmlChar **) xmlRealloc((void *) atts,
+ n = (const xmlChar **) xmlRealloc((void *) atts,
maxatts * sizeof(xmlChar *));
- if (atts == NULL) {
+ if (n == NULL) {
xmlGenericError(xmlGenericErrorContext,
"realloc of %ld byte failed\n",
maxatts * (long)sizeof(xmlChar *));
- return(NULL);
+ if (attname != NULL)
+ xmlFree(attname);
+ if (attvalue != NULL)
+ xmlFree(attvalue);
+ ctxt->errNo = XML_ERR_NO_MEMORY;
+ ctxt->instate = XML_PARSER_EOF;
+ ctxt->disableSAX = 1;
+ goto failed;
}
+ atts = n;
}
atts[nbatts++] = attname;
atts[nbatts++] = attvalue;
ctxt->sax->startElement(ctxt->userData, name, atts);
if (atts != NULL) {
- for (i = 0;i < nbatts;i++) xmlFree((xmlChar *) atts[i]);
+ for (i = 0;i < nbatts;i++)
+ if (atts[i] != NULL)
+ xmlFree((xmlChar *) atts[i]);
xmlFree((void *) atts);
}
return(name);
}
/**
- * xmlParseEndTag:
+ * xmlParseEndTagInternal:
* @ctxt: an XML parser context
*
* parse an end of tag
* [NS 9] ETag ::= '</' QName S? '>'
*/
-void
-xmlParseEndTag(xmlParserCtxtPtr ctxt) {
+static void
+xmlParseEndTagInternal(xmlParserCtxtPtr ctxt, int line) {
xmlChar *name;
xmlChar *oldname;
*/
GROW;
SKIP_BLANKS;
- if ((!IS_CHAR(RAW)) || (RAW != '>')) {
+ if ((!IS_CHAR((unsigned int) RAW)) || (RAW != '>')) {
ctxt->errNo = XML_ERR_GT_REQUIRED;
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData, "End tag : expected '>'\n");
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) {
if (name != NULL) {
ctxt->sax->error(ctxt->userData,
- "Opening and ending tag mismatch: %s and %s\n",
- ctxt->name, name);
+ "Opening and ending tag mismatch: %s line %d and %s\n",
+ ctxt->name, line, name);
} else {
ctxt->sax->error(ctxt->userData,
- "Ending tag error for: %s\n", ctxt->name);
+ "Ending tag error for: %s line %d\n", ctxt->name, line);
}
}
ctxt->wellFormed = 0;
if (ctxt->recovery == 0) ctxt->disableSAX = 1;
-#if 0
- else {
- /*
- * Recover in case of one missing close
- */
- if ((ctxt->nameNr > 2) &&
- (xmlStrEqual(ctxt->nameTab[ctxt->nameNr -2], name))) {
- namePop(ctxt);
- spacePop(ctxt);
- }
- }
-#endif
if (name != NULL)
xmlFree(name);
}
}
/**
+ * xmlParseEndTag:
+ * @ctxt: an XML parser context
+ *
+ * parse an end of tag
+ *
+ * [42] ETag ::= '</' Name S? '>'
+ *
+ * With namespace
+ *
+ * [NS 9] ETag ::= '</' QName S? '>'
+ */
+
+void
+xmlParseEndTag(xmlParserCtxtPtr ctxt) {
+ xmlParseEndTagInternal(ctxt, 0);
+}
+
+/**
* xmlParseCDSect:
* @ctxt: an XML parser context
*
}
NEXTL(sl);
cur = CUR_CHAR(l);
- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
+ buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
if (buf == NULL) {
xmlGenericError(xmlGenericErrorContext,
"malloc of %d byte failed\n", size);
while ((RAW != 0) &&
((RAW != '<') || (NXT(1) != '/'))) {
const xmlChar *test = CUR_PTR;
- int cons = ctxt->input->consumed;
+ unsigned int cons = ctxt->input->consumed;
const xmlChar *cur = ctxt->input->cur;
/*
xmlChar *name;
xmlChar *oldname;
xmlParserNodeInfo node_info;
+ int line;
xmlNodePtr ret;
/* Capture start position */
else
spacePush(ctxt, *ctxt->space);
+ line = ctxt->input->line;
name = xmlParseStartTag(ctxt);
if (name == NULL) {
spacePop(ctxt);
ctxt->errNo = XML_ERR_GT_REQUIRED;
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
- "Couldn't find end of Start Tag %s\n",
- name);
+ "Couldn't find end of Start Tag %s line %d\n",
+ name, line);
ctxt->wellFormed = 0;
if (ctxt->recovery == 0) ctxt->disableSAX = 1;
* Parse the content of the element:
*/
xmlParseContent(ctxt);
- if (!IS_CHAR(RAW)) {
+ if (!IS_CHAR((unsigned int) RAW)) {
ctxt->errNo = XML_ERR_TAG_NOT_FINISHED;
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
- "Premature end of data in tag %s\n", name);
+ "Premature end of data in tag %s line %d\n", name, line);
ctxt->wellFormed = 0;
if (ctxt->recovery == 0) ctxt->disableSAX = 1;
/*
* parse the end of tag: '</' should be here.
*/
- xmlParseEndTag(ctxt);
+ xmlParseEndTagInternal(ctxt, line);
/*
* Capture end position and add node
int size = 10;
xmlChar cur;
- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
+ buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
if (buf == NULL) {
xmlGenericError(xmlGenericErrorContext,
"malloc of %d byte failed\n", size);
cur = CUR;
if (((cur >= 'a') && (cur <= 'z')) ||
((cur >= 'A') && (cur <= 'Z'))) {
- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
+ buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
if (buf == NULL) {
xmlGenericError(xmlGenericErrorContext,
"malloc of %d byte failed\n", size);
* Returns the encoding value or NULL
*/
-xmlChar *
+const xmlChar *
xmlParseEncodingDecl(xmlParserCtxtPtr ctxt) {
xmlChar *encoding = NULL;
const xmlChar *q;
ctxt->wellFormed = 0;
if (ctxt->recovery == 0) ctxt->disableSAX = 1;
}
- if (encoding != NULL) {
- xmlCharEncoding enc;
+ /*
+ * UTF-16 encoding stwich has already taken place at this stage,
+ * more over the little-endian/big-endian selection is already done
+ */
+ if ((encoding != NULL) &&
+ ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-16")) ||
+ (!xmlStrcasecmp(encoding, BAD_CAST "UTF16")))) {
+ if (ctxt->encoding != NULL)
+ xmlFree((xmlChar *) ctxt->encoding);
+ ctxt->encoding = encoding;
+ }
+ /*
+ * UTF-8 encoding is handled natively
+ */
+ else if ((encoding != NULL) &&
+ ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-8")) ||
+ (!xmlStrcasecmp(encoding, BAD_CAST "UTF8")))) {
+ if (ctxt->encoding != NULL)
+ xmlFree((xmlChar *) ctxt->encoding);
+ ctxt->encoding = encoding;
+ }
+ else if (encoding != NULL) {
xmlCharEncodingHandlerPtr handler;
if (ctxt->input->encoding != NULL)
xmlFree((xmlChar *) ctxt->input->encoding);
ctxt->input->encoding = encoding;
- enc = xmlParseCharEncoding((const char *) encoding);
- /*
- * registered set of known encodings
- */
- if (enc != XML_CHAR_ENCODING_ERROR) {
- xmlSwitchEncoding(ctxt, enc);
- if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
- ctxt->input->encoding = NULL;
- xmlFree(encoding);
- return(NULL);
- }
+ handler = xmlFindCharEncodingHandler((const char *) encoding);
+ if (handler != NULL) {
+ xmlSwitchToEncoding(ctxt, handler);
} else {
- /*
- * fallback for unknown encodings
- */
- handler = xmlFindCharEncodingHandler((const char *) encoding);
- if (handler != NULL) {
- xmlSwitchToEncoding(ctxt, handler);
- } else {
- ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Unsupported encoding %s\n", encoding);
- return(NULL);
- }
+ ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
+ ctxt->sax->error(ctxt->userData,
+ "Unsupported encoding %s\n", encoding);
+ return(NULL);
}
}
}
}
/**
+ * xmlParseGetLasts:
+ * @ctxt: an XML parser context
+ * @lastlt: pointer to store the last '<' from the input
+ * @lastgt: pointer to store the last '>' from the input
+ *
+ * Lookup the last < and > in the current chunk
+ */
+static void
+xmlParseGetLasts(xmlParserCtxtPtr ctxt, const xmlChar **lastlt,
+ const xmlChar **lastgt) {
+ const xmlChar *tmp;
+
+ if ((ctxt == NULL) || (lastlt == NULL) || (lastgt == NULL)) {
+ xmlGenericError(xmlGenericErrorContext,
+ "Internal error: xmlParseGetLasts\n");
+ return;
+ }
+ if ((ctxt->progressive == 1) && (ctxt->inputNr == 1)) {
+ tmp = ctxt->input->end;
+ tmp--;
+ while ((tmp >= ctxt->input->base) && (*tmp != '<') &&
+ (*tmp != '>')) tmp--;
+ if (tmp < ctxt->input->base) {
+ *lastlt = NULL;
+ *lastgt = NULL;
+ } else if (*tmp == '<') {
+ *lastlt = tmp;
+ tmp--;
+ while ((tmp >= ctxt->input->base) && (*tmp != '>')) tmp--;
+ if (tmp < ctxt->input->base)
+ *lastgt = NULL;
+ else
+ *lastgt = tmp;
+ } else {
+ *lastgt = tmp;
+ tmp--;
+ while ((tmp >= ctxt->input->base) && (*tmp != '<')) tmp--;
+ if (tmp < ctxt->input->base)
+ *lastlt = NULL;
+ else
+ *lastlt = tmp;
+ }
+
+ } else {
+ *lastlt = NULL;
+ *lastgt = NULL;
+ }
+}
+/**
* xmlParseTryOrFinish:
* @ctxt: an XML parser context
* @terminate: last chunk indicator
int ret = 0;
int avail;
xmlChar cur, next;
+ const xmlChar *lastlt, *lastgt;
#ifdef DEBUG_PUSH
switch (ctxt->instate) {
}
#endif
+ if (ctxt->input->cur - ctxt->input->base > 4096) {
+ xmlSHRINK(ctxt);
+ ctxt->checkIndex = 0;
+ }
+ xmlParseGetLasts(ctxt, &lastlt, &lastgt);
+
while (1) {
- SHRINK;
+ if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
+ return(0);
+
/*
* Pop-up of finished entities.
*/
if (ctxt->input ==NULL) break;
if (ctxt->input->buf == NULL)
- avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
+ avail = ctxt->input->length -
+ (ctxt->input->cur - ctxt->input->base);
else {
/*
* If we are operating on converted input, try to flush
#endif
}
break;
- case XML_PARSER_MISC:
- SKIP_BLANKS;
- if (ctxt->input->buf == NULL)
- avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
- else
- avail = ctxt->input->buf->buffer->use - (ctxt->input->cur - ctxt->input->base);
- if (avail < 2)
- goto done;
- cur = ctxt->input->cur[0];
- next = ctxt->input->cur[1];
- if ((cur == '<') && (next == '?')) {
- if ((!terminate) &&
- (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
- goto done;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: Parsing PI\n");
-#endif
- xmlParsePI(ctxt);
- } else if ((cur == '<') && (next == '!') &&
- (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
- if ((!terminate) &&
- (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
- goto done;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: Parsing Comment\n");
-#endif
- xmlParseComment(ctxt);
- ctxt->instate = XML_PARSER_MISC;
- } else if ((cur == '<') && (next == '!') &&
- (ctxt->input->cur[2] == 'D') && (ctxt->input->cur[3] == 'O') &&
- (ctxt->input->cur[4] == 'C') && (ctxt->input->cur[5] == 'T') &&
- (ctxt->input->cur[6] == 'Y') && (ctxt->input->cur[7] == 'P') &&
- (ctxt->input->cur[8] == 'E')) {
- if ((!terminate) &&
- (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
- goto done;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: Parsing internal subset\n");
-#endif
- ctxt->inSubset = 1;
- xmlParseDocTypeDecl(ctxt);
- if (RAW == '[') {
- ctxt->instate = XML_PARSER_DTD;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering DTD\n");
-#endif
- } else {
- /*
- * Create and update the external subset.
- */
- ctxt->inSubset = 2;
- if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
- (ctxt->sax->externalSubset != NULL))
- ctxt->sax->externalSubset(ctxt->userData,
- ctxt->intSubName, ctxt->extSubSystem,
- ctxt->extSubURI);
- ctxt->inSubset = 0;
- ctxt->instate = XML_PARSER_PROLOG;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering PROLOG\n");
-#endif
- }
- } else if ((cur == '<') && (next == '!') &&
- (avail < 9)) {
- goto done;
- } else {
- ctxt->instate = XML_PARSER_START_TAG;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering START_TAG\n");
-#endif
- }
- break;
- case XML_PARSER_IGNORE:
- xmlGenericError(xmlGenericErrorContext,
- "PP: internal error, state == IGNORE");
- ctxt->instate = XML_PARSER_DTD;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering DTD\n");
-#endif
- break;
- case XML_PARSER_PROLOG:
- SKIP_BLANKS;
- if (ctxt->input->buf == NULL)
- avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
- else
- avail = ctxt->input->buf->buffer->use - (ctxt->input->cur - ctxt->input->base);
- if (avail < 2)
- goto done;
- cur = ctxt->input->cur[0];
- next = ctxt->input->cur[1];
- if ((cur == '<') && (next == '?')) {
- if ((!terminate) &&
- (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
- goto done;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: Parsing PI\n");
-#endif
- xmlParsePI(ctxt);
- } else if ((cur == '<') && (next == '!') &&
- (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
- if ((!terminate) &&
- (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
- goto done;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: Parsing Comment\n");
-#endif
- xmlParseComment(ctxt);
- ctxt->instate = XML_PARSER_PROLOG;
- } else if ((cur == '<') && (next == '!') &&
- (avail < 4)) {
- goto done;
- } else {
- ctxt->instate = XML_PARSER_START_TAG;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering START_TAG\n");
-#endif
- }
- break;
- case XML_PARSER_EPILOG:
- SKIP_BLANKS;
- if (ctxt->input->buf == NULL)
- avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
- else
- avail = ctxt->input->buf->buffer->use - (ctxt->input->cur - ctxt->input->base);
- if (avail < 2)
- goto done;
- cur = ctxt->input->cur[0];
- next = ctxt->input->cur[1];
- if ((cur == '<') && (next == '?')) {
- if ((!terminate) &&
- (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
- goto done;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: Parsing PI\n");
-#endif
- xmlParsePI(ctxt);
- ctxt->instate = XML_PARSER_EPILOG;
- } else if ((cur == '<') && (next == '!') &&
- (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
- if ((!terminate) &&
- (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
- goto done;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: Parsing Comment\n");
-#endif
- xmlParseComment(ctxt);
- ctxt->instate = XML_PARSER_EPILOG;
- } else if ((cur == '<') && (next == '!') &&
- (avail < 4)) {
- goto done;
- } else {
- ctxt->errNo = XML_ERR_DOCUMENT_END;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Extra content at the end of the document\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- ctxt->instate = XML_PARSER_EOF;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering EOF\n");
-#endif
- if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
- ctxt->sax->endDocument(ctxt->userData);
- goto done;
- }
- break;
case XML_PARSER_START_TAG: {
xmlChar *name, *oldname;
ctxt->sax->endDocument(ctxt->userData);
goto done;
}
- if ((!terminate) &&
- (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
- goto done;
+ if (!terminate) {
+ if (ctxt->progressive) {
+ if ((lastgt == NULL) || (ctxt->input->cur > lastgt))
+ goto done;
+ } else if (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0) {
+ goto done;
+ }
+ }
if (ctxt->spaceNr == 0)
spacePush(ctxt, -1);
else
ctxt->sax->endDocument(ctxt->userData);
goto done;
}
- namePush(ctxt, xmlStrdup(name));
+ namePush(ctxt, name);
/*
* [ VC: Root Element Type ]
if ((ctxt->sax != NULL) &&
(ctxt->sax->endElement != NULL) && (!ctxt->disableSAX))
ctxt->sax->endElement(ctxt->userData, name);
- xmlFree(name);
oldname = namePop(ctxt);
spacePop(ctxt);
if (oldname != NULL) {
xmlFree(oldname);
}
}
- xmlFree(name);
ctxt->instate = XML_PARSER_CONTENT;
#ifdef DEBUG_PUSH
xmlGenericError(xmlGenericErrorContext,
}
case XML_PARSER_CONTENT: {
const xmlChar *test;
- int cons;
+ unsigned int cons;
if ((avail < 2) && (ctxt->inputNr == 1))
goto done;
cur = ctxt->input->cur[0];
test = CUR_PTR;
cons = ctxt->input->consumed;
- if ((cur == '<') && (next == '?')) {
+ if ((cur == '<') && (next == '/')) {
+ ctxt->instate = XML_PARSER_END_TAG;
+#ifdef DEBUG_PUSH
+ xmlGenericError(xmlGenericErrorContext,
+ "PP: entering END_TAG\n");
+#endif
+ break;
+ } else if ((cur == '<') && (next == '?')) {
if ((!terminate) &&
(xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
goto done;
"PP: Parsing PI\n");
#endif
xmlParsePI(ctxt);
+ } else if ((cur == '<') && (next != '!')) {
+ ctxt->instate = XML_PARSER_START_TAG;
+#ifdef DEBUG_PUSH
+ xmlGenericError(xmlGenericErrorContext,
+ "PP: entering START_TAG\n");
+#endif
+ break;
} else if ((cur == '<') && (next == '!') &&
- (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
+ (ctxt->input->cur[2] == '-') &&
+ (ctxt->input->cur[3] == '-')) {
if ((!terminate) &&
(xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
goto done;
xmlParseComment(ctxt);
ctxt->instate = XML_PARSER_CONTENT;
} else if ((cur == '<') && (ctxt->input->cur[1] == '!') &&
- (ctxt->input->cur[2] == '[') && (NXT(3) == 'C') &&
- (ctxt->input->cur[4] == 'D') && (NXT(5) == 'A') &&
- (ctxt->input->cur[6] == 'T') && (NXT(7) == 'A') &&
+ (ctxt->input->cur[2] == '[') &&
+ (ctxt->input->cur[3] == 'C') &&
+ (ctxt->input->cur[4] == 'D') &&
+ (ctxt->input->cur[5] == 'A') &&
+ (ctxt->input->cur[6] == 'T') &&
+ (ctxt->input->cur[7] == 'A') &&
(ctxt->input->cur[8] == '[')) {
SKIP(9);
ctxt->instate = XML_PARSER_CDATA_SECTION;
} else if ((cur == '<') && (next == '!') &&
(avail < 9)) {
goto done;
- } else if ((cur == '<') && (next == '/')) {
- ctxt->instate = XML_PARSER_END_TAG;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering END_TAG\n");
-#endif
- break;
- } else if (cur == '<') {
- ctxt->instate = XML_PARSER_START_TAG;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering START_TAG\n");
-#endif
- break;
} else if (cur == '&') {
if ((!terminate) &&
(xmlParseLookupSequence(ctxt, ';', 0, 0) < 0))
*/
if ((ctxt->inputNr == 1) &&
(avail < XML_PARSER_BIG_BUFFER_SIZE)) {
- if ((!terminate) &&
- (xmlParseLookupSequence(ctxt, '<', 0, 0) < 0))
- goto done;
+ if (!terminate) {
+ if (ctxt->progressive) {
+ if ((lastlt == NULL) ||
+ (ctxt->input->cur > lastlt))
+ goto done;
+ } else if (xmlParseLookupSequence(ctxt,
+ '<', 0, 0) < 0) {
+ goto done;
+ }
+ }
}
ctxt->checkIndex = 0;
#ifdef DEBUG_PUSH
}
break;
}
+ case XML_PARSER_END_TAG:
+ if (avail < 2)
+ goto done;
+ if (!terminate) {
+ if (ctxt->progressive) {
+ if ((lastgt == NULL) || (ctxt->input->cur > lastgt))
+ goto done;
+ } else if (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0) {
+ goto done;
+ }
+ }
+ xmlParseEndTag(ctxt);
+ if (ctxt->name == NULL) {
+ ctxt->instate = XML_PARSER_EPILOG;
+#ifdef DEBUG_PUSH
+ xmlGenericError(xmlGenericErrorContext,
+ "PP: entering EPILOG\n");
+#endif
+ } else {
+ ctxt->instate = XML_PARSER_CONTENT;
+#ifdef DEBUG_PUSH
+ xmlGenericError(xmlGenericErrorContext,
+ "PP: entering CONTENT\n");
+#endif
+ }
+ break;
case XML_PARSER_CDATA_SECTION: {
/*
* The Push mode need to have the SAX callback for
if (avail >= XML_PARSER_BIG_BUFFER_SIZE + 2) {
if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
if (ctxt->sax->cdataBlock != NULL)
- ctxt->sax->cdataBlock(ctxt->userData, ctxt->input->cur,
+ ctxt->sax->cdataBlock(ctxt->userData,
+ ctxt->input->cur,
+ XML_PARSER_BIG_BUFFER_SIZE);
+ else if (ctxt->sax->characters != NULL)
+ ctxt->sax->characters(ctxt->userData,
+ ctxt->input->cur,
XML_PARSER_BIG_BUFFER_SIZE);
}
SKIP(XML_PARSER_BIG_BUFFER_SIZE);
if (ctxt->sax->cdataBlock != NULL)
ctxt->sax->cdataBlock(ctxt->userData,
ctxt->input->cur, base);
+ else if (ctxt->sax->characters != NULL)
+ ctxt->sax->characters(ctxt->userData,
+ ctxt->input->cur, base);
}
SKIP(base + 3);
ctxt->checkIndex = 0;
}
break;
}
- case XML_PARSER_END_TAG:
+ case XML_PARSER_MISC:
+ SKIP_BLANKS;
+ if (ctxt->input->buf == NULL)
+ avail = ctxt->input->length -
+ (ctxt->input->cur - ctxt->input->base);
+ else
+ avail = ctxt->input->buf->buffer->use -
+ (ctxt->input->cur - ctxt->input->base);
if (avail < 2)
goto done;
- if ((!terminate) &&
- (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
+ cur = ctxt->input->cur[0];
+ next = ctxt->input->cur[1];
+ if ((cur == '<') && (next == '?')) {
+ if ((!terminate) &&
+ (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
+ goto done;
+#ifdef DEBUG_PUSH
+ xmlGenericError(xmlGenericErrorContext,
+ "PP: Parsing PI\n");
+#endif
+ xmlParsePI(ctxt);
+ } else if ((cur == '<') && (next == '!') &&
+ (ctxt->input->cur[2] == '-') &&
+ (ctxt->input->cur[3] == '-')) {
+ if ((!terminate) &&
+ (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
+ goto done;
+#ifdef DEBUG_PUSH
+ xmlGenericError(xmlGenericErrorContext,
+ "PP: Parsing Comment\n");
+#endif
+ xmlParseComment(ctxt);
+ ctxt->instate = XML_PARSER_MISC;
+ } else if ((cur == '<') && (next == '!') &&
+ (ctxt->input->cur[2] == 'D') &&
+ (ctxt->input->cur[3] == 'O') &&
+ (ctxt->input->cur[4] == 'C') &&
+ (ctxt->input->cur[5] == 'T') &&
+ (ctxt->input->cur[6] == 'Y') &&
+ (ctxt->input->cur[7] == 'P') &&
+ (ctxt->input->cur[8] == 'E')) {
+ if ((!terminate) &&
+ (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
+ goto done;
+#ifdef DEBUG_PUSH
+ xmlGenericError(xmlGenericErrorContext,
+ "PP: Parsing internal subset\n");
+#endif
+ ctxt->inSubset = 1;
+ xmlParseDocTypeDecl(ctxt);
+ if (RAW == '[') {
+ ctxt->instate = XML_PARSER_DTD;
+#ifdef DEBUG_PUSH
+ xmlGenericError(xmlGenericErrorContext,
+ "PP: entering DTD\n");
+#endif
+ } else {
+ /*
+ * Create and update the external subset.
+ */
+ ctxt->inSubset = 2;
+ if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
+ (ctxt->sax->externalSubset != NULL))
+ ctxt->sax->externalSubset(ctxt->userData,
+ ctxt->intSubName, ctxt->extSubSystem,
+ ctxt->extSubURI);
+ ctxt->inSubset = 0;
+ ctxt->instate = XML_PARSER_PROLOG;
+#ifdef DEBUG_PUSH
+ xmlGenericError(xmlGenericErrorContext,
+ "PP: entering PROLOG\n");
+#endif
+ }
+ } else if ((cur == '<') && (next == '!') &&
+ (avail < 9)) {
goto done;
- xmlParseEndTag(ctxt);
- if (ctxt->name == NULL) {
+ } else {
+ ctxt->instate = XML_PARSER_START_TAG;
+ ctxt->progressive = 1;
+ xmlParseGetLasts(ctxt, &lastlt, &lastgt);
+#ifdef DEBUG_PUSH
+ xmlGenericError(xmlGenericErrorContext,
+ "PP: entering START_TAG\n");
+#endif
+ }
+ break;
+ case XML_PARSER_PROLOG:
+ SKIP_BLANKS;
+ if (ctxt->input->buf == NULL)
+ avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
+ else
+ avail = ctxt->input->buf->buffer->use - (ctxt->input->cur - ctxt->input->base);
+ if (avail < 2)
+ goto done;
+ cur = ctxt->input->cur[0];
+ next = ctxt->input->cur[1];
+ if ((cur == '<') && (next == '?')) {
+ if ((!terminate) &&
+ (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
+ goto done;
+#ifdef DEBUG_PUSH
+ xmlGenericError(xmlGenericErrorContext,
+ "PP: Parsing PI\n");
+#endif
+ xmlParsePI(ctxt);
+ } else if ((cur == '<') && (next == '!') &&
+ (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
+ if ((!terminate) &&
+ (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
+ goto done;
+#ifdef DEBUG_PUSH
+ xmlGenericError(xmlGenericErrorContext,
+ "PP: Parsing Comment\n");
+#endif
+ xmlParseComment(ctxt);
+ ctxt->instate = XML_PARSER_PROLOG;
+ } else if ((cur == '<') && (next == '!') &&
+ (avail < 4)) {
+ goto done;
+ } else {
+ ctxt->instate = XML_PARSER_START_TAG;
+ ctxt->progressive = 1;
+ xmlParseGetLasts(ctxt, &lastlt, &lastgt);
+#ifdef DEBUG_PUSH
+ xmlGenericError(xmlGenericErrorContext,
+ "PP: entering START_TAG\n");
+#endif
+ }
+ break;
+ case XML_PARSER_EPILOG:
+ SKIP_BLANKS;
+ if (ctxt->input->buf == NULL)
+ avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
+ else
+ avail = ctxt->input->buf->buffer->use - (ctxt->input->cur - ctxt->input->base);
+ if (avail < 2)
+ goto done;
+ cur = ctxt->input->cur[0];
+ next = ctxt->input->cur[1];
+ if ((cur == '<') && (next == '?')) {
+ if ((!terminate) &&
+ (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
+ goto done;
+#ifdef DEBUG_PUSH
+ xmlGenericError(xmlGenericErrorContext,
+ "PP: Parsing PI\n");
+#endif
+ xmlParsePI(ctxt);
ctxt->instate = XML_PARSER_EPILOG;
+ } else if ((cur == '<') && (next == '!') &&
+ (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
+ if ((!terminate) &&
+ (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
+ goto done;
#ifdef DEBUG_PUSH
xmlGenericError(xmlGenericErrorContext,
- "PP: entering EPILOG\n");
+ "PP: Parsing Comment\n");
#endif
+ xmlParseComment(ctxt);
+ ctxt->instate = XML_PARSER_EPILOG;
+ } else if ((cur == '<') && (next == '!') &&
+ (avail < 4)) {
+ goto done;
} else {
- ctxt->instate = XML_PARSER_CONTENT;
+ ctxt->errNo = XML_ERR_DOCUMENT_END;
+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
+ ctxt->sax->error(ctxt->userData,
+ "Extra content at the end of the document\n");
+ ctxt->wellFormed = 0;
+ if (ctxt->recovery == 0) ctxt->disableSAX = 1;
+ ctxt->instate = XML_PARSER_EOF;
#ifdef DEBUG_PUSH
xmlGenericError(xmlGenericErrorContext,
- "PP: entering CONTENT\n");
+ "PP: entering EOF\n");
#endif
+ if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
+ ctxt->sax->endDocument(ctxt->userData);
+ goto done;
}
break;
case XML_PARSER_DTD: {
"PP: entering CONTENT\n");
#endif
break;
+ case XML_PARSER_IGNORE:
+ xmlGenericError(xmlGenericErrorContext,
+ "PP: internal error, state == IGNORE");
+ ctxt->instate = XML_PARSER_DTD;
+#ifdef DEBUG_PUSH
+ xmlGenericError(xmlGenericErrorContext,
+ "PP: entering DTD\n");
+#endif
+ break;
case XML_PARSER_PI:
xmlGenericError(xmlGenericErrorContext,
"PP: internal error, state == PI\n");
int
xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
int terminate) {
+ if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
+ return(ctxt->errNo);
if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
(ctxt->input->buf != NULL) && (ctxt->instate != XML_PARSER_EOF)) {
int base = ctxt->input->base - ctxt->input->buf->buffer->content;
xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
#endif
+#if 0
if ((terminate) || (ctxt->input->buf->buffer->use > 80))
xmlParseTryOrFinish(ctxt, terminate);
+#endif
} else if (ctxt->instate != XML_PARSER_EOF) {
if ((ctxt->input != NULL) && ctxt->input->buf != NULL) {
xmlParserInputBufferPtr in = ctxt->input->buf;
}
}
xmlParseTryOrFinish(ctxt, terminate);
+ if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
+ return(ctxt->errNo);
if (terminate) {
/*
* Check for termination
ctxt = xmlNewParserCtxt();
if (ctxt == NULL) {
- xmlFree(buf);
+ xmlGenericError(xmlGenericErrorContext,
+ "xml parser: out of memory\n");
+ xmlFreeParserInputBuffer(buf);
return(NULL);
}
if (sax != NULL) {
xmlFree(ctxt->sax);
ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
if (ctxt->sax == NULL) {
- xmlFree(buf);
- xmlFree(ctxt);
+ xmlGenericError(xmlGenericErrorContext,
+ "xml parser: out of memory\n");
+ xmlFreeParserInputBuffer(buf);
+ xmlFreeParserCtxt(ctxt);
return(NULL);
}
memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
inputStream = xmlNewInputStream(ctxt);
if (inputStream == NULL) {
xmlFreeParserCtxt(ctxt);
+ xmlFreeParserInputBuffer(buf);
return(NULL);
}
if (ctxt->wellFormed) {
ret = ctxt->myDoc->extSubset;
ctxt->myDoc->extSubset = NULL;
+ if (ret != NULL) {
+ xmlNodePtr tmp;
+
+ ret->doc = NULL;
+ tmp = ret->children;
+ while (tmp != NULL) {
+ tmp->doc = NULL;
+ tmp = tmp->next;
+ }
+ }
} else {
ret = NULL;
}
if (ctxt->sax != NULL)
xmlFree(ctxt->sax);
ctxt->sax = sax;
- ctxt->userData = NULL;
+ ctxt->userData = ctxt;
}
/*
*/
if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
- input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID, SystemID);
+ input = ctxt->sax->resolveEntity(ctxt, ExternalID, SystemID);
if (input == NULL) {
if (sax != NULL) ctxt->sax = NULL;
xmlFreeParserCtxt(ctxt);
xmlSwitchEncoding(ctxt, enc);
if (input->filename == NULL)
- input->filename = (char *) xmlStrdup(SystemID);
+ input->filename = (char *) xmlCanonicPath(SystemID);
input->line = 1;
input->col = 1;
input->base = ctxt->input->cur;
if (ctxt->wellFormed) {
ret = ctxt->myDoc->extSubset;
ctxt->myDoc->extSubset = NULL;
+ if (ret != NULL) {
+ xmlNodePtr tmp;
+
+ ret->doc = NULL;
+ tmp = ret->children;
+ while (tmp != NULL) {
+ tmp->doc = NULL;
+ tmp = tmp->next;
+ }
+ }
} else {
ret = NULL;
}
*/
ctxt->instate = XML_PARSER_CONTENT;
ctxt->validate = ctx->validate;
+ ctxt->valid = ctx->valid;
ctxt->loadsubset = ctx->loadsubset;
ctxt->depth = ctx->depth + 1;
ctxt->replaceEntities = ctx->replaceEntities;
xmlParseContent(ctxt);
+ ctx->validate = ctxt->validate;
+ ctx->valid = ctxt->valid;
if ((RAW == '<') && (NXT(1) == '/')) {
ctxt->errNo = XML_ERR_NOT_WELL_BALANCED;
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->validate = 0;
ctxt->loadsubset = oldctxt->loadsubset;
+ if ((oldctxt->validate) || (oldctxt->replaceEntities != 0)) {
+ /*
+ * ID/IDREF registration will be done in xmlValidateElement below
+ */
+ ctxt->loadsubset |= XML_SKIP_IDS;
+ }
xmlParseContent(ctxt);
if ((RAW == '<') && (NXT(1) == '/')) {
xmlSAXParseEntity(xmlSAXHandlerPtr sax, const char *filename) {
xmlDocPtr ret;
xmlParserCtxtPtr ctxt;
- char *directory = NULL;
ctxt = xmlCreateFileParserCtxt(filename);
if (ctxt == NULL) {
ctxt->userData = NULL;
}
- if ((ctxt->directory == NULL) && (directory == NULL))
- directory = xmlParserGetDirectory(filename);
-
xmlParseExtParsedEnt(ctxt);
if (ctxt->wellFormed)
{
xmlParserCtxtPtr ctxt;
xmlParserInputPtr inputStream;
- char *canonicFilename;
char *directory = NULL;
ctxt = xmlNewParserCtxt();
return(NULL);
}
- canonicFilename = (char *) xmlCanonicPath((const xmlChar *) filename);
- if (canonicFilename == NULL) {
- if (xmlDefaultSAXHandler.error != NULL) {
- xmlDefaultSAXHandler.error(NULL, "out of memory\n");
- }
- return(NULL);
- }
- inputStream = xmlLoadExternalEntity(canonicFilename, NULL, ctxt);
- xmlFree(canonicFilename);
+ inputStream = xmlLoadExternalEntity(filename, NULL, ctxt);
if (inputStream == NULL) {
xmlFreeParserCtxt(ctxt);
return(NULL);
xmlClearParserCtxt(ctxt);
if (filename != NULL)
- input->filename = xmlMemStrdup(filename);
+ input->filename = (char *) xmlCanonicPath((const xmlChar *)filename);
input->base = buffer;
input->cur = buffer;
input->end = &buffer[xmlStrlen(buffer)];
ctxt->_private=data;
}
+ ctxt->recovery = recovery;
+
xmlParseDocument(ctxt);
if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
if ((xmlGenericError == xmlGenericErrorDefaultFunc) ||
(xmlGenericError == NULL))
initGenericErrorDefaultFunc(NULL);
+ xmlInitGlobals();
xmlInitThreads();
xmlInitMemory();
xmlInitCharEncodingHandlers();
xmlCatalogCleanup();
#endif
xmlCleanupThreads();
+ xmlCleanupGlobals();
xmlParserInitialized = 0;
}