diff --git a/ChangeLog b/ChangeLog index ae121b83..f5d21b20 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,16 @@ +Mon Jul 1 23:23:41 CEST 2002 Daniel Veillard + + * 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 - * 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 diff --git a/Makefile.am b/Makefile.am index 96433960..0d3162f1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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@ diff --git a/hash.c b/hash.c index f1bfb926..28bf014f 100644 --- a/hash.c +++ b/hash.c @@ -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); } diff --git a/parser.c b/parser.c index 2d08673c..2338100d 100644 --- a/parser.c +++ b/parser.c @@ -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] = "&"; - - 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, diff --git a/parserInternals.c b/parserInternals.c index 68ac5382..8d4e680f 100644 --- a/parserInternals.c +++ b/parserInternals.c @@ -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; } diff --git a/result/XPath/expr/floats b/result/XPath/expr/floats index bc3801d7..b6255ce0 100644 --- a/result/XPath/expr/floats +++ b/result/XPath/expr/floats @@ -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 diff --git a/test/XPath/expr/floats b/test/XPath/expr/floats index 2453186f..96c10d15 100644 --- a/test/XPath/expr/floats +++ b/test/XPath/expr/floats @@ -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 diff --git a/xmlschemas.c b/xmlschemas.c index bae2c7aa..99956d48 100644 --- a/xmlschemas.c +++ b/xmlschemas.c @@ -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 diff --git a/xmlschemastypes.c b/xmlschemastypes.c index 4d632248..06150252 100644 --- a/xmlschemastypes.c +++ b/xmlschemastypes.c @@ -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) diff --git a/xpath.c b/xpath.c index 4d2fcd73..f8249896 100644 --- a/xpath.c +++ b/xpath.c @@ -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); + } } /**