summaryrefslogtreecommitdiff
path: root/xmlIO.c
diff options
context:
space:
mode:
Diffstat (limited to 'xmlIO.c')
-rw-r--r--xmlIO.c494
1 files changed, 259 insertions, 235 deletions
diff --git a/xmlIO.c b/xmlIO.c
index 60e0a50..90db848 100644
--- a/xmlIO.c
+++ b/xmlIO.c
@@ -50,6 +50,12 @@
# endif
# define HAVE_STAT
# endif
+#else
+# ifdef HAVE__STAT
+# if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
+# define stat _stat
+# endif
+# endif
#endif
#ifdef HAVE_STAT
# ifndef S_ISDIR
@@ -193,7 +199,7 @@ static const char *IOerr[] = {
"unknown address familly", /* EAFNOSUPPORT */
};
-#if defined(WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
+#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
/**
* __xmlIOWin32UTF8ToWChar:
* @u8String: uft-8 string
@@ -203,26 +209,25 @@ static const char *IOerr[] = {
static wchar_t *
__xmlIOWin32UTF8ToWChar(const char *u8String)
{
- wchar_t *wString = NULL;
+ wchar_t *wString = NULL;
+
+ if (u8String) {
+ int wLen =
+ MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, u8String,
+ -1, NULL, 0);
+ if (wLen) {
+ wString = xmlMalloc(wLen * sizeof(wchar_t));
+ if (wString) {
+ if (MultiByteToWideChar
+ (CP_UTF8, 0, u8String, -1, wString, wLen) == 0) {
+ xmlFree(wString);
+ wString = NULL;
+ }
+ }
+ }
+ }
- if (u8String)
- {
- int wLen = MultiByteToWideChar(CP_UTF8,0,u8String,-1,NULL,0);
- if (wLen)
- {
- wString = malloc((wLen+1) * sizeof(wchar_t));
- if (wString)
- {
- if (MultiByteToWideChar(CP_UTF8,0,u8String,-1,wString,wLen+1) == 0)
- {
- free(wString);
- wString = NULL;
- }
- }
- }
- }
-
- return wString;
+ return wString;
}
#endif
@@ -572,6 +577,132 @@ xmlCleanupOutputCallbacks(void)
* *
************************************************************************/
+#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
+
+/**
+ * xmlWrapOpenUtf8:
+ * @path: the path in utf-8 encoding
+ * @mode: type of access (0 - read, 1 - write)
+ *
+ * function opens the file specified by @path
+ *
+ */
+static FILE*
+xmlWrapOpenUtf8(const char *path,int mode)
+{
+ FILE *fd = NULL;
+ wchar_t *wPath;
+
+ wPath = __xmlIOWin32UTF8ToWChar(path);
+ if(wPath)
+ {
+ fd = _wfopen(wPath, mode ? L"wb" : L"rb");
+ xmlFree(wPath);
+ }
+ /* maybe path in native encoding */
+ if(fd == NULL)
+ fd = fopen(path, mode ? "wb" : "rb");
+
+ return fd;
+}
+
+/**
+ * xmlWrapStatUtf8:
+ * @path: the path in utf-8 encoding
+ * @info: structure that stores results
+ *
+ * function obtains information about the file or directory
+ *
+ */
+static int
+xmlWrapStatUtf8(const char *path,struct stat *info)
+{
+#ifdef HAVE_STAT
+ int retval = -1;
+ wchar_t *wPath;
+
+ wPath = __xmlIOWin32UTF8ToWChar(path);
+ if (wPath)
+ {
+ retval = _wstat(wPath,info);
+ xmlFree(wPath);
+ }
+ /* maybe path in native encoding */
+ if(retval < 0)
+ retval = stat(path,info);
+ return retval;
+#else
+ return -1;
+#endif
+}
+
+/**
+ * xmlWrapOpenNative:
+ * @path: the path
+ * @mode: type of access (0 - read, 1 - write)
+ *
+ * function opens the file specified by @path
+ *
+ */
+static FILE*
+xmlWrapOpenNative(const char *path,int mode)
+{
+ return fopen(path,mode ? "wb" : "rb");
+}
+
+/**
+ * xmlWrapStatNative:
+ * @path: the path
+ * @info: structure that stores results
+ *
+ * function obtains information about the file or directory
+ *
+ */
+static int
+xmlWrapStatNative(const char *path,struct stat *info)
+{
+#ifdef HAVE_STAT
+ return stat(path,info);
+#else
+ return -1;
+#endif
+}
+
+typedef int (* xmlWrapStatFunc) (const char *f, struct stat *s);
+static xmlWrapStatFunc xmlWrapStat = xmlWrapStatNative;
+typedef FILE* (* xmlWrapOpenFunc)(const char *f,int mode);
+static xmlWrapOpenFunc xmlWrapOpen = xmlWrapOpenNative;
+
+/**
+ * xmlInitPlatformSpecificIo:
+ *
+ * Initialize platform specific features.
+ */
+static void
+xmlInitPlatformSpecificIo(void)
+{
+ static int xmlPlatformIoInitialized = 0;
+ OSVERSIONINFO osvi;
+
+ if(xmlPlatformIoInitialized)
+ return;
+
+ osvi.dwOSVersionInfoSize = sizeof(osvi);
+
+ if(GetVersionEx(&osvi) && (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)) {
+ xmlWrapStat = xmlWrapStatUtf8;
+ xmlWrapOpen = xmlWrapOpenUtf8;
+ } else {
+ xmlWrapStat = xmlWrapStatNative;
+ xmlWrapOpen = xmlWrapOpenNative;
+ }
+
+ xmlPlatformIoInitialized = 1;
+ return;
+}
+
+#endif
+
/**
* xmlCheckFilename:
* @path: the path to check
@@ -594,41 +725,20 @@ xmlCheckFilename (const char *path)
#endif
if (path == NULL)
return(0);
-
-#if defined(WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
- {
- int retval = 0;
-
- wchar_t *wPath = __xmlIOWin32UTF8ToWChar(path);
- if (wPath)
- {
- struct _stat stat_buffer;
-
- if (_wstat(wPath,&stat_buffer) == 0)
- {
- retval = 1;
-
- if (((stat_buffer.st_mode & S_IFDIR) == S_IFDIR))
- retval = 2;
- }
-
- free(wPath);
- }
- return retval;
- }
-#else
#ifdef HAVE_STAT
+#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
+ if (xmlWrapStat(path, &stat_buffer) == -1)
+ return 0;
+#else
if (stat(path, &stat_buffer) == -1)
return 0;
-
+#endif
#ifdef S_ISDIR
if (S_ISDIR(stat_buffer.st_mode))
return 2;
-#endif /* S_ISDIR */
+#endif
#endif /* HAVE_STAT */
-#endif /* WIN32 */
-
return 1;
}
@@ -750,19 +860,8 @@ xmlFileOpen_real (const char *filename) {
if (!xmlCheckFilename(path))
return(NULL);
-#if defined(WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
- {
- wchar_t *wPath = __xmlIOWin32UTF8ToWChar(path);
- if (wPath)
- {
- fd = _wfopen(wPath, L"rb");
- free(wPath);
- }
- else
- {
- fd = fopen(path, "rb");
- }
- }
+#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
+ fd = xmlWrapOpen(path, 0);
#else
fd = fopen(path, "r");
#endif /* WIN32 */
@@ -832,19 +931,8 @@ xmlFileOpenW (const char *filename) {
if (path == NULL)
return(NULL);
-#if defined(WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
- {
- wchar_t *wPath = __xmlIOWin32UTF8ToWChar(path);
- if (wPath)
- {
- fd = _wfopen(wPath, L"wb");
- free(wPath);
- }
- else
- {
- fd = fopen(path, "wb");
- }
- }
+#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
+ fd = xmlWrapOpen(path, 1);
#else
fd = fopen(path, "wb");
#endif /* WIN32 */
@@ -2018,11 +2106,14 @@ xmlRegisterOutputCallbacks(xmlOutputMatchCallback matchFunc,
* Registers the default compiled-in I/O handlers.
*/
void
-xmlRegisterDefaultInputCallbacks
-(void) {
+xmlRegisterDefaultInputCallbacks(void) {
if (xmlInputCallbackInitialized)
return;
+#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
+ xmlInitPlatformSpecificIo();
+#endif
+
xmlRegisterInputCallbacks(xmlFileMatch, xmlFileOpen,
xmlFileRead, xmlFileClose);
#ifdef HAVE_ZLIB_H
@@ -2049,11 +2140,14 @@ xmlRegisterDefaultInputCallbacks
* Registers the default compiled-in I/O handlers.
*/
void
-xmlRegisterDefaultOutputCallbacks
-(void) {
+xmlRegisterDefaultOutputCallbacks (void) {
if (xmlOutputCallbackInitialized)
return;
+#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
+ xmlInitPlatformSpecificIo();
+#endif
+
xmlRegisterOutputCallbacks(xmlFileMatch, xmlFileOpenW,
xmlFileWrite, xmlFileClose);
@@ -2368,7 +2462,8 @@ __xmlOutputBufferCreateFilename(const char *URI,
/*
* try to limit the damages of the URI unescaping code.
*/
- if (puri->scheme != NULL)
+ if ((puri->scheme == NULL) ||
+ (xmlStrEqual(BAD_CAST puri->scheme, BAD_CAST "file")))
unescaped = xmlURIUnescapeString(URI, 0, NULL);
xmlFreeURI(puri);
}
@@ -3499,10 +3594,7 @@ xmlCheckHTTPInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr ret) {
return(ret);
}
-static int xmlSysIDExists(const char *URL) {
-#ifdef HAVE_STAT
- int ret;
- struct stat info;
+static int xmlNoNetExists(const char *URL) {
const char *path;
if (URL == NULL)
@@ -3522,13 +3614,88 @@ static int xmlSysIDExists(const char *URL) {
#endif
} else
path = URL;
- ret = stat(path, &info);
- if (ret == 0)
- return(1);
-#endif
- return(0);
+
+ return xmlCheckFilename(path);
}
+#ifdef LIBXML_CATALOG_ENABLED
+
+/**
+ * xmlResolveResourceFromCatalog:
+ * @URL: the URL for the entity to load
+ * @ID: the System ID for the entity to load
+ * @ctxt: the context in which the entity is called or NULL
+ *
+ * Resolves the URL and ID against the appropriate catalog.
+ * This function is used by xmlDefaultExternalEntityLoader and
+ * xmlNoNetExternalEntityLoader.
+ *
+ * Returns a new allocated URL, or NULL.
+ */
+xmlChar *
+xmlResolveResourceFromCatalog(const char *URL, const char *ID,
+ xmlParserCtxtPtr ctxt) {
+ xmlChar *resource = NULL;
+ xmlCatalogAllow pref;
+
+ /*
+ * If the resource doesn't exists as a file,
+ * try to load it from the resource pointed in the catalogs
+ */
+ pref = xmlCatalogGetDefaults();
+
+ if ((pref != XML_CATA_ALLOW_NONE) && (!xmlNoNetExists(URL))) {
+ /*
+ * Do a local lookup
+ */
+ if ((ctxt != NULL) && (ctxt->catalogs != NULL) &&
+ ((pref == XML_CATA_ALLOW_ALL) ||
+ (pref == XML_CATA_ALLOW_DOCUMENT))) {
+ resource = xmlCatalogLocalResolve(ctxt->catalogs,
+ (const xmlChar *)ID,
+ (const xmlChar *)URL);
+ }
+ /*
+ * Try a global lookup
+ */
+ if ((resource == NULL) &&
+ ((pref == XML_CATA_ALLOW_ALL) ||
+ (pref == XML_CATA_ALLOW_GLOBAL))) {
+ resource = xmlCatalogResolve((const xmlChar *)ID,
+ (const xmlChar *)URL);
+ }
+ if ((resource == NULL) && (URL != NULL))
+ resource = xmlStrdup((const xmlChar *) URL);
+
+ /*
+ * TODO: do an URI lookup on the reference
+ */
+ if ((resource != NULL) && (!xmlNoNetExists((const char *)resource))) {
+ xmlChar *tmp = NULL;
+
+ if ((ctxt != NULL) && (ctxt->catalogs != NULL) &&
+ ((pref == XML_CATA_ALLOW_ALL) ||
+ (pref == XML_CATA_ALLOW_DOCUMENT))) {
+ tmp = xmlCatalogLocalResolveURI(ctxt->catalogs, resource);
+ }
+ if ((tmp == NULL) &&
+ ((pref == XML_CATA_ALLOW_ALL) ||
+ (pref == XML_CATA_ALLOW_GLOBAL))) {
+ tmp = xmlCatalogResolveURI(resource);
+ }
+
+ if (tmp != NULL) {
+ xmlFree(resource);
+ resource = tmp;
+ }
+ }
+ }
+
+ return resource;
+}
+
+#endif
+
/**
* xmlDefaultExternalEntityLoader:
* @URL: the URL for the entity to load
@@ -3546,15 +3713,10 @@ xmlDefaultExternalEntityLoader(const char *URL, const char *ID,
xmlParserInputPtr ret = NULL;
xmlChar *resource = NULL;
-#ifdef LIBXML_CATALOG_ENABLED
- xmlCatalogAllow pref;
-#endif
-
#ifdef DEBUG_EXTERNAL_ENTITIES
xmlGenericError(xmlGenericErrorContext,
"xmlDefaultExternalEntityLoader(%s, xxx)\n", URL);
#endif
-#ifdef LIBXML_CATALOG_ENABLED
if ((ctxt != NULL) && (ctxt->options & XML_PARSE_NONET)) {
int options = ctxt->options;
@@ -3563,60 +3725,8 @@ xmlDefaultExternalEntityLoader(const char *URL, const char *ID,
ctxt->options = options;
return(ret);
}
-
- /*
- * If the resource doesn't exists as a file,
- * try to load it from the resource pointed in the catalogs
- */
- pref = xmlCatalogGetDefaults();
-
- if ((pref != XML_CATA_ALLOW_NONE) && (!xmlSysIDExists(URL))) {
- /*
- * Do a local lookup
- */
- if ((ctxt != NULL) && (ctxt->catalogs != NULL) &&
- ((pref == XML_CATA_ALLOW_ALL) ||
- (pref == XML_CATA_ALLOW_DOCUMENT))) {
- resource = xmlCatalogLocalResolve(ctxt->catalogs,
- (const xmlChar *) ID,
- (const xmlChar *) URL);
- }
- /*
- * Try a global lookup
- */
- if ((resource == NULL) &&
- ((pref == XML_CATA_ALLOW_ALL) ||
- (pref == XML_CATA_ALLOW_GLOBAL))) {
- resource = xmlCatalogResolve((const xmlChar *) ID,
- (const xmlChar *) URL);
- }
- if ((resource == NULL) && (URL != NULL))
- resource = xmlStrdup((const xmlChar *) URL);
-
- /*
- * TODO: do an URI lookup on the reference
- */
- if ((resource != NULL)
- && (!xmlSysIDExists((const char *) resource))) {
- xmlChar *tmp = NULL;
-
- if ((ctxt != NULL) && (ctxt->catalogs != NULL) &&
- ((pref == XML_CATA_ALLOW_ALL) ||
- (pref == XML_CATA_ALLOW_DOCUMENT))) {
- tmp = xmlCatalogLocalResolveURI(ctxt->catalogs, resource);
- }
- if ((tmp == NULL) &&
- ((pref == XML_CATA_ALLOW_ALL) ||
- (pref == XML_CATA_ALLOW_GLOBAL))) {
- tmp = xmlCatalogResolveURI(resource);
- }
-
- if (tmp != NULL) {
- xmlFree(resource);
- resource = tmp;
- }
- }
- }
+#ifdef LIBXML_CATALOG_ENABLED
+ resource = xmlResolveResourceFromCatalog(URL, ID, ctxt);
#endif
if (resource == NULL)
@@ -3674,7 +3784,7 @@ xmlGetExternalEntityLoader(void) {
xmlParserInputPtr
xmlLoadExternalEntity(const char *URL, const char *ID,
xmlParserCtxtPtr ctxt) {
- if ((URL != NULL) && (xmlSysIDExists(URL) == 0)) {
+ if ((URL != NULL) && (xmlNoNetExists(URL) == 0)) {
char *canonicFilename;
xmlParserInputPtr ret;
@@ -3697,40 +3807,6 @@ xmlLoadExternalEntity(const char *URL, const char *ID,
* *
************************************************************************/
-#ifdef LIBXML_CATALOG_ENABLED
-static int
-xmlNoNetExists(const char *URL)
-{
-#ifdef HAVE_STAT
- int ret;
- struct stat info;
- const char *path;
-
- if (URL == NULL)
- return (0);
-
- if (!xmlStrncasecmp(BAD_CAST URL, BAD_CAST "file://localhost/", 17))
-#if defined (_WIN32) || defined (__DJGPP__) && !defined(__CYGWIN__)
- path = &URL[17];
-#else
- path = &URL[16];
-#endif
- else if (!xmlStrncasecmp(BAD_CAST URL, BAD_CAST "file:///", 8)) {
-#if defined (_WIN32) || defined (__DJGPP__) && !defined(__CYGWIN__)
- path = &URL[8];
-#else
- path = &URL[7];
-#endif
- } else
- path = URL;
- ret = stat(path, &info);
- if (ret == 0)
- return (1);
-#endif
- return (0);
-}
-#endif
-
/**
* xmlNoNetExternalEntityLoader:
* @URL: the URL for the entity to load
@@ -3749,61 +3825,9 @@ xmlNoNetExternalEntityLoader(const char *URL, const char *ID,
xmlChar *resource = NULL;
#ifdef LIBXML_CATALOG_ENABLED
- xmlCatalogAllow pref;
-
- /*
- * If the resource doesn't exists as a file,
- * try to load it from the resource pointed in the catalogs
- */
- pref = xmlCatalogGetDefaults();
-
- if ((pref != XML_CATA_ALLOW_NONE) && (!xmlNoNetExists(URL))) {
- /*
- * Do a local lookup
- */
- if ((ctxt != NULL) && (ctxt->catalogs != NULL) &&
- ((pref == XML_CATA_ALLOW_ALL) ||
- (pref == XML_CATA_ALLOW_DOCUMENT))) {
- resource = xmlCatalogLocalResolve(ctxt->catalogs,
- (const xmlChar *)ID,
- (const xmlChar *)URL);
- }
- /*
- * Try a global lookup
- */
- if ((resource == NULL) &&
- ((pref == XML_CATA_ALLOW_ALL) ||
- (pref == XML_CATA_ALLOW_GLOBAL))) {
- resource = xmlCatalogResolve((const xmlChar *)ID,
- (const xmlChar *)URL);
- }
- if ((resource == NULL) && (URL != NULL))
- resource = xmlStrdup((const xmlChar *) URL);
-
- /*
- * TODO: do an URI lookup on the reference
- */
- if ((resource != NULL) && (!xmlNoNetExists((const char *)resource))) {
- xmlChar *tmp = NULL;
-
- if ((ctxt != NULL) && (ctxt->catalogs != NULL) &&
- ((pref == XML_CATA_ALLOW_ALL) ||
- (pref == XML_CATA_ALLOW_DOCUMENT))) {
- tmp = xmlCatalogLocalResolveURI(ctxt->catalogs, resource);
- }
- if ((tmp == NULL) &&
- ((pref == XML_CATA_ALLOW_ALL) ||
- (pref == XML_CATA_ALLOW_GLOBAL))) {
- tmp = xmlCatalogResolveURI(resource);
- }
-
- if (tmp != NULL) {
- xmlFree(resource);
- resource = tmp;
- }
- }
- }
+ resource = xmlResolveResourceFromCatalog(URL, ID, ctxt);
#endif
+
if (resource == NULL)
resource = (xmlChar *) URL;