1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-10-23 01:52:48 +03:00

io: Pass error codes from xmlFileOpenReal to xmlNewInputFromFile

This allows to report the reason why opening a file failed to the parser
context and improve error messages. Now we can also remove the stat call
before opening a file.
This commit is contained in:
Nick Wellnhofer
2023-12-19 15:41:37 +01:00
parent b2dbcc432b
commit 7e511f35f1
14 changed files with 228 additions and 124 deletions

View File

@@ -5,13 +5,15 @@
#include <libxml/tree.h> #include <libxml/tree.h>
#include <libxml/xmlversion.h> #include <libxml/xmlversion.h>
XML_HIDDEN void XML_HIDDEN int
__xmlIOErr(int domain, int code, const char *extra); __xmlIOErr(int domain, int code, const char *extra);
XML_HIDDEN void XML_HIDDEN void
xmlLoaderErr(xmlParserCtxtPtr ctxt, const char *msg, xmlLoaderErr(xmlParserCtxtPtr ctxt, int code, const char *filename);
const char *filename) LIBXML_ATTR_FORMAT(2,0);
xmlParserInputBufferPtr XML_HIDDEN int
xmlParserInputBufferCreateFilenameSafe(const char *URI, xmlCharEncoding enc,
xmlParserInputBufferPtr *out);
XML_HIDDEN xmlParserInputBufferPtr
xmlParserInputBufferCreateString(const xmlChar *str); xmlParserInputBufferCreateString(const xmlChar *str);
#ifdef LIBXML_OUTPUT_ENABLED #ifdef LIBXML_OUTPUT_ENABLED

View File

@@ -1804,17 +1804,15 @@ xmlNewInputFromFile(xmlParserCtxtPtr ctxt, const char *filename) {
xmlParserInputPtr inputStream; xmlParserInputPtr inputStream;
char *directory = NULL; char *directory = NULL;
xmlChar *URI = NULL; xmlChar *URI = NULL;
int code;
if (ctxt == NULL) return(NULL); if ((ctxt == NULL) || (filename == NULL))
buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE); return(NULL);
code = xmlParserInputBufferCreateFilenameSafe(filename,
XML_CHAR_ENCODING_NONE, &buf);
if (buf == NULL) { if (buf == NULL) {
if (filename == NULL) xmlLoaderErr(ctxt, code, filename);
xmlLoaderErr(ctxt,
"failed to load external entity: NULL filename\n",
NULL);
else
xmlLoaderErr(ctxt, "failed to load external entity \"%s\"\n",
(const char *) filename);
return(NULL); return(NULL);
} }

View File

@@ -10,7 +10,7 @@ import libxml2
# Memory debug specific # Memory debug specific
libxml2.debugMemory(1) libxml2.debugMemory(1)
expect='--> I/O --> warning : --> failed to load external entity "missing.xml"\n' expect='--> I/O --> warning : --> failed to load "missing.xml": No such file or directory\n'
err="" err=""
def callback(ctx, str): def callback(ctx, str):
global err global err

View File

@@ -91,7 +91,7 @@ run_test(desc="Loading entity without custom callback",
exp_status="not loaded", exp_err=[ exp_status="not loaded", exp_err=[
(-1, "I/O "), (-1, "I/O "),
(-1, "warning : "), (-1, "warning : "),
(-1, "failed to load external entity \"py://strings/xml/sample.xml\"\n") (-1, "failed to load \"py://strings/xml/sample.xml\": No such file or directory\n")
]) ])
# Register handler and try to load the same entity # Register handler and try to load the same entity
@@ -99,7 +99,7 @@ libxml2.registerInputCallback(my_input_cb)
run_test(desc="Loading entity with custom callback", run_test(desc="Loading entity with custom callback",
docpath=startURL, catalog=None, docpath=startURL, catalog=None,
exp_status="loaded", exp_err=[ exp_status="loaded", exp_err=[
( 3, "Attempt to load network entity http://example.com/dtds/sample.dtd"), ( 3, 'failed to load "http://example.com/dtds/sample.dtd": Attempt to load network entity\n'),
( 4, "Entity 'sample.entity' not defined\n") ( 4, "Entity 'sample.entity' not defined\n")
]) ])
@@ -112,7 +112,7 @@ run_test(desc="Loading entity and unregistering callback",
docpath=startURL, catalog=catURL, docpath=startURL, catalog=catURL,
test_callback=lambda: libxml2.popInputCallbacks(), test_callback=lambda: libxml2.popInputCallbacks(),
exp_status="loaded", exp_err=[ exp_status="loaded", exp_err=[
( 3, "failed to load external entity \"py://strings/dtds/sample.dtd\"\n"), ( 3, "failed to load \"py://strings/dtds/sample.dtd\": No such file or directory\n"),
( 4, "Entity 'sample.entity' not defined\n") ( 4, "Entity 'sample.entity' not defined\n")
]) ])
@@ -122,7 +122,7 @@ run_test(desc="Retry loading document after unregistering callback",
exp_status="not loaded", exp_err=[ exp_status="not loaded", exp_err=[
(-1, "I/O "), (-1, "I/O "),
(-1, "warning : "), (-1, "warning : "),
(-1, "failed to load external entity \"py://strings/xml/sample.xml\"\n") (-1, "failed to load \"py://strings/xml/sample.xml\": No such file or directory\n")
]) ])
# But should be able to read standard I/O yet... # But should be able to read standard I/O yet...
@@ -142,7 +142,7 @@ run_test(desc="Loading using standard i/o after unregistering all callbacks",
exp_status="not loaded", exp_err=[ exp_status="not loaded", exp_err=[
(-1, "I/O "), (-1, "I/O "),
(-1, "warning : "), (-1, "warning : "),
(-1, "failed to load external entity \"tst.xml\"\n") (-1, "failed to load \"tst.xml\": No such file or directory\n")
]) ])
print("OK") print("OK")

View File

@@ -58,8 +58,8 @@ class TestCase(unittest.TestCase):
("dummy.xml",None,0), ("dummy.xml",None,0),
libxml2.treeError, libxml2.treeError,
domain=libxml2.XML_FROM_IO, domain=libxml2.XML_FROM_IO,
code=libxml2.XML_IO_LOAD_ERROR, code=libxml2.XML_IO_ENOENT,
message='failed to load external entity "dummy.xml"\n', message='failed to load "dummy.xml": No such file or directory\n',
level=libxml2.XML_ERR_WARNING, level=libxml2.XML_ERR_WARNING,
file=None, file=None,
line=0) line=0)

View File

@@ -1 +1 @@
I/O warning : failed to load external entity "test/XInclude/docs/something.xml" I/O warning : failed to load "test/XInclude/docs/something.xml": No such file or directory

View File

@@ -1,2 +1,2 @@
I/O warning : failed to load external entity "test/XInclude/docs/b.xml" I/O warning : failed to load "test/XInclude/docs/b.xml": No such file or directory
I/O warning : failed to load external entity "test/XInclude/docs/c.xml" I/O warning : failed to load "test/XInclude/docs/c.xml": No such file or directory

View File

@@ -1 +1 @@
I/O warning : failed to load external entity "test/XInclude/docs/c.xml" I/O warning : failed to load "test/XInclude/docs/c.xml": No such file or directory

View File

@@ -1,16 +1,16 @@
I/O warning : failed to load external entity "test/XInclude/docs/a01.xml" I/O warning : failed to load "test/XInclude/docs/a01.xml": No such file or directory
I/O warning : failed to load external entity "test/XInclude/docs/a02.xml" I/O warning : failed to load "test/XInclude/docs/a02.xml": No such file or directory
I/O warning : failed to load external entity "test/XInclude/docs/a03.xml" I/O warning : failed to load "test/XInclude/docs/a03.xml": No such file or directory
I/O warning : failed to load external entity "test/XInclude/docs/a04.xml" I/O warning : failed to load "test/XInclude/docs/a04.xml": No such file or directory
I/O warning : failed to load external entity "test/XInclude/docs/a05.xml" I/O warning : failed to load "test/XInclude/docs/a05.xml": No such file or directory
I/O warning : failed to load external entity "test/XInclude/docs/a06.xml" I/O warning : failed to load "test/XInclude/docs/a06.xml": No such file or directory
I/O warning : failed to load external entity "test/XInclude/docs/a07.xml" I/O warning : failed to load "test/XInclude/docs/a07.xml": No such file or directory
I/O warning : failed to load external entity "test/XInclude/docs/a08.xml" I/O warning : failed to load "test/XInclude/docs/a08.xml": No such file or directory
I/O warning : failed to load external entity "test/XInclude/docs/a09.xml" I/O warning : failed to load "test/XInclude/docs/a09.xml": No such file or directory
I/O warning : failed to load external entity "test/XInclude/docs/a10.xml" I/O warning : failed to load "test/XInclude/docs/a10.xml": No such file or directory
I/O warning : failed to load external entity "test/XInclude/docs/a11.xml" I/O warning : failed to load "test/XInclude/docs/a11.xml": No such file or directory
I/O warning : failed to load external entity "test/XInclude/docs/a12.xml" I/O warning : failed to load "test/XInclude/docs/a12.xml": No such file or directory
I/O warning : failed to load external entity "test/XInclude/docs/a13.xml" I/O warning : failed to load "test/XInclude/docs/a13.xml": No such file or directory
I/O warning : failed to load external entity "test/XInclude/docs/a14.xml" I/O warning : failed to load "test/XInclude/docs/a14.xml": No such file or directory
I/O warning : failed to load external entity "test/XInclude/docs/a15.xml" I/O warning : failed to load "test/XInclude/docs/a15.xml": No such file or directory
I/O warning : failed to load external entity "test/XInclude/docs/a16.xml" I/O warning : failed to load "test/XInclude/docs/a16.xml": No such file or directory

View File

@@ -1,2 +1,2 @@
I/O warning : failed to load external entity "test/XInclude/docs/b.xml" I/O warning : failed to load "test/XInclude/docs/b.xml": No such file or directory
I/O warning : failed to load external entity "test/XInclude/docs/c.xml" I/O warning : failed to load "test/XInclude/docs/c.xml": No such file or directory

View File

@@ -1 +1 @@
I/O warning : failed to load external entity "test/XInclude/without-reader/404.xml" I/O warning : failed to load "test/XInclude/without-reader/404.xml": No such file or directory

View File

@@ -1 +1 @@
I/O warning : failed to load external entity "test/XInclude/without-reader/b.xml" I/O warning : failed to load "test/XInclude/without-reader/b.xml": No such file or directory

View File

@@ -1 +1 @@
I/O warning : failed to load external entity "/etc/doesnotexist" I/O warning : failed to load "/etc/doesnotexist": No such file or directory

260
xmlIO.c
View File

@@ -228,7 +228,7 @@ xmlIOErrMemory(void)
* *
* Handle an I/O error * Handle an I/O error
*/ */
void int
__xmlIOErr(int domain, int code, const char *extra) __xmlIOErr(int domain, int code, const char *extra)
{ {
unsigned int idx; unsigned int idx;
@@ -399,8 +399,12 @@ __xmlIOErr(int domain, int code, const char *extra)
domain, code, XML_ERR_ERROR, NULL, 0, domain, code, XML_ERR_ERROR, NULL, 0,
extra, NULL, NULL, 0, 0, extra, NULL, NULL, 0, 0,
IOerr[idx], extra); IOerr[idx], extra);
if (res < 0) if (res < 0) {
xmlIOErrMemory(); xmlIOErrMemory();
return(XML_ERR_NO_MEMORY);
}
return(code);
} }
/** /**
@@ -410,33 +414,40 @@ __xmlIOErr(int domain, int code, const char *extra)
* *
* Handle an I/O error * Handle an I/O error
*/ */
static void static int
xmlIOErr(int code, const char *extra) xmlIOErr(int code, const char *extra)
{ {
__xmlIOErr(XML_FROM_IO, code, extra); return(__xmlIOErr(XML_FROM_IO, code, extra));
} }
/** /**
* __xmlLoaderErr: * xmlLoaderErr:
* @ctx: the parser context * @ctx: parser context
* @extra: extra information * @code: error code
* @filename: file name
* *
* Handle a resource access error * Handle a resource access error
*/ */
void void
xmlLoaderErr(xmlParserCtxtPtr ctxt, const char *msg, const char *filename) xmlLoaderErr(xmlParserCtxtPtr ctxt, int code, const char *filename)
{ {
xmlErrorLevel level; xmlErrorLevel level;
unsigned idx = 0;
if (ctxt->validate) if (ctxt->validate)
level = XML_ERR_ERROR; level = XML_ERR_ERROR;
else else
level = XML_ERR_WARNING; level = XML_ERR_WARNING;
xmlErrParser(ctxt, NULL, XML_FROM_IO, XML_IO_LOAD_ERROR, level, if (code >= XML_IO_UNKNOWN) {
(const xmlChar *) filename, NULL, NULL, 0, idx = code - XML_IO_UNKNOWN;
msg, filename); if (idx >= (sizeof(IOerr) / sizeof(IOerr[0])))
idx = 0;
}
xmlErrParser(ctxt, NULL, XML_FROM_IO, code, level,
(const xmlChar *) filename, NULL, NULL, 0,
"failed to load \"%s\": %s\n", filename, IOerr[idx]);
} }
/************************************************************************ /************************************************************************
@@ -736,25 +747,28 @@ xmlFileMatch (const char *filename ATTRIBUTE_UNUSED) {
} }
/** /**
* xmlFileOpen_real: * xmlFileOpenReal:
* @filename: the URI for matching * @filename: the URI for matching
* @out: pointer to resulting context
* *
* input from FILE *, supports compressed input * input from FILE *, supports compressed input
* if @filename is " " then the standard input is used * if @filename is "-" then the standard input is used
* *
* Returns an I/O context or NULL in case of error * Returns an I/O context or NULL in case of error
*/ */
static void * static int
xmlFileOpen_real (const char *filename) { xmlFileOpenReal(const char *filename, void **out) {
const char *path = filename; const char *path = filename;
FILE *fd; FILE *fd;
int ret = XML_ERR_OK;
*out = NULL;
if (filename == NULL) if (filename == NULL)
return(NULL); return(XML_ERR_ARGUMENT);
if (!strcmp(filename, "-")) { if (!strcmp(filename, "-")) {
fd = stdin; *out = stdin;
return((void *) fd); return(XML_ERR_OK);
} }
if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file://localhost/", 17)) { if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file://localhost/", 17)) {
@@ -778,45 +792,76 @@ xmlFileOpen_real (const char *filename) {
#endif #endif
} }
/* Do not check DDNAME on zOS ! */
#if !defined(__MVS__)
if (!xmlCheckFilename(path))
return(NULL);
#endif
#if defined(_WIN32) #if defined(_WIN32)
fd = xmlWrapOpenUtf8(path, 0); fd = xmlWrapOpenUtf8(path, 0);
#else #else
fd = fopen(path, "rb"); fd = fopen(path, "rb");
#endif /* WIN32 */ #endif /* WIN32 */
if (fd == NULL) xmlIOErr(0, path);
return((void *) fd); if (fd == NULL) {
/*
* Windows and possibly other platforms return EINVAL
* for invalid filenames.
*/
if ((errno == ENOENT) || (errno == EINVAL)) {
ret = XML_IO_ENOENT;
} else {
/*
* This error won't be forwarded to the parser context
* which will report it a second time.
*/
ret = xmlIOErr(0, path);
}
}
*out = fd;
return(ret);
}
/**
* xmlFileOpenSafe:
* @filename: the URI for matching
* @out: pointer to resulting context
*
* Wrapper around xmlFileOpen_real that try it with an unescaped
* version of @filename, if this fails fallback to @filename
*
* Returns an xmlParserErrors code.
*/
static int
xmlFileOpenSafe(const char *filename, void **out) {
char *unescaped;
int retval;
retval = xmlFileOpenReal(filename, out);
if (retval == XML_ERR_OK)
return(retval);
if (retval == XML_IO_ENOENT) {
unescaped = xmlURIUnescapeString(filename, 0, NULL);
if (unescaped == NULL)
return(XML_ERR_NO_MEMORY);
retval = xmlFileOpenReal(unescaped, out);
xmlFree(unescaped);
}
return retval;
} }
/** /**
* xmlFileOpen: * xmlFileOpen:
* @filename: the URI for matching * @filename: the URI for matching
* *
* Wrapper around xmlFileOpen_real that try it with an unescaped * Open a file.
* version of @filename, if this fails fallback to @filename
* *
* Returns a handler or NULL in case or failure * Returns an IO context or NULL in case or failure
*/ */
void * void *
xmlFileOpen (const char *filename) { xmlFileOpen(const char *filename) {
char *unescaped; void *context;
void *retval;
retval = xmlFileOpen_real(filename); xmlFileOpenSafe(filename, &context);
if (retval == NULL) { return(context);
unescaped = xmlURIUnescapeString(filename, 0, NULL);
if (unescaped != NULL) {
retval = xmlFileOpen_real(unescaped);
xmlFree(unescaped);
}
}
return retval;
} }
#ifdef LIBXML_OUTPUT_ENABLED #ifdef LIBXML_OUTPUT_ENABLED
@@ -2066,8 +2111,17 @@ xmlIODefaultMatch(const char *filename ATTRIBUTE_UNUSED) {
return(1); return(1);
} }
/**
* xmlInputDefaultOpen:
* @buf: input buffer to be filled
* @filename: filename or URI
*
* Returns an xmlParserErrors code.
*/
static int static int
xmlInputDefaultOpen(xmlParserInputBufferPtr buf, const char *filename) { xmlInputDefaultOpen(xmlParserInputBufferPtr buf, const char *filename) {
int ret;
#ifdef LIBXML_FTP_ENABLED #ifdef LIBXML_FTP_ENABLED
if (xmlIOFTPMatch(filename)) { if (xmlIOFTPMatch(filename)) {
buf->context = xmlIOFTPOpen(filename); buf->context = xmlIOFTPOpen(filename);
@@ -2140,13 +2194,15 @@ xmlInputDefaultOpen(xmlParserInputBufferPtr buf, const char *filename) {
#endif /* LIBXML_ZLIB_ENABLED */ #endif /* LIBXML_ZLIB_ENABLED */
if (xmlFileMatch(filename)) { if (xmlFileMatch(filename)) {
buf->context = xmlFileOpen(filename); ret = xmlFileOpenSafe(filename, &buf->context);
if (buf->context != NULL) { if (buf->context != NULL) {
buf->readcallback = xmlFileRead; buf->readcallback = xmlFileRead;
buf->closecallback = xmlFileClose; buf->closecallback = xmlFileClose;
return(XML_ERR_OK); return(XML_ERR_OK);
} }
if (ret != XML_IO_ENOENT)
return(ret);
} }
return(XML_IO_ENOENT); return(XML_IO_ENOENT);
@@ -2163,6 +2219,15 @@ xmlRegisterDefaultInputCallbacks(void) {
} }
#ifdef LIBXML_OUTPUT_ENABLED #ifdef LIBXML_OUTPUT_ENABLED
/**
* xmlOutputDefaultOpen:
* @buf: input buffer to be filled
* @filename: filename or URI
* @compression: compression level or 0
* @is_file_uri: whether filename is a file URI
*
* Returns an xmlParserErrors code.
*/
static int static int
xmlOutputDefaultOpen(xmlOutputBufferPtr buf, const char *filename, xmlOutputDefaultOpen(xmlOutputBufferPtr buf, const char *filename,
int compression, int is_file_uri) { int compression, int is_file_uri) {
@@ -2448,49 +2513,71 @@ xmlOutputBufferClose(xmlOutputBufferPtr out)
} }
#endif /* LIBXML_OUTPUT_ENABLED */ #endif /* LIBXML_OUTPUT_ENABLED */
xmlParserInputBufferPtr /**
__xmlParserInputBufferCreateFilename(const char *URI, xmlCharEncoding enc) { * xmlParserInputBufferCreateFilenameInt:
xmlParserInputBufferPtr ret; * @URI: the filename or URI
int i = 0; * @enc: encoding enum (deprecated)
* @out: pointer to resulting input buffer
*
* Returns an xmlParserErrors code.
*/
static int
xmlParserInputBufferCreateFilenameInt(const char *URI, xmlCharEncoding enc,
xmlParserInputBufferPtr *out) {
xmlParserInputBufferPtr buf;
int ret;
int i;
if (URI == NULL) return(NULL); *out = NULL;
if (URI == NULL)
return(XML_ERR_ARGUMENT);
/* /*
* Allocate the Input buffer front-end. * Allocate the Input buffer front-end.
*/ */
ret = xmlAllocParserInputBuffer(enc); buf = xmlAllocParserInputBuffer(enc);
if (ret == NULL) if (buf == NULL)
return(NULL); return(XML_ERR_NO_MEMORY);
/* /*
* Try to find one of the input accept method accepting that scheme * Try to find one of the input accept method accepting that scheme
* Go in reverse to give precedence to user defined handlers. * Go in reverse to give precedence to user defined handlers.
*/ */
ret = XML_IO_ENOENT;
for (i = xmlInputCallbackNr - 1; i >= 0; i--) { for (i = xmlInputCallbackNr - 1; i >= 0; i--) {
xmlInputCallback *cb = &xmlInputCallbackTable[i]; xmlInputCallback *cb = &xmlInputCallbackTable[i];
if (cb->matchcallback == xmlIODefaultMatch) { if (cb->matchcallback == xmlIODefaultMatch) {
int code = xmlInputDefaultOpen(ret, URI); ret = xmlInputDefaultOpen(buf, URI);
if (code == XML_ERR_OK) if ((ret == XML_ERR_OK) || (ret != XML_IO_ENOENT))
break; break;
/* TODO: Handle other errors */
} else if ((cb->matchcallback != NULL) && } else if ((cb->matchcallback != NULL) &&
(cb->matchcallback(URI) != 0)) { (cb->matchcallback(URI) != 0)) {
ret->context = cb->opencallback(URI); buf->context = cb->opencallback(URI);
if (ret->context != NULL) { if (buf->context != NULL) {
ret->readcallback = cb->readcallback; buf->readcallback = cb->readcallback;
ret->closecallback = cb->closecallback; buf->closecallback = cb->closecallback;
ret = XML_ERR_OK;
break; break;
} }
} }
} }
if (ret->context == NULL) { if (ret != XML_ERR_OK) {
xmlFreeParserInputBuffer(ret); xmlFreeParserInputBuffer(buf);
/* TODO: Return not found error */ *out = NULL;
return(NULL); return(ret);
} }
*out = buf;
return(ret);
}
xmlParserInputBufferPtr
__xmlParserInputBufferCreateFilename(const char *URI, xmlCharEncoding enc) {
xmlParserInputBufferPtr ret;
xmlParserInputBufferCreateFilenameInt(URI, enc, &ret);
return(ret); return(ret);
} }
@@ -2500,7 +2587,7 @@ __xmlParserInputBufferCreateFilename(const char *URI, xmlCharEncoding enc) {
* @enc: the charset encoding if known * @enc: the charset encoding if known
* *
* Create a buffered parser input for the progressive parsing of a file * Create a buffered parser input for the progressive parsing of a file
* If filename is "-' then we use stdin as the input. * If filename is "-" then we use stdin as the input.
* Automatic support for ZLIB/Compress compressed document is provided * Automatic support for ZLIB/Compress compressed document is provided
* by default if found at compile-time. * by default if found at compile-time.
* Do an encoding check if enc == XML_CHAR_ENCODING_NONE * Do an encoding check if enc == XML_CHAR_ENCODING_NONE
@@ -2509,10 +2596,32 @@ __xmlParserInputBufferCreateFilename(const char *URI, xmlCharEncoding enc) {
*/ */
xmlParserInputBufferPtr xmlParserInputBufferPtr
xmlParserInputBufferCreateFilename(const char *URI, xmlCharEncoding enc) { xmlParserInputBufferCreateFilename(const char *URI, xmlCharEncoding enc) {
if ((xmlParserInputBufferCreateFilenameValue)) { if (xmlParserInputBufferCreateFilenameValue != NULL)
return xmlParserInputBufferCreateFilenameValue(URI, enc); return(xmlParserInputBufferCreateFilenameValue(URI, enc));
}
return __xmlParserInputBufferCreateFilename(URI, enc); return(__xmlParserInputBufferCreateFilename(URI, enc));
}
/**
* xmlParserInputBufferCreateFilenameSafe:
* @URI: the filename or URI
* @enc: encoding enum (deprecated)
* @out: pointer to resulting input buffer
*
* Returns an xmlParserErrors code.
*/
int
xmlParserInputBufferCreateFilenameSafe(const char *URI, xmlCharEncoding enc,
xmlParserInputBufferPtr *out) {
if (xmlParserInputBufferCreateFilenameValue != NULL) {
*out = xmlParserInputBufferCreateFilenameValue(URI, enc);
if (*out == NULL)
return(XML_IO_ENOENT);
return(XML_ERR_OK);
}
return(xmlParserInputBufferCreateFilenameInt(URI, enc, out));
} }
#ifdef LIBXML_OUTPUT_ENABLED #ifdef LIBXML_OUTPUT_ENABLED
@@ -3723,10 +3832,9 @@ xmlCheckHTTPInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr ret) {
if (code >= 400) { if (code >= 400) {
/* fatal error */ /* fatal error */
if (ret->filename != NULL) if (ret->filename != NULL)
xmlLoaderErr(ctxt, "failed to load HTTP resource \"%s\"\n", xmlLoaderErr(ctxt, XML_IO_LOAD_ERROR, ret->filename);
(const char *) ret->filename);
else else
xmlLoaderErr(ctxt, "failed to load HTTP resource\n", NULL); xmlLoaderErr(ctxt, XML_IO_LOAD_ERROR, "<null>");
xmlFreeInputStream(ret); xmlFreeInputStream(ret);
ret = NULL; ret = NULL;
} else { } else {
@@ -3877,6 +3985,9 @@ xmlDefaultExternalEntityLoader(const char *URL, const char *ID,
xmlParserInputPtr ret = NULL; xmlParserInputPtr ret = NULL;
xmlChar *resource = NULL; xmlChar *resource = NULL;
if (URL == NULL)
return(NULL);
if ((ctxt != NULL) && (ctxt->options & XML_PARSE_NONET)) { if ((ctxt != NULL) && (ctxt->options & XML_PARSE_NONET)) {
int options = ctxt->options; int options = ctxt->options;
@@ -3892,13 +4003,6 @@ xmlDefaultExternalEntityLoader(const char *URL, const char *ID,
if (resource == NULL) if (resource == NULL)
resource = (xmlChar *) URL; resource = (xmlChar *) URL;
if (resource == NULL) {
if (ID == NULL)
ID = "NULL";
if (ctxt != NULL)
xmlLoaderErr(ctxt, "failed to load external entity \"%s\"\n", ID);
return (NULL);
}
ret = xmlNewInputFromFile(ctxt, (const char *) resource); ret = xmlNewInputFromFile(ctxt, (const char *) resource);
if ((resource != NULL) && (resource != (xmlChar *) URL)) if ((resource != NULL) && (resource != (xmlChar *) URL))
xmlFree(resource); xmlFree(resource);
@@ -3995,7 +4099,7 @@ xmlNoNetExternalEntityLoader(const char *URL, const char *ID,
if (resource != NULL) { if (resource != NULL) {
if ((!xmlStrncasecmp(BAD_CAST resource, BAD_CAST "ftp://", 6)) || if ((!xmlStrncasecmp(BAD_CAST resource, BAD_CAST "ftp://", 6)) ||
(!xmlStrncasecmp(BAD_CAST resource, BAD_CAST "http://", 7))) { (!xmlStrncasecmp(BAD_CAST resource, BAD_CAST "http://", 7))) {
xmlLoaderErr(ctxt, "Attempt to load network entity %s", xmlLoaderErr(ctxt, XML_IO_NETWORK_ATTEMPT,
(const char *) resource); (const char *) resource);
if (resource != (xmlChar *) URL) if (resource != (xmlChar *) URL)
xmlFree(resource); xmlFree(resource);