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

io: Fix reading from pipes like stdin on Windows

On Windows, lseek doesn't return an error on unseekable streams like
pipes.

Fixes #951.
This commit is contained in:
Nick Wellnhofer
2025-07-20 13:03:59 +02:00
parent 8f1cc9151e
commit c70d88f19a

38
xmlIO.c
View File

@@ -1188,6 +1188,32 @@ xmlIODefaultMatch(const char *filename ATTRIBUTE_UNUSED) {
return(1);
}
#if defined(LIBXML_LZMA_ENABLED) || defined(LIBXML_ZLIB_ENABLED)
#ifdef _WIN32
typedef __int64 xmlFileOffset;
#else
typedef off_t xmlFileOffset;
#endif
static xmlFileOffset
xmlSeek(int fd, int offset, int whence) {
#ifdef _WIN32
HANDLE h = (HANDLE) _get_osfhandle(fd);
/*
* Windows doesn't return an error on unseekable files like pipes.
*/
if (h != INVALID_HANDLE_VALUE && GetFileType(h) != FILE_TYPE_DISK)
return -1;
return _lseeki64(fd, offset, whence);
#else
return lseek(fd, offset, whence);
#endif
}
#endif /* defined(LIBXML_LZMA_ENABLED) || defined(LIBXML_ZLIB_ENABLED) */
/**
* Update the buffer to read from `fd`. Supports the XML_INPUT_UNZIP
* flag.
@@ -1208,9 +1234,9 @@ xmlInputFromFd(xmlParserInputBuffer *buf, int fd,
#ifdef LIBXML_LZMA_ENABLED
if (flags & XML_INPUT_UNZIP) {
xzFile xzStream;
off_t pos;
xmlFileOffset pos;
pos = lseek(fd, 0, SEEK_CUR);
pos = xmlSeek(fd, 0, SEEK_CUR);
copy = dup(fd);
if (copy == -1)
@@ -1226,7 +1252,7 @@ xmlInputFromFd(xmlParserInputBuffer *buf, int fd,
if ((compressed) ||
/* Try to rewind if not gzip compressed */
(pos < 0) ||
(lseek(fd, pos, SEEK_SET) < 0)) {
(xmlSeek(fd, pos, SEEK_SET) < 0)) {
/*
* If a file isn't seekable, we pipe uncompressed
* input through xzlib.
@@ -1247,9 +1273,9 @@ xmlInputFromFd(xmlParserInputBuffer *buf, int fd,
#ifdef LIBXML_ZLIB_ENABLED
if (flags & XML_INPUT_UNZIP) {
gzFile gzStream;
off_t pos;
xmlFileOffset pos;
pos = lseek(fd, 0, SEEK_CUR);
pos = xmlSeek(fd, 0, SEEK_CUR);
copy = dup(fd);
if (copy == -1)
@@ -1265,7 +1291,7 @@ xmlInputFromFd(xmlParserInputBuffer *buf, int fd,
if ((compressed) ||
/* Try to rewind if not gzip compressed */
(pos < 0) ||
(lseek(fd, pos, SEEK_SET) < 0)) {
(xmlSeek(fd, pos, SEEK_SET) < 0)) {
/*
* If a file isn't seekable, we pipe uncompressed
* input through zlib.