applied patch from Richard Jinks for the namespace axis + fixed a memory

* xpath.c: applied patch from Richard Jinks for the namespace
  axis + fixed a memory error.
* parser.c parserInternals.c: applied patches from Peter Jacobi
  removing ctxt->token for good.
* xmlschemas.c xmlschemastypes.c: fixed a few memory leaks
  popped out by the regression tests.
* Makefile.am: patch for threads makefile from Gary Pennington
Daniel
This commit is contained in:
Daniel Veillard 2002-07-01 21:52:03 +00:00
parent 692092b588
commit fdc9156a75
10 changed files with 216 additions and 393 deletions

View File

@ -1,6 +1,16 @@
Mon Jul 1 23:23:41 CEST 2002 Daniel Veillard <daniel@veillard.com>
* xpath.c: applied patch from Richard Jinks for the namespace
axis + fixed a memory error.
* parser.c parserInternals.c: applied patches from Peter Jacobi
removing ctxt->token for good.
* xmlschemas.c xmlschemastypes.c: fixed a few memory leaks
popped out by the regression tests.
* Makefile.am: patch for threads makefile from Gary Pennington
Fri Jun 28 19:38:00 HKT 2002 William Brack <wbrack@mmm.com.hk>
* xpath.c enhanced behaviour of position() after usage of
* xpath.c: enhanced behaviour of position() after usage of
expressions involving preceding-sibling (et al).
Tue Jun 18 09:58:48 CEST 2002 Daniel Veillard <daniel@veillard.com>

View File

@ -13,7 +13,7 @@ bin_PROGRAMS = xmllint xmlcatalog
bin_SCRIPTS=xml2-config
lib_LTLIBRARIES = libxml2.la
libxml2_la_LIBADD = @Z_LIBS@ $(ICONV_LIBS) -lm
libxml2_la_LIBADD = @THREAD_LIBS@ @Z_LIBS@ $(ICONV_LIBS) -lm
libxml2_la_LDFLAGS = -version-info @LIBXML_VERSION_INFO@

129
hash.c
View File

@ -42,13 +42,14 @@ struct _xmlHashEntry {
xmlChar *name2;
xmlChar *name3;
void *payload;
int valid;
};
/*
* The entire hash table
*/
struct _xmlHashTable {
struct _xmlHashEntry **table;
struct _xmlHashEntry *table;
int size;
int nbElems;
};
@ -101,9 +102,9 @@ xmlHashCreate(int size) {
if (table) {
table->size = size;
table->nbElems = 0;
table->table = xmlMalloc(size * sizeof(xmlHashEntryPtr));
table->table = xmlMalloc(size * sizeof(xmlHashEntry));
if (table->table) {
memset(table->table, 0, size * sizeof(xmlHashEntryPtr));
memset(table->table, 0, size * sizeof(xmlHashEntry));
return(table);
}
xmlFree(table);
@ -125,7 +126,7 @@ xmlHashGrow(xmlHashTablePtr table, int size) {
unsigned long key;
int oldsize, i;
xmlHashEntryPtr iter, next;
struct _xmlHashEntry **oldtable;
struct _xmlHashEntry *oldtable;
#ifdef DEBUG_GROW
unsigned long nbElem = 0;
#endif
@ -142,16 +143,31 @@ xmlHashGrow(xmlHashTablePtr table, int size) {
if (oldtable == NULL)
return(-1);
table->table = xmlMalloc(size * sizeof(xmlHashEntryPtr));
table->table = xmlMalloc(size * sizeof(xmlHashEntry));
if (table->table == NULL) {
table->table = oldtable;
return(-1);
}
memset(table->table, 0, size * sizeof(xmlHashEntryPtr));
memset(table->table, 0, size * sizeof(xmlHashEntry));
table->size = size;
/* If the two loops are merged, there would be situations where
a new entry needs to allocated and data copied into it from
the main table. So instead, we run through the array twice, first
copying all the elements in the main array (where we can't get
conflicts) and then the rest, so we only free (and don't allocate)
*/
for (i = 0; i < oldsize; i++) {
iter = oldtable[i];
if (oldtable[i].valid == 0)
continue;
key = xmlHashComputeKey(table, oldtable[i].name, oldtable[i].name2,
oldtable[i].name3);
memcpy(&(table->table[key]), &(oldtable[i]), sizeof(xmlHashEntry));
table->table[key].next = NULL;
}
for (i = 0; i < oldsize; i++) {
iter = oldtable[i].next;
while (iter) {
next = iter->next;
@ -161,8 +177,14 @@ xmlHashGrow(xmlHashTablePtr table, int size) {
key = xmlHashComputeKey(table, iter->name, iter->name2,
iter->name3);
iter->next = table->table[key];
table->table[key] = iter;
if (table->table[key].valid == 0) {
memcpy(&(table->table[key]), iter, sizeof(xmlHashEntry));
table->table[key].next = NULL;
xmlFree(iter);
} else {
iter->next = table->table[key].next;
table->table[key].next = iter;
}
#ifdef DEBUG_GROW
nbElem++;
@ -195,12 +217,16 @@ xmlHashFree(xmlHashTablePtr table, xmlHashDeallocator f) {
int i;
xmlHashEntryPtr iter;
xmlHashEntryPtr next;
int inside_table = 0;
if (table == NULL)
return;
if (table->table) {
for(i = 0; i < table->size; i++) {
iter = table->table[i];
iter = &(table->table[i]);
if (iter->valid == 0)
continue;
inside_table = 1;
while (iter) {
next = iter->next;
if (f)
@ -212,10 +238,12 @@ xmlHashFree(xmlHashTablePtr table, xmlHashDeallocator f) {
if (iter->name3)
xmlFree(iter->name3);
iter->payload = NULL;
xmlFree(iter);
if (!inside_table)
xmlFree(iter);
inside_table = 0;
iter = next;
}
table->table[i] = NULL;
inside_table = 0;
}
xmlFree(table->table);
}
@ -355,10 +383,10 @@ xmlHashAddEntry3(xmlHashTablePtr table, const xmlChar *name,
* Check for duplicate and insertion location.
*/
key = xmlHashComputeKey(table, name, name2, name3);
if (table->table[key] == NULL) {
if (table->table[key].valid == 0) {
insert = NULL;
} else {
for (insert = table->table[key]; insert->next != NULL;
for (insert = &(table->table[key]); insert->next != NULL;
insert = insert->next) {
if ((xmlStrEqual(insert->name, name)) &&
(xmlStrEqual(insert->name2, name2)) &&
@ -372,21 +400,25 @@ xmlHashAddEntry3(xmlHashTablePtr table, const xmlChar *name,
return(-1);
}
entry = xmlMalloc(sizeof(xmlHashEntry));
if (entry == NULL)
return(-1);
if (insert == NULL) {
entry = &(table->table[key]);
} else {
entry = xmlMalloc(sizeof(xmlHashEntry));
if (entry == NULL)
return(-1);
}
entry->name = xmlStrdup(name);
entry->name2 = xmlStrdup(name2);
entry->name3 = xmlStrdup(name3);
entry->payload = userdata;
entry->next = NULL;
entry->valid = 1;
if (insert == NULL) {
table->table[key] = entry;
} else {
if (insert != NULL)
insert->next = entry;
}
table->nbElems++;
if (len > MAX_HASH_LEN)
@ -425,10 +457,10 @@ xmlHashUpdateEntry3(xmlHashTablePtr table, const xmlChar *name,
* Check for duplicate and insertion location.
*/
key = xmlHashComputeKey(table, name, name2, name3);
if (table->table[key] == NULL) {
if (table->table[key].valid == 0) {
insert = NULL;
} else {
for (insert = table->table[key]; insert->next != NULL;
for (insert = &(table->table[key]); insert->next != NULL;
insert = insert->next) {
if ((xmlStrEqual(insert->name, name)) &&
(xmlStrEqual(insert->name2, name2)) &&
@ -449,20 +481,24 @@ xmlHashUpdateEntry3(xmlHashTablePtr table, const xmlChar *name,
}
}
entry = xmlMalloc(sizeof(xmlHashEntry));
if (entry == NULL)
return(-1);
if (insert == NULL) {
entry = &(table->table[key]);
} else {
entry = xmlMalloc(sizeof(xmlHashEntry));
if (entry == NULL)
return(-1);
}
entry->name = xmlStrdup(name);
entry->name2 = xmlStrdup(name2);
entry->name3 = xmlStrdup(name3);
entry->payload = userdata;
entry->next = NULL;
entry->valid = 1;
table->nbElems++;
if (insert == NULL) {
table->table[key] = entry;
} else {
if (insert != NULL) {
insert->next = entry;
}
return(0);
@ -490,7 +526,9 @@ xmlHashLookup3(xmlHashTablePtr table, const xmlChar *name,
if (name == NULL)
return(NULL);
key = xmlHashComputeKey(table, name, name2, name3);
for (entry = table->table[key]; entry != NULL; entry = entry->next) {
if (table->table[key].valid == 0)
return(NULL);
for (entry = &(table->table[key]); entry != NULL; entry = entry->next) {
if ((xmlStrEqual(entry->name, name)) &&
(xmlStrEqual(entry->name2, name2)) &&
(xmlStrEqual(entry->name3, name3)))
@ -549,7 +587,9 @@ xmlHashScanFull(xmlHashTablePtr table, xmlHashScannerFull f, void *data) {
if (table->table) {
for(i = 0; i < table->size; i++) {
iter = table->table[i];
if (table->table[i].valid == 0)
continue;
iter = &(table->table[i]);
while (iter) {
next = iter->next;
if (f)
@ -610,7 +650,9 @@ xmlHashScanFull3(xmlHashTablePtr table, const xmlChar *name,
if (table->table) {
for(i = 0; i < table->size; i++) {
iter = table->table[i];
if (table->table[i].valid == 0)
continue;
iter = &(table->table[i]);
while (iter) {
next = iter->next;
if (((name == NULL) || (xmlStrEqual(name, iter->name))) &&
@ -649,7 +691,9 @@ xmlHashCopy(xmlHashTablePtr table, xmlHashCopier f) {
ret = xmlHashCreate(table->size);
if (table->table) {
for(i = 0; i < table->size; i++) {
iter = table->table[i];
if (table->table[i].valid == 0)
continue;
iter = &(table->table[i]);
while (iter) {
next = iter->next;
xmlHashAddEntry3(ret, iter->name, iter->name2,
@ -737,10 +781,10 @@ int xmlHashRemoveEntry3(xmlHashTablePtr table, const xmlChar *name,
return(-1);
key = xmlHashComputeKey(table, name, name2, name3);
if (table->table[key] == NULL) {
if (table->table[key].valid == 0) {
return(-1);
} else {
for (entry = table->table[key]; entry != NULL; entry = entry->next) {
for (entry = &(table->table[key]); entry != NULL; entry = entry->next) {
if (xmlStrEqual(entry->name, name) &&
xmlStrEqual(entry->name2, name2) &&
xmlStrEqual(entry->name3, name3)) {
@ -753,11 +797,18 @@ int xmlHashRemoveEntry3(xmlHashTablePtr table, const xmlChar *name,
xmlFree(entry->name2);
if(entry->name3)
xmlFree(entry->name3);
if(prev)
if(prev) {
prev->next = entry->next;
else
table->table[key] = entry->next;
xmlFree(entry);
xmlFree(entry);
} else {
if (entry->next == NULL) {
entry->valid = 0;
} else {
entry = entry->next;
memcpy(&(table->table[key]), entry, sizeof(xmlHashEntry));
xmlFree(entry);
}
}
table->nbElems--;
return(0);
}

View File

@ -268,8 +268,8 @@ static int spacePop(xmlParserCtxtPtr ctxt) {
* GROW, SHRINK handling of input buffers
*/
#define RAW (ctxt->token ? -1 : (*ctxt->input->cur))
#define CUR (ctxt->token ? ctxt->token : (*ctxt->input->cur))
#define RAW (*ctxt->input->cur)
#define CUR (*ctxt->input->cur)
#define NXT(val) ctxt->input->cur[(val)]
#define CUR_PTR ctxt->input->cur
@ -316,7 +316,7 @@ static void xmlGROW (xmlParserCtxtPtr ctxt) {
if (*(ctxt->input->cur) == '\n') { \
ctxt->input->line++; ctxt->input->col = 1; \
} else ctxt->input->col++; \
ctxt->token = 0; ctxt->input->cur += l; \
ctxt->input->cur += l; \
if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt); \
} while (0)
@ -341,12 +341,6 @@ int
xmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
int res = 0;
if (ctxt->token != 0) {
if (!IS_BLANK(ctxt->token))
return(0);
ctxt->token = 0;
res++;
}
/*
* It's Okay to use CUR/NEXT here since all the blanks are on
* the ASCII range.
@ -465,11 +459,6 @@ xmlParseCharRef(xmlParserCtxtPtr ctxt) {
unsigned int val = 0;
int count = 0;
if (ctxt->token != 0) {
val = ctxt->token;
ctxt->token = 0;
return(val);
}
/*
* Using RAW/CUR/NEXT is okay since we are working on ASCII range here
*/
@ -754,9 +743,6 @@ xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) {
xmlEntityPtr entity = NULL;
xmlParserInputPtr input;
if (ctxt->token != 0) {
return;
}
if (RAW != '%') return;
switch(ctxt->instate) {
case XML_PARSER_CDATA_SECTION:
@ -2363,32 +2349,10 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt) {
* OK loop until we reach one of the ending char or a size limit.
*/
c = CUR_CHAR(l);
while (((NXT(0) != limit) && /* checked */
(c != '<')) || (ctxt->token != 0)) {
while ((NXT(0) != limit) && /* checked */
(c != '<')) {
if (c == 0) break;
if (ctxt->token == '&') {
if (ctxt->replaceEntities) {
if (len > buf_size - 10) {
growBuffer(buf);
}
buf[len++] = '&';
} else {
/*
* The reparsing will be done in xmlStringGetNodeList()
* called by the attribute() function in SAX.c
*/
static xmlChar buffer[6] = "&#38;";
if (len > buf_size - 10) {
growBuffer(buf);
}
current = &buffer[0];
while (*current != 0) { /* non input consuming */
buf[len++] = *current++;
}
ctxt->token = 0;
}
} else if (c == '&') {
if (c == '&') {
if (NXT(1) == '#') {
int val = xmlParseCharRef(ctxt);
if (val == '&') {
@ -2707,7 +2671,7 @@ xmlParseCharData(xmlParserCtxtPtr ctxt, int cdata) {
* Accelerated common case where input don't need to be
* modified before passing it to the handler.
*/
if ((ctxt->token == 0) && (!cdata)) {
if (!cdata) {
in = ctxt->input->cur;
do {
get_more:
@ -2799,9 +2763,9 @@ xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata) {
SHRINK;
GROW;
cur = CUR_CHAR(l);
while (((cur != '<') || (ctxt->token == '<')) && /* checked */
((cur != '&') || (ctxt->token == '&')) &&
(IS_CHAR(cur))) /* test also done in xmlCurrentChar() */ {
while ((cur != '<') && /* checked */
(cur != '&') &&
(IS_CHAR(cur))) /* test also done in xmlCurrentChar() */ {
if ((cur == ']') && (NXT(1) == ']') &&
(NXT(2) == '>')) {
if (cdata) break;
@ -4960,7 +4924,6 @@ xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
(NXT(2) != '>'))) {
const xmlChar *check = CUR_PTR;
int cons = ctxt->input->consumed;
int tok = ctxt->token;
if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
xmlParseConditionalSections(ctxt);
@ -4977,8 +4940,7 @@ xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
while ((RAW == 0) && (ctxt->inputNr > 1))
xmlPopInput(ctxt);
if ((CUR_PTR == check) && (cons == ctxt->input->consumed) &&
(tok == ctxt->token)) {
if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
ctxt->errNo = XML_ERR_EXT_SUBSET_NOT_FINISHED;
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
@ -5270,7 +5232,6 @@ xmlParseExternalSubset(xmlParserCtxtPtr ctxt, const xmlChar *ExternalID,
(RAW == '%') || IS_BLANK(CUR)) {
const xmlChar *check = CUR_PTR;
int cons = ctxt->input->consumed;
int tok = ctxt->token;
GROW;
if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
@ -5288,8 +5249,7 @@ xmlParseExternalSubset(xmlParserCtxtPtr ctxt, const xmlChar *ExternalID,
while ((RAW == 0) && (ctxt->inputNr > 1))
xmlPopInput(ctxt);
if ((CUR_PTR == check) && (cons == ctxt->input->consumed) &&
(tok == ctxt->token)) {
if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
ctxt->errNo = XML_ERR_EXT_SUBSET_NOT_FINISHED;
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
@ -6884,23 +6844,16 @@ xmlParseCDSect(xmlParserCtxtPtr ctxt) {
void
xmlParseContent(xmlParserCtxtPtr ctxt) {
GROW;
while (((RAW != 0) || (ctxt->token != 0)) &&
while ((RAW != 0) &&
((RAW != '<') || (NXT(1) != '/'))) {
const xmlChar *test = CUR_PTR;
int cons = ctxt->input->consumed;
int tok = ctxt->token;
const xmlChar *cur = ctxt->input->cur;
/*
* Handle possible processed charrefs.
*/
if (ctxt->token != 0) {
xmlParseCharData(ctxt, 0);
}
/*
* First case : a Processing Instruction.
*/
else if ((*cur == '<') && (cur[1] == '?')) {
if ((*cur == '<') && (cur[1] == '?')) {
xmlParsePI(ctxt);
}
@ -6955,8 +6908,7 @@ xmlParseContent(xmlParserCtxtPtr ctxt) {
xmlPopInput(ctxt);
SHRINK;
if ((cons == ctxt->input->consumed) && (test == CUR_PTR) &&
(tok == ctxt->token)) {
if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
ctxt->errNo = XML_ERR_INTERNAL_ERROR;
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
@ -8573,20 +8525,6 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
case XML_PARSER_CONTENT: {
const xmlChar *test;
int cons;
int tok;
/*
* Handle preparsed entities and charRef
*/
if (ctxt->token != 0) {
xmlChar current[2] = { 0 , 0 } ;
current[0] = (xmlChar) ctxt->token;
if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
(ctxt->sax->characters != NULL))
ctxt->sax->characters(ctxt->userData, current, 1);
ctxt->token = 0;
}
if ((avail < 2) && (ctxt->inputNr == 1))
goto done;
cur = ctxt->input->cur[0];
@ -8594,7 +8532,6 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
test = CUR_PTR;
cons = ctxt->input->consumed;
tok = ctxt->token;
if ((cur == '<') && (next == '?')) {
if ((!terminate) &&
(xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
@ -8684,8 +8621,7 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
*/
while ((RAW == 0) && (ctxt->inputNr > 1))
xmlPopInput(ctxt);
if ((cons == ctxt->input->consumed) && (test == CUR_PTR) &&
(tok == ctxt->token)) {
if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
ctxt->errNo = XML_ERR_INTERNAL_ERROR;
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,

View File

@ -1110,8 +1110,7 @@ xmlNextChar(xmlParserCtxtPtr ctxt) {
* literal #xD, an XML processor must pass to the application
* the single character #xA.
*/
if (ctxt->token != 0) ctxt->token = 0;
else if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
if ((*ctxt->input->cur == 0) &&
(xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0) &&
(ctxt->instate != XML_PARSER_COMMENT)) {
@ -1260,10 +1259,6 @@ xmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) {
if (ctxt->instate == XML_PARSER_EOF)
return(0);
if (ctxt->token != 0) {
*len = 0;
return(ctxt->token);
}
if ((*ctxt->input->cur >= 0x20) && (*ctxt->input->cur <= 0x7F)) {
*len = 1;
return((int) *ctxt->input->cur);
@ -2785,11 +2780,11 @@ xmlDecodeEntities(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED, int len ATTRIBUTE_UNUS
(c != end2) && (c != end3)) {
GROW;
if (c == 0) break;
if (((c == '&') && (ctxt->token != '&')) && (NXT(1) == '#')) {
if ((c == '&') && (NXT(1) == '#')) {
int val = xmlParseCharRef(ctxt);
COPY_BUF(0,buffer,nbchars,val);
NEXTL(l);
} else if ((c == '&') && (ctxt->token != '&') &&
} else if (c == '&') &&
(what & XML_SUBSTITUTE_REF)) {
if (xmlParserDebugEntities)
xmlGenericError(xmlGenericErrorContext,
@ -3321,229 +3316,6 @@ xmlParserHandleReference(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED) {
deprecated = 1;
}
#if 0
xmlParserInputPtr input;
xmlChar *name;
xmlEntityPtr ent = NULL;
if (ctxt->token != 0) {
return;
}
if (RAW != '&') return;
GROW;
if ((RAW == '&') && (NXT(1) == '#')) {
switch(ctxt->instate) {
case XML_PARSER_ENTITY_DECL:
case XML_PARSER_PI:
case XML_PARSER_CDATA_SECTION:
case XML_PARSER_COMMENT:
case XML_PARSER_SYSTEM_LITERAL:
/* we just ignore it there */
return;
case XML_PARSER_START_TAG:
return;
case XML_PARSER_END_TAG:
return;
case XML_PARSER_EOF:
ctxt->errNo = XML_ERR_CHARREF_AT_EOF;
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData, "CharRef at EOF\n");
ctxt->wellFormed = 0;
ctxt->disableSAX = 1;
return;
case XML_PARSER_PROLOG:
case XML_PARSER_START:
case XML_PARSER_MISC:
ctxt->errNo = XML_ERR_CHARREF_IN_PROLOG;
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData, "CharRef in prolog!\n");
ctxt->wellFormed = 0;
ctxt->disableSAX = 1;
return;
case XML_PARSER_EPILOG:
ctxt->errNo = XML_ERR_CHARREF_IN_EPILOG;
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData, "CharRef in epilog!\n");
ctxt->wellFormed = 0;
ctxt->disableSAX = 1;
return;
case XML_PARSER_DTD:
ctxt->errNo = XML_ERR_CHARREF_IN_DTD;
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
"CharRef are forbidden in DTDs!\n");
ctxt->wellFormed = 0;
ctxt->disableSAX = 1;
return;
case XML_PARSER_ENTITY_VALUE:
/*
* NOTE: in the case of entity values, we don't do the
* substitution here since we need the literal
* entity value to be able to save the internal
* subset of the document.
* This will be handled by xmlStringDecodeEntities
*/
return;
case XML_PARSER_CONTENT:
return;
case XML_PARSER_ATTRIBUTE_VALUE:
/* ctxt->token = xmlParseCharRef(ctxt); */
return;
case XML_PARSER_IGNORE:
return;
}
return;
}
switch(ctxt->instate) {
case XML_PARSER_CDATA_SECTION:
return;
case XML_PARSER_PI:
case XML_PARSER_COMMENT:
case XML_PARSER_SYSTEM_LITERAL:
case XML_PARSER_CONTENT:
return;
case XML_PARSER_START_TAG:
return;
case XML_PARSER_END_TAG:
return;
case XML_PARSER_EOF:
ctxt->errNo = XML_ERR_ENTITYREF_AT_EOF;
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData, "Reference at EOF\n");
ctxt->wellFormed = 0;
ctxt->disableSAX = 1;
return;
case XML_PARSER_PROLOG:
case XML_PARSER_START:
case XML_PARSER_MISC:
ctxt->errNo = XML_ERR_ENTITYREF_IN_PROLOG;
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData, "Reference in prolog!\n");
ctxt->wellFormed = 0;
ctxt->disableSAX = 1;
return;
case XML_PARSER_EPILOG:
ctxt->errNo = XML_ERR_ENTITYREF_IN_EPILOG;
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData, "Reference in epilog!\n");
ctxt->wellFormed = 0;
ctxt->disableSAX = 1;
return;
case XML_PARSER_ENTITY_VALUE:
/*
* NOTE: in the case of entity values, we don't do the
* substitution here since we need the literal
* entity value to be able to save the internal
* subset of the document.
* This will be handled by xmlStringDecodeEntities
*/
return;
case XML_PARSER_ATTRIBUTE_VALUE:
/*
* NOTE: in the case of attributes values, we don't do the
* substitution here unless we are in a mode where
* the parser is explicitly asked to substitute
* entities. The SAX callback is called with values
* without entity substitution.
* This will then be handled by xmlStringDecodeEntities
*/
return;
case XML_PARSER_ENTITY_DECL:
/*
* we just ignore it there
* the substitution will be done once the entity is referenced
*/
return;
case XML_PARSER_DTD:
ctxt->errNo = XML_ERR_ENTITYREF_IN_DTD;
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
"Entity references are forbidden in DTDs!\n");
ctxt->wellFormed = 0;
ctxt->disableSAX = 1;
return;
case XML_PARSER_IGNORE:
return;
}
/* TODO: this seems not reached anymore .... Verify ... */
xmlGenericError(xmlGenericErrorContext,
"Reached deprecated section in xmlParserHandleReference()\n");
xmlGenericError(xmlGenericErrorContext,
"Please forward the document to daniel@veillard.com\n");
xmlGenericError(xmlGenericErrorContext,
"indicating the version: %s, thanks !\n", xmlParserVersion);
NEXT;
name = xmlScanName(ctxt);
if (name == NULL) {
ctxt->errNo = XML_ERR_ENTITYREF_NO_NAME;
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData, "Entity reference: no name\n");
ctxt->wellFormed = 0;
ctxt->disableSAX = 1;
ctxt->token = '&';
return;
}
if (NXT(xmlStrlen(name)) != ';') {
ctxt->errNo = XML_ERR_ENTITYREF_SEMICOL_MISSING;
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
"Entity reference: ';' expected\n");
ctxt->wellFormed = 0;
ctxt->disableSAX = 1;
ctxt->token = '&';
xmlFree(name);
return;
}
SKIP(xmlStrlen(name) + 1);
if (ctxt->sax != NULL) {
if (ctxt->sax->getEntity != NULL)
ent = ctxt->sax->getEntity(ctxt->userData, name);
}
/*
* [ WFC: Entity Declared ]
* the Name given in the entity reference must match that in an entity
* declaration, except that well-formed documents need not declare any
* of the following entities: amp, lt, gt, apos, quot.
*/
if (ent == NULL)
ent = xmlGetPredefinedEntity(name);
if (ent == NULL) {
ctxt->errNo = XML_ERR_UNDECLARED_ENTITY;
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
"Entity reference: entity %s not declared\n",
name);
ctxt->wellFormed = 0;
ctxt->disableSAX = 1;
xmlFree(name);
return;
}
/*
* [ WFC: Parsed Entity ]
* An entity reference must not contain the name of an unparsed entity
*/
if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
ctxt->errNo = XML_ERR_UNPARSED_ENTITY;
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
"Entity reference to unparsed entity %s\n", name);
ctxt->wellFormed = 0;
ctxt->disableSAX = 1;
}
if (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY) {
ctxt->token = ent->content[0];
xmlFree(name);
return;
}
input = xmlNewEntityInputStream(ctxt, ent);
xmlPushInput(ctxt, input);
xmlFree(name);
#endif
return;
}

View File

@ -222,3 +222,23 @@ Object is a number : Infinity
========================
Expression: -(1 div 0) div 1
Object is a number : -Infinity
========================
Expression: 5 mod 2
Object is a number : 1
========================
Expression: 5 mod -2
Object is a number : 1
========================
Expression: -5 mod 2
Object is a number : -1
========================
Expression: -5 mod -2
Object is a number : -1
========================
Expression: 8 mod 3 = 2
Object is a Boolean : true

View File

@ -54,3 +54,8 @@ number('f') div 1
1 div (1 div 0)
(1 div 0) div 1
-(1 div 0) div 1
5 mod 2
5 mod -2
-5 mod 2
-5 mod -2
8 mod 3 = 2

View File

@ -209,6 +209,20 @@ xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
return (ret);
}
/**
* xmlSchemaFreeAnnot:
* @annot: a schema type structure
*
* Deallocate a annotation structure
*/
static void
xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
{
if (annot == NULL)
return;
xmlFree(annot);
}
/**
* xmlSchemaFreeNotation:
* @schema: a schema notation structure
@ -310,6 +324,8 @@ xmlSchemaFreeFacet(xmlSchemaFacetPtr facet)
xmlSchemaFreeValue(facet->val);
if (facet->regexp != NULL)
xmlRegFreeRegexp(facet->regexp);
if (facet->annot != NULL)
xmlSchemaFreeAnnot(facet->annot);
xmlFree(facet);
}
@ -345,20 +361,6 @@ xmlSchemaFreeType(xmlSchemaTypePtr type)
xmlFree(type);
}
/**
* xmlSchemaFreeAnnot:
* @annot: a schema type structure
*
* Deallocate a annotation structure
*/
static void
xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
{
if (annot == NULL)
return;
xmlFree(annot);
}
/**
* xmlSchemaFree:
* @schema: a schema structure

View File

@ -1463,18 +1463,25 @@ xmlSchemaCompareDates (xmlSchemaValPtr x, xmlSchemaValPtr y)
q1 = xmlSchemaDateNormalize(y, (14 * SECS_PER_HOUR));
q1d = _xmlSchemaDateCastYMToDays(q1) + q1->value.date.day;
if (p1d < q1d)
if (p1d < q1d) {
xmlSchemaFreeValue(p1);
xmlSchemaFreeValue(q1);
return -1;
else if (p1d == q1d) {
} else if (p1d == q1d) {
double sec;
sec = TIME_TO_NUMBER(p1) - TIME_TO_NUMBER(q1);
if (sec < 0.0)
if (sec < 0.0) {
xmlSchemaFreeValue(p1);
xmlSchemaFreeValue(q1);
return -1;
else {
} else {
/* normalize y - 14:00 */
q2 = xmlSchemaDateNormalize(y, -(14 * SECS_PER_HOUR));
q2d = _xmlSchemaDateCastYMToDays(q2) + q2->value.date.day;
xmlSchemaFreeValue(p1);
xmlSchemaFreeValue(q1);
xmlSchemaFreeValue(q2);
if (p1d > q2d)
return 1;
else if (p1d == q2d) {
@ -1485,7 +1492,10 @@ xmlSchemaCompareDates (xmlSchemaValPtr x, xmlSchemaValPtr y)
return 2; /* indeterminate */
}
}
}
} else {
xmlSchemaFreeValue(p1);
xmlSchemaFreeValue(q1);
}
}
} else if (y->value.date.tz_flag) {
q1 = xmlSchemaDateNormalize(y, 0);
@ -1495,19 +1505,26 @@ xmlSchemaCompareDates (xmlSchemaValPtr x, xmlSchemaValPtr y)
p1 = xmlSchemaDateNormalize(x, -(14 * SECS_PER_HOUR));
p1d = _xmlSchemaDateCastYMToDays(p1) + p1->value.date.day;
if (p1d < q1d)
if (p1d < q1d) {
xmlSchemaFreeValue(p1);
xmlSchemaFreeValue(q1);
return -1;
else if (p1d == q1d) {
} else if (p1d == q1d) {
double sec;
sec = TIME_TO_NUMBER(p1) - TIME_TO_NUMBER(q1);
if (sec < 0.0)
if (sec < 0.0) {
xmlSchemaFreeValue(p1);
xmlSchemaFreeValue(q1);
return -1;
else {
} else {
/* normalize x + 14:00 */
p2 = xmlSchemaDateNormalize(x, (14 * SECS_PER_HOUR));
p2d = _xmlSchemaDateCastYMToDays(p2) + p2->value.date.day;
xmlSchemaFreeValue(p1);
xmlSchemaFreeValue(q1);
xmlSchemaFreeValue(p2);
if (p2d > q1d)
return 1;
else if (p2d == q1d) {
@ -1518,6 +1535,9 @@ xmlSchemaCompareDates (xmlSchemaValPtr x, xmlSchemaValPtr y)
return 2; /* indeterminate */
}
}
} else {
xmlSchemaFreeValue(p1);
xmlSchemaFreeValue(q1);
}
}
@ -1531,14 +1551,20 @@ xmlSchemaCompareDates (xmlSchemaValPtr x, xmlSchemaValPtr y)
p1 = xmlSchemaDateNormalize(x, 0);
p1d = _xmlSchemaDateCastYMToDays(p1) + p1->value.date.day;
if (p1d < q1d)
if (p1d < q1d) {
xmlSchemaFreeValue(p1);
xmlSchemaFreeValue(q1);
return -1;
else if (p1d > q1d)
} else if (p1d > q1d) {
xmlSchemaFreeValue(p1);
xmlSchemaFreeValue(q1);
return 1;
else {
} else {
double sec;
sec = TIME_TO_NUMBER(p1) - TIME_TO_NUMBER(q1);
xmlSchemaFreeValue(p1);
xmlSchemaFreeValue(q1);
if (sec < 0.0)
return -1;
else if (sec > 0.0)

31
xpath.c
View File

@ -4873,7 +4873,7 @@ xmlXPathDivValues(xmlXPathParserContextPtr ctxt) {
void
xmlXPathModValues(xmlXPathParserContextPtr ctxt) {
xmlXPathObjectPtr arg;
double arg1, arg2, tmp;
double arg1, arg2;
arg = valuePop(ctxt);
if (arg == NULL)
@ -4887,8 +4887,7 @@ xmlXPathModValues(xmlXPathParserContextPtr ctxt) {
if (arg2 == 0)
ctxt->value->floatval = xmlXPathNAN;
else {
tmp=arg1/arg2;
ctxt->value->floatval = arg2 * (tmp - (double)((int)tmp));
ctxt->value->floatval = fmod(arg1, arg2);
}
}
@ -5443,26 +5442,28 @@ xmlXPathNextPrecedingInternal(xmlXPathParserContextPtr ctxt,
*/
xmlNodePtr
xmlXPathNextNamespace(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
xmlNodePtr ret;
if (ctxt->context->node->type != XML_ELEMENT_NODE) return(NULL);
if (cur == (xmlNodePtr) xmlXPathXMLNamespace)
return(NULL);
if ((cur == NULL) || (ctxt->context->tmpNsList == NULL)) {
if (ctxt->context->tmpNsList == NULL && cur != (xmlNodePtr) xmlXPathXMLNamespace) {
if (ctxt->context->tmpNsList != NULL)
xmlFree(ctxt->context->tmpNsList);
ctxt->context->tmpNsList =
xmlGetNsList(ctxt->context->doc, ctxt->context->node);
if (ctxt->context->tmpNsList == NULL) return(NULL);
ctxt->context->tmpNsNr = 0;
}
ret = (xmlNodePtr)ctxt->context->tmpNsList[ctxt->context->tmpNsNr++];
if (ret == NULL) {
xmlFree(ctxt->context->tmpNsList);
ctxt->context->tmpNsList = NULL;
if (ctxt->context->tmpNsList != NULL) {
while (ctxt->context->tmpNsList[ctxt->context->tmpNsNr] != NULL) {
ctxt->context->tmpNsNr++;
}
}
return((xmlNodePtr) xmlXPathXMLNamespace);
}
return(ret);
if (ctxt->context->tmpNsNr > 0) {
return (xmlNodePtr)ctxt->context->tmpNsList[--ctxt->context->tmpNsNr];
} else {
if (ctxt->context->tmpNsList != NULL)
xmlFree(ctxt->context->tmpNsList);
ctxt->context->tmpNsList = NULL;
return(NULL);
}
}
/**