1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-04-01 10:50:08 +03:00

xmllint: Improve error reports from reader

This commit is contained in:
Nick Wellnhofer 2025-01-17 22:54:51 +01:00
parent 16286dea31
commit 1c82bca6bd
2 changed files with 141 additions and 90 deletions

16
xmlIO.c
View File

@ -1494,11 +1494,25 @@ __xmlParserInputBufferCreateFilename(const char *URI, xmlCharEncoding enc) {
xmlParserInputBufferPtr
xmlParserInputBufferCreateFilename(const char *URI, xmlCharEncoding enc) {
xmlParserInputBufferPtr ret;
int code;
if (xmlParserInputBufferCreateFilenameValue != NULL)
return(xmlParserInputBufferCreateFilenameValue(URI, enc));
xmlParserInputBufferCreateUrl(URI, enc, 0, &ret);
code = xmlParserInputBufferCreateUrl(URI, enc, 0, &ret);
/*
* xmlParserInputBufferCreateFilename has no way to return
* the kind of error although it really is crucial.
* All we can do is to set the global error.
*/
if ((code != XML_ERR_OK) && (code != XML_IO_ENOENT)) {
if (xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_IO, code,
XML_ERR_ERROR, URI, 0, NULL, NULL, NULL, 0, 0,
"Failed to open file\n") < 0)
xmlRaiseMemoryError(NULL, NULL, NULL, XML_FROM_IO, NULL);
}
return(ret);
}

215
xmllint.c
View File

@ -1684,6 +1684,7 @@ static void processNode(xmllintState *lint, xmlTextReaderPtr reader) {
}
static void streamFile(xmllintState *lint, const char *filename) {
xmlParserInputBufferPtr input = NULL;
FILE *errStream = lint->errStream;
xmlTextReaderPtr reader;
int ret;
@ -1694,10 +1695,50 @@ static void streamFile(xmllintState *lint, const char *filename) {
filename, NULL, lint->options);
} else
#endif
if (strcmp(filename, "-") == 0)
reader = xmlReaderForFd(STDIN_FILENO, "-", NULL, lint->options);
else
reader = xmlReaderForFile(filename, NULL, lint->options);
{
if (strcmp(filename, "-") == 0) {
reader = xmlReaderForFd(STDIN_FILENO, "-", NULL, lint->options);
}
else {
/*
* There's still no easy way to get a reader for a file with
* adequate error repoting.
*/
xmlResetLastError();
input = xmlParserInputBufferCreateFilename(filename,
XML_CHAR_ENCODING_NONE);
if (input == NULL) {
const xmlError *error = xmlGetLastError();
if ((error != NULL) && (error->code == XML_ERR_NO_MEMORY)) {
lint->progresult = XMLLINT_ERR_MEM;
} else {
fprintf(errStream, "Unable to open %s\n", filename);
lint->progresult = XMLLINT_ERR_RDFILE;
}
return;
}
reader = xmlNewTextReader(input, filename);
if (reader == NULL) {
lint->progresult = XMLLINT_ERR_MEM;
xmlFreeParserInputBuffer(input);
return;
}
if (xmlTextReaderSetup(reader, NULL, NULL, NULL,
lint->options) < 0) {
lint->progresult = XMLLINT_ERR_MEM;
xmlFreeParserInputBuffer(input);
return;
}
}
}
if (reader == NULL) {
lint->progresult = XMLLINT_ERR_MEM;
return;
}
#ifdef LIBXML_PATTERN_ENABLED
if (lint->patternc != NULL) {
lint->patstream = xmlPatternGetStreamCtxt(lint->patternc);
@ -1713,106 +1754,102 @@ static void streamFile(xmllintState *lint, const char *filename) {
#endif
if (reader != NULL) {
xmlTextReaderSetResourceLoader(reader, xmllintResourceLoader, lint);
if (lint->maxAmpl > 0)
xmlTextReaderSetMaxAmplification(reader, lint->maxAmpl);
xmlTextReaderSetResourceLoader(reader, xmllintResourceLoader, lint);
if (lint->maxAmpl > 0)
xmlTextReaderSetMaxAmplification(reader, lint->maxAmpl);
#ifdef LIBXML_SCHEMAS_ENABLED
if (lint->relaxng != NULL) {
if ((lint->timing) && (lint->repeat == 1)) {
startTimer(lint);
}
ret = xmlTextReaderRelaxNGValidate(reader, lint->relaxng);
if (ret < 0) {
fprintf(errStream, "Relax-NG schema %s failed to compile\n",
lint->relaxng);
lint->progresult = XMLLINT_ERR_SCHEMACOMP;
lint->relaxng = NULL;
}
if ((lint->timing) && (lint->repeat == 1)) {
endTimer(lint, "Compiling the schemas");
}
}
if (lint->schema != NULL) {
if ((lint->timing) && (lint->repeat == 1)) {
startTimer(lint);
}
ret = xmlTextReaderSchemaValidate(reader, lint->schema);
if (ret < 0) {
fprintf(errStream, "XSD schema %s failed to compile\n",
lint->schema);
lint->progresult = XMLLINT_ERR_SCHEMACOMP;
lint->schema = NULL;
}
if ((lint->timing) && (lint->repeat == 1)) {
endTimer(lint, "Compiling the schemas");
}
}
if (lint->relaxng != NULL) {
if ((lint->timing) && (lint->repeat == 1)) {
startTimer(lint);
}
ret = xmlTextReaderRelaxNGValidate(reader, lint->relaxng);
if (ret < 0) {
fprintf(errStream, "Relax-NG schema %s failed to compile\n",
lint->relaxng);
lint->progresult = XMLLINT_ERR_SCHEMACOMP;
lint->relaxng = NULL;
}
if ((lint->timing) && (lint->repeat == 1)) {
endTimer(lint, "Compiling the schemas");
}
}
if (lint->schema != NULL) {
if ((lint->timing) && (lint->repeat == 1)) {
startTimer(lint);
}
ret = xmlTextReaderSchemaValidate(reader, lint->schema);
if (ret < 0) {
fprintf(errStream, "XSD schema %s failed to compile\n",
lint->schema);
lint->progresult = XMLLINT_ERR_SCHEMACOMP;
lint->schema = NULL;
}
if ((lint->timing) && (lint->repeat == 1)) {
endTimer(lint, "Compiling the schemas");
}
}
#endif
/*
* Process all nodes in sequence
*/
if ((lint->timing) && (lint->repeat == 1)) {
startTimer(lint);
}
ret = xmlTextReaderRead(reader);
while (ret == 1) {
if ((lint->debug)
/*
* Process all nodes in sequence
*/
if ((lint->timing) && (lint->repeat == 1)) {
startTimer(lint);
}
ret = xmlTextReaderRead(reader);
while (ret == 1) {
if ((lint->debug)
#ifdef LIBXML_PATTERN_ENABLED
|| (lint->patternc)
|| (lint->patternc)
#endif
)
processNode(lint, reader);
ret = xmlTextReaderRead(reader);
}
if ((lint->timing) && (lint->repeat == 1)) {
)
processNode(lint, reader);
ret = xmlTextReaderRead(reader);
}
if ((lint->timing) && (lint->repeat == 1)) {
#ifdef LIBXML_SCHEMAS_ENABLED
if (lint->relaxng != NULL)
endTimer(lint, "Parsing and validating");
else
if (lint->relaxng != NULL)
endTimer(lint, "Parsing and validating");
else
#endif
#ifdef LIBXML_VALID_ENABLED
if (lint->options & XML_PARSE_DTDVALID)
endTimer(lint, "Parsing and validating");
else
if (lint->options & XML_PARSE_DTDVALID)
endTimer(lint, "Parsing and validating");
else
#endif
endTimer(lint, "Parsing");
}
endTimer(lint, "Parsing");
}
#ifdef LIBXML_VALID_ENABLED
if (lint->options & XML_PARSE_DTDVALID) {
if (xmlTextReaderIsValid(reader) != 1) {
fprintf(errStream,
"Document %s does not validate\n", filename);
lint->progresult = XMLLINT_ERR_VALID;
}
}
if (lint->options & XML_PARSE_DTDVALID) {
if (xmlTextReaderIsValid(reader) != 1) {
fprintf(errStream,
"Document %s does not validate\n", filename);
lint->progresult = XMLLINT_ERR_VALID;
}
}
#endif /* LIBXML_VALID_ENABLED */
#ifdef LIBXML_SCHEMAS_ENABLED
if ((lint->relaxng != NULL) || (lint->schema != NULL)) {
if (xmlTextReaderIsValid(reader) != 1) {
fprintf(errStream, "%s fails to validate\n", filename);
lint->progresult = XMLLINT_ERR_VALID;
} else {
if (!lint->quiet) {
fprintf(errStream, "%s validates\n", filename);
}
}
}
if ((lint->relaxng != NULL) || (lint->schema != NULL)) {
if (xmlTextReaderIsValid(reader) != 1) {
fprintf(errStream, "%s fails to validate\n", filename);
lint->progresult = XMLLINT_ERR_VALID;
} else {
if (!lint->quiet) {
fprintf(errStream, "%s validates\n", filename);
}
}
}
#endif
/*
* Done, cleanup and status
*/
xmlFreeTextReader(reader);
if (ret != 0) {
fprintf(errStream, "%s : failed to parse\n", filename);
lint->progresult = XMLLINT_ERR_UNCLASS;
}
} else {
fprintf(errStream, "Unable to open %s\n", filename);
lint->progresult = XMLLINT_ERR_UNCLASS;
/*
* Done, cleanup and status
*/
xmlFreeTextReader(reader);
xmlFreeParserInputBuffer(input);
if (ret != 0) {
fprintf(errStream, "%s : failed to parse\n", filename);
lint->progresult = XMLLINT_ERR_UNCLASS;
}
#ifdef LIBXML_PATTERN_ENABLED
if (lint->patstream != NULL) {