1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-10-21 14:53:44 +03:00

better handling of conditional features more testing on parser contexts

* gentest.py testapi.c: better handling of conditional features
* HTMLparser.c SAX2.c parserInternals.c xmlwriter.c: more testing
  on parser contexts closed leaks, error messages
Daniel
This commit is contained in:
Daniel Veillard
2004-11-09 14:59:59 +00:00
parent 645a924a9d
commit a521d28751
7 changed files with 631 additions and 158 deletions

View File

@@ -1,3 +1,9 @@
Tue Nov 9 15:59:50 CET 2004 Daniel Veillard <daniel@veillard.com>
* gentest.py testapi.c: better handling of conditional features
* HTMLparser.c SAX2.c parserInternals.c xmlwriter.c: more testing
on parser contexts closed leaks, error messages
Tue Nov 9 10:21:37 GMT 2004 William Brack <wbrack@mmm.com.hk> Tue Nov 9 10:21:37 GMT 2004 William Brack <wbrack@mmm.com.hk>
* xpath.c: fixed problem concerning XPath context corruption * xpath.c: fixed problem concerning XPath context corruption

View File

@@ -5675,8 +5675,12 @@ htmlCtxtReset(htmlParserCtxtPtr ctxt)
ctxt->input = NULL; ctxt->input = NULL;
ctxt->spaceNr = 0; ctxt->spaceNr = 0;
ctxt->spaceTab[0] = -1; if (ctxt->spaceTab != NULL) {
ctxt->space = &ctxt->spaceTab[0]; ctxt->spaceTab[0] = -1;
ctxt->space = &ctxt->spaceTab[0];
} else {
ctxt->space = NULL;
}
ctxt->nodeNr = 0; ctxt->nodeNr = 0;

2
SAX2.c
View File

@@ -1421,7 +1421,7 @@ xmlSAX2StartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
const xmlChar *value; const xmlChar *value;
int i; int i;
if ((ctx == NULL) || (fullname == NULL)) return; if ((ctx == NULL) || (fullname == NULL) || (ctxt->myDoc == NULL)) return;
parent = ctxt->node; parent = ctxt->node;
#ifdef DEBUG_SAX #ifdef DEBUG_SAX
xmlGenericError(xmlGenericErrorContext, xmlGenericError(xmlGenericErrorContext,

View File

@@ -20,6 +20,80 @@ skipped_modules = [ "SAX", "xlink", "threads", "globals",
"DOCBparser", "DOCBparser",
] ]
#
# defines for each module
#
modules_defines = {
"HTMLparser": "LIBXML_HTML_ENABLED",
"catalog": "LIBXML_CATALOG_ENABLED",
"xmlreader": "LIBXML_READER_ENABLED",
"relaxng": "LIBXML_SCHEMAS_ENABLED",
"schemasInternals": "LIBXML_SCHEMAS_ENABLED",
"xmlschemas": "LIBXML_SCHEMAS_ENABLED",
"xmlschemastypes": "LIBXML_SCHEMAS_ENABLED",
"xpath": "LIBXML_XPATH_ENABLED",
"xpathInternals": "LIBXML_XPATH_ENABLED",
"xinclude": "LIBXML_XINCLUDE_ENABLED",
"xpointer": "LIBXML_XPTR_ENABLED",
"xmlregexp" : "LIBXML_REGEXP_ENABLED",
"xmlautomata" : "LIBXML_AUTOMATA_ENABLED",
"xmlsave" : "LIBXML_OUTPUT_ENABLED",
"DOCBparser" : "LIBXML_DOCB_ENABLED",
}
#
# defines for specific functions
#
function_defines = {
"htmlDefaultSAXHandlerInit": "LIBXML_HTML_ENABLED",
"xmlSAX2EndElement" : "LIBXML_SAX1_ENABLED",
"xmlSAX2StartElement" : "LIBXML_SAX1_ENABLED",
"xmlSAXDefaultVersion" : "LIBXML_SAX1_ENABLED",
"UTF8Toisolat1" : "LIBXML_OUTPUT_ENABLED",
"xmlCleanupPredefinedEntities": "LIBXML_LEGACY_ENABLED",
"xmlInitializePredefinedEntities": "LIBXML_LEGACY_ENABLED",
"xmlSetFeature": "LIBXML_LEGACY_ENABLED",
"xmlGetFeature": "LIBXML_LEGACY_ENABLED",
"xmlGetFeaturesList": "LIBXML_LEGACY_ENABLED",
"xmlIOParseDTD": "LIBXML_VALID_ENABLED",
"xmlParseDTD": "LIBXML_VALID_ENABLED",
"xmlParseDoc": "LIBXML_SAX1_ENABLED",
"xmlParseMemory": "LIBXML_SAX1_ENABLED",
"xmlRecoverDoc": "LIBXML_SAX1_ENABLED",
"xmlParseFile": "LIBXML_SAX1_ENABLED",
"xmlRecoverFile": "LIBXML_SAX1_ENABLED",
"xmlRecoverMemory": "LIBXML_SAX1_ENABLED",
"xmlSAXParseFileWithData": "LIBXML_SAX1_ENABLED",
"xmlSAXParseMemory": "LIBXML_SAX1_ENABLED",
"xmlSAXUserParseMemory": "LIBXML_SAX1_ENABLED",
"xmlSAXParseDoc": "LIBXML_SAX1_ENABLED",
"xmlSAXParseDTD": "LIBXML_SAX1_ENABLED",
"xmlSAXUserParseFile": "LIBXML_SAX1_ENABLED",
"xmlParseEntity": "LIBXML_SAX1_ENABLED",
"xmlParseExternalEntity": "LIBXML_SAX1_ENABLED",
"xmlSAXParseMemoryWithData": "LIBXML_SAX1_ENABLED",
"xmlParseBalancedChunkMemory": "LIBXML_SAX1_ENABLED",
"xmlParseBalancedChunkMemoryRecover": "LIBXML_SAX1_ENABLED",
"xmlSetupParserForBuffer": "LIBXML_SAX1_ENABLED",
"xmlStopParser": "LIBXML_PUSH_ENABLED",
"xmlAttrSerializeTxtContent": "LIBXML_OUTPUT_ENABLED",
"xmlSAXParseFile": "LIBXML_SAX1_ENABLED",
"xmlSAXParseEntity": "LIBXML_SAX1_ENABLED",
"xmlNewTextChild": "LIBXML_TREE_ENABLED",
"xmlNewDocRawNode": "LIBXML_TREE_ENABLED",
"xmlNewProp": "LIBXML_TREE_ENABLED",
"xmlReconciliateNs": "LIBXML_TREE_ENABLED",
"xmlValidateNCName": "LIBXML_TREE_ENABLED",
"xmlValidateNMToken": "LIBXML_TREE_ENABLED",
"xmlValidateName": "LIBXML_TREE_ENABLED",
"xmlNewChild": "LIBXML_TREE_ENABLED",
"xmlValidateQName": "LIBXML_TREE_ENABLED",
"xmlSprintfElementContent": "LIBXML_OUTPUT_ENABLED",
"xmlValidGetPotentialChildren" : "LIBXML_VALID_ENABLED",
"xmlValidGetValidElements" : "LIBXML_VALID_ENABLED",
"docbDefaultSAXHandlerInit" : "LIBXML_DOCB_ENABLED",
}
# #
# Some function really need to be skipped for the tests. # Some function really need to be skipped for the tests.
# #
@@ -97,14 +171,26 @@ skipped_memcheck = [ "xmlLoadCatalog", "xmlAddEncodingAlias",
# Extra code needed for some test cases # Extra code needed for some test cases
# #
extra_pre_call = { extra_pre_call = {
"xmlSAXUserParseFile": "xmlSAXUserParseFile": """
"if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;", #ifdef LIBXML_SAX1_ENABLED
"xmlSAXUserParseMemory": if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
"if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;", #endif
"xmlParseBalancedChunkMemory": """,
"if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;", "xmlSAXUserParseMemory": """
"xmlParseBalancedChunkMemoryRecover": #ifdef LIBXML_SAX1_ENABLED
"if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;", if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
#endif
""",
"xmlParseBalancedChunkMemory": """
#ifdef LIBXML_SAX1_ENABLED
if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
#endif
""",
"xmlParseBalancedChunkMemoryRecover": """
#ifdef LIBXML_SAX1_ENABLED
if (sax == (xmlSAXHandlerPtr)&xmlDefaultSAXHandler) user_data = NULL;
#endif
""",
"xmlParserInputBufferCreateFd": "xmlParserInputBufferCreateFd":
"if (fd >= 0) fd = -1;", "if (fd >= 0) fd = -1;",
} }
@@ -151,8 +237,13 @@ extra_post_call = {
"xmlCopyNamespace": "if (ret_val != NULL) xmlFreeNs(ret_val);", "xmlCopyNamespace": "if (ret_val != NULL) xmlFreeNs(ret_val);",
"xmlCopyNamespaceList": "if (ret_val != NULL) xmlFreeNsList(ret_val);", "xmlCopyNamespaceList": "if (ret_val != NULL) xmlFreeNsList(ret_val);",
"xmlNewTextWriter": "if (ret_val != NULL) out = NULL;", "xmlNewTextWriter": "if (ret_val != NULL) out = NULL;",
"xmlNewTextWriterPushParser": "if (ret_val != NULL) ctxt = NULL;", "xmlNewTextWriterPushParser": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;} if (ret_val != NULL) ctxt = NULL;",
"xmlNewIOInputStream": "if (ret_val != NULL) input = NULL;", "xmlNewIOInputStream": "if (ret_val != NULL) input = NULL;",
"htmlParseChunk": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
"htmlParseDocument": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
"xmlParseDocument": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
"xmlParseChunk": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
"xmlParseExtParsedEnt": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
} }
modules = [] modules = []
@@ -217,9 +308,6 @@ def type_convert(str, name, info, module, function, pos):
res = string.replace(str, " *", "_ptr") res = string.replace(str, " *", "_ptr")
# res = string.replace(str, "*", "_ptr") # res = string.replace(str, "*", "_ptr")
res = string.replace(res, " ", "_") res = string.replace(res, " ", "_")
res = string.replace(res, "htmlNode", "xmlNode")
res = string.replace(res, "htmlDoc", "xmlDoc")
res = string.replace(res, "htmlParser", "xmlParser")
if res == 'const_char_ptr': if res == 'const_char_ptr':
if string.find(name, "file") != -1 or \ if string.find(name, "file") != -1 or \
string.find(name, "uri") != -1 or \ string.find(name, "uri") != -1 or \
@@ -301,6 +389,10 @@ def is_known_param_type(name, rtype):
else: else:
crtype = rtype crtype = rtype
define = 0
if modules_defines.has_key(module):
test.write("#ifdef %s\n" % (modules_defines[module]))
define = 1
test.write(""" test.write("""
#define gen_nb_%s 1 #define gen_nb_%s 1
static %s gen_%s(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) { static %s gen_%s(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
@@ -309,6 +401,8 @@ static %s gen_%s(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
static void des_%s(int no ATTRIBUTE_UNUSED, %s val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) { static void des_%s(int no ATTRIBUTE_UNUSED, %s val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
} }
""" % (name, crtype, name, name, rtype)) """ % (name, crtype, name, name, rtype))
if define == 1:
test.write("#endif\n\n")
add_generated_param_type(name) add_generated_param_type(name)
return 1 return 1
@@ -386,6 +480,8 @@ for enum in enums:
name = enum.xpathEval('string(@name)') name = enum.xpathEval('string(@name)')
if name == None: if name == None:
continue; continue;
module = enum.xpathEval('string(@file)')
define = 0
if is_known_param_type(name, name) == 0: if is_known_param_type(name, name) == 0:
values = ctxt.xpathEval("/api/symbols/enum[@type='%s']" % name) values = ctxt.xpathEval("/api/symbols/enum[@type='%s']" % name)
@@ -402,6 +498,9 @@ for enum in enums:
if vals == []: if vals == []:
print "Didn't found any value for enum %s" % (name) print "Didn't found any value for enum %s" % (name)
continue continue
if modules_defines.has_key(module):
test.write("#ifdef %s\n" % (modules_defines[module]))
define = 1
test.write("#define gen_nb_%s %d\n" % (name, len(vals))) test.write("#define gen_nb_%s %d\n" % (name, len(vals)))
test.write("""static %s gen_%s(int no, int nr ATTRIBUTE_UNUSED) {\n""" % test.write("""static %s gen_%s(int no, int nr ATTRIBUTE_UNUSED) {\n""" %
(name, name)) (name, name))
@@ -415,6 +514,9 @@ for enum in enums:
known_param_types.append(name) known_param_types.append(name)
if is_known_return_type(name) == 0: if is_known_return_type(name) == 0:
if define == 0 and modules_defines.has_key(module):
test.write("#ifdef %s\n" % (modules_defines[module]))
define = 1
test.write("""static void des_%s(int no ATTRIBUTE_UNUSED, %s val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) { test.write("""static void des_%s(int no ATTRIBUTE_UNUSED, %s val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) {
} }
static void desret_%s(%s val ATTRIBUTE_UNUSED) { static void desret_%s(%s val ATTRIBUTE_UNUSED) {
@@ -422,6 +524,8 @@ static void desret_%s(%s val ATTRIBUTE_UNUSED) {
""" % (name, name, name, name)) """ % (name, name, name, name))
known_return_types.append(name) known_return_types.append(name)
if define == 1:
test.write("#endif\n\n")
# #
# Load the interfaces # Load the interfaces
@@ -566,6 +670,11 @@ test_%s(void) {
nb_cond = nb_cond + 1 nb_cond = nb_cond + 1
except: except:
pass pass
define = 0
if function_defines.has_key(name):
test.write("#ifdef %s\n" % (function_defines[name]))
define = 1
# Declare the memory usage counter # Declare the memory usage counter
no_mem = is_skipped_memcheck(name) no_mem = is_skipped_memcheck(name)
@@ -672,6 +781,8 @@ test_%s(void) {
while nb_cond > 0: while nb_cond > 0:
test.write("#endif\n") test.write("#endif\n")
nb_cond = nb_cond -1 nb_cond = nb_cond -1
if define == 1:
test.write("#endif\n")
nb_tests = nb_tests + 1; nb_tests = nb_tests + 1;

View File

@@ -574,15 +574,20 @@ encoding_error:
* to ISO-Latin-1 (if you don't like this policy, just declare the * to ISO-Latin-1 (if you don't like this policy, just declare the
* encoding !) * encoding !)
*/ */
__xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR, if ((ctxt == NULL) || (ctxt->input == NULL) ||
"Input is not proper UTF-8, indicate encoding !\n", (ctxt->input->end - ctxt->input->cur < 4)) {
NULL, NULL); __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL) && "Input is not proper UTF-8, indicate encoding !\n",
(ctxt->input != NULL)) { NULL, NULL);
ctxt->sax->error(ctxt->userData, } else {
"Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n", char buffer[150];
ctxt->input->cur[0], ctxt->input->cur[1],
ctxt->input->cur[2], ctxt->input->cur[3]); snprintf(buffer, 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
ctxt->input->cur[0], ctxt->input->cur[1],
ctxt->input->cur[2], ctxt->input->cur[3]);
__xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
"Input is not proper UTF-8, indicate encoding !\n%s",
BAD_CAST buffer, NULL);
} }
ctxt->charset = XML_CHAR_ENCODING_8859_1; ctxt->charset = XML_CHAR_ENCODING_8859_1;
ctxt->input->cur++; ctxt->input->cur++;
@@ -722,14 +727,15 @@ encoding_error:
* to ISO-Latin-1 (if you don't like this policy, just declare the * to ISO-Latin-1 (if you don't like this policy, just declare the
* encoding !) * encoding !)
*/ */
__xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR, {
"Input is not proper UTF-8, indicate encoding !\n", char buffer[150];
NULL, NULL);
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL) && snprintf(buffer, 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
(ctxt->input != NULL)) {
ctxt->sax->error(ctxt->userData, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
ctxt->input->cur[0], ctxt->input->cur[1], ctxt->input->cur[0], ctxt->input->cur[1],
ctxt->input->cur[2], ctxt->input->cur[3]); ctxt->input->cur[2], ctxt->input->cur[3]);
__xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
"Input is not proper UTF-8, indicate encoding !\n%s",
BAD_CAST buffer, NULL);
} }
ctxt->charset = XML_CHAR_ENCODING_8859_1; ctxt->charset = XML_CHAR_ENCODING_8859_1;
*len = 1; *len = 1;
@@ -817,6 +823,16 @@ xmlStringCurrentChar(xmlParserCtxtPtr ctxt, const xmlChar * cur, int *len)
return ((int) *cur); return ((int) *cur);
encoding_error: encoding_error:
/*
* An encoding problem may arise from a truncated input buffer
* splitting a character in the middle. In that case do not raise
* an error but return 0 to endicate an end of stream problem
*/
if ((ctxt == NULL) || (ctxt->input == NULL) ||
(ctxt->input->end - ctxt->input->cur < 4)) {
*len = 0;
return(0);
}
/* /*
* If we detect an UTF8 error that probably mean that the * If we detect an UTF8 error that probably mean that the
* input encoding didn't get properly advertised in the * input encoding didn't get properly advertised in the
@@ -824,15 +840,15 @@ encoding_error:
* to ISO-Latin-1 (if you don't like this policy, just declare the * to ISO-Latin-1 (if you don't like this policy, just declare the
* encoding !) * encoding !)
*/ */
__xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR, {
"Input is not proper UTF-8, indicate encoding !\n", char buffer[150];
NULL, NULL);
if ((ctxt != NULL) && (ctxt->sax != NULL) && (ctxt->sax->error != NULL) && snprintf(buffer, 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
(ctxt->input != NULL)) { ctxt->input->cur[0], ctxt->input->cur[1],
ctxt->sax->error(ctxt->userData, ctxt->input->cur[2], ctxt->input->cur[3]);
"Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n", __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
ctxt->input->cur[0], ctxt->input->cur[1], "Input is not proper UTF-8, indicate encoding !\n%s",
ctxt->input->cur[2], ctxt->input->cur[3]); BAD_CAST buffer, NULL);
} }
*len = 1; *len = 1;
return ((int) *cur); return ((int) *cur);
@@ -1526,6 +1542,8 @@ xmlNewInputFromFile(xmlParserCtxtPtr ctxt, const char *filename) {
int int
xmlInitParserCtxt(xmlParserCtxtPtr ctxt) xmlInitParserCtxt(xmlParserCtxtPtr ctxt)
{ {
xmlParserInputPtr input;
if(ctxt==NULL) { if(ctxt==NULL) {
xmlErrInternal(NULL, "Got NULL parser context\n", NULL); xmlErrInternal(NULL, "Got NULL parser context\n", NULL);
return(-1); return(-1);
@@ -1563,6 +1581,9 @@ xmlInitParserCtxt(xmlParserCtxtPtr ctxt)
ctxt->input = NULL; ctxt->input = NULL;
return(-1); return(-1);
} }
while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
xmlFreeInputStream(input);
}
ctxt->inputNr = 0; ctxt->inputNr = 0;
ctxt->input = NULL; ctxt->input = NULL;

555
testapi.c

File diff suppressed because it is too large Load Diff

View File

@@ -71,6 +71,7 @@ struct _xmlTextWriter {
xmlChar *ichar; /* indent character */ xmlChar *ichar; /* indent character */
char qchar; /* character used for quoting attribute values */ char qchar; /* character used for quoting attribute values */
xmlParserCtxtPtr ctxt; xmlParserCtxtPtr ctxt;
int no_doc_free;
}; };
static void xmlFreeTextWriterStackEntry(xmlLinkPtr lk); static void xmlFreeTextWriterStackEntry(xmlLinkPtr lk);
@@ -198,6 +199,7 @@ xmlNewTextWriter(xmlOutputBufferPtr out)
"xmlNewTextWriter : out of memory!\n"); "xmlNewTextWriter : out of memory!\n");
return NULL; return NULL;
} }
ret->no_doc_free = 0;
return ret; return ret;
} }
@@ -376,8 +378,10 @@ xmlNewTextWriterDoc(xmlDocPtr * doc, int compression)
xmlSetDocCompressMode(ctxt->myDoc, compression); xmlSetDocCompressMode(ctxt->myDoc, compression);
if (doc != NULL) if (doc != NULL) {
*doc = ctxt->myDoc; *doc = ctxt->myDoc;
ret->no_doc_free = 1;
}
return ret; return ret;
} }
@@ -434,6 +438,7 @@ xmlNewTextWriterTree(xmlDocPtr doc, xmlNodePtr node, int compression)
ctxt->myDoc = doc; ctxt->myDoc = doc;
ctxt->node = node; ctxt->node = node;
ret->no_doc_free = 1;
xmlSetDocCompressMode(doc, compression); xmlSetDocCompressMode(doc, compression);
@@ -461,8 +466,13 @@ xmlFreeTextWriter(xmlTextWriterPtr writer)
if (writer->nsstack != NULL) if (writer->nsstack != NULL)
xmlListDelete(writer->nsstack); xmlListDelete(writer->nsstack);
if (writer->ctxt != NULL) if (writer->ctxt != NULL) {
if ((writer->ctxt->myDoc != NULL) && (writer->no_doc_free == 0)) {
xmlFreeDoc(writer->ctxt->myDoc);
writer->ctxt->myDoc = NULL;
}
xmlFreeParserCtxt(writer->ctxt); xmlFreeParserCtxt(writer->ctxt);
}
if (writer->ichar != NULL) if (writer->ichar != NULL)
xmlFree(writer->ichar); xmlFree(writer->ichar);