io: Don't cast file descriptors to pointers

This doesn't work if open() returns 0 which is rare but can happen. Wrap
the fd in a context struct.

Fixes #835.
This commit is contained in:
Nick Wellnhofer 2025-01-03 19:49:37 +01:00
parent 71c37a565d
commit 41c10c0cec

66
xmlIO.c
View File

@ -438,6 +438,10 @@ xmlConvertUriToPath(const char *uri, char **out) {
return(0);
}
typedef struct {
int fd;
} xmlFdIOCtxt;
/**
* xmlFdOpen:
* @filename: the URI for matching
@ -517,7 +521,8 @@ xmlFdOpen(const char *filename, int write, int *out) {
*/
static int
xmlFdRead(void *context, char *buffer, int len) {
int fd = (int) (ptrdiff_t) context;
xmlFdIOCtxt *fdctxt = context;
int fd = fdctxt->fd;
int ret = 0;
int bytes;
@ -555,7 +560,8 @@ xmlFdRead(void *context, char *buffer, int len) {
*/
static int
xmlFdWrite(void *context, const char *buffer, int len) {
int fd = (int) (ptrdiff_t) context;
xmlFdIOCtxt *fdctxt = context;
int fd = fdctxt->fd;
int ret = 0;
int bytes;
@ -572,6 +578,12 @@ xmlFdWrite(void *context, const char *buffer, int len) {
}
#endif /* LIBXML_OUTPUT_ENABLED */
static int
xmlFdFree(void *context) {
xmlFree(context);
return(XML_ERR_OK);
}
/**
* xmlFdClose:
* @context: the I/O context
@ -582,9 +594,14 @@ xmlFdWrite(void *context, const char *buffer, int len) {
*/
static int
xmlFdClose (void * context) {
xmlFdIOCtxt *fdctxt = context;
int fd = fdctxt->fd;
int ret;
ret = close((int) (ptrdiff_t) context);
ret = close(fd);
xmlFree(fdctxt);
if (ret < 0)
return(xmlIOErr(errno));
@ -1031,6 +1048,7 @@ xmlIODefaultMatch(const char *filename ATTRIBUTE_UNUSED) {
static int
xmlInputDefaultOpen(xmlParserInputBufferPtr buf, const char *filename,
int flags) {
xmlFdIOCtxt *fdctxt;
int ret;
int fd;
@ -1125,7 +1143,14 @@ xmlInputDefaultOpen(xmlParserInputBufferPtr buf, const char *filename,
if (ret != XML_ERR_OK)
return(ret);
buf->context = (void *) (ptrdiff_t) fd;
fdctxt = xmlMalloc(sizeof(*fdctxt));
if (fdctxt == NULL) {
close(fd);
return(XML_ERR_NO_MEMORY);
}
fdctxt->fd = fd;
buf->context = fdctxt;
buf->readcallback = xmlFdRead;
buf->closecallback = xmlFdClose;
return(XML_ERR_OK);
@ -1144,6 +1169,7 @@ xmlInputDefaultOpen(xmlParserInputBufferPtr buf, const char *filename,
static int
xmlOutputDefaultOpen(xmlOutputBufferPtr buf, const char *filename,
int compression) {
xmlFdIOCtxt *fdctxt;
int fd;
(void) compression;
@ -1182,7 +1208,14 @@ xmlOutputDefaultOpen(xmlOutputBufferPtr buf, const char *filename,
}
#endif /* LIBXML_ZLIB_ENABLED */
buf->context = (void *) (ptrdiff_t) fd;
fdctxt = xmlMalloc(sizeof(*fdctxt));
if (fdctxt == NULL) {
close(fd);
return(XML_ERR_NO_MEMORY);
}
fdctxt->fd = fd;
buf->context = fdctxt;
buf->writecallback = xmlFdWrite;
buf->closecallback = xmlFdClose;
return(XML_ERR_OK);
@ -1722,8 +1755,17 @@ xmlParserInputBufferCreateFd(int fd, xmlCharEncoding enc) {
ret = xmlAllocParserInputBuffer(enc);
if (ret != NULL) {
ret->context = (void *) (ptrdiff_t) fd;
xmlFdIOCtxt *fdctxt;
fdctxt = xmlMalloc(sizeof(*fdctxt));
if (fdctxt == NULL) {
return(NULL);
}
fdctxt->fd = fd;
ret->context = fdctxt;
ret->readcallback = xmlFdRead;
ret->closecallback = xmlFdFree;
}
return(ret);
@ -1927,9 +1969,17 @@ xmlOutputBufferCreateFd(int fd, xmlCharEncodingHandlerPtr encoder) {
ret = xmlAllocOutputBuffer(encoder);
if (ret != NULL) {
ret->context = (void *) (ptrdiff_t) fd;
xmlFdIOCtxt *fdctxt;
fdctxt = xmlMalloc(sizeof(*fdctxt));
if (fdctxt == NULL) {
return(NULL);
}
fdctxt->fd = fd;
ret->context = fdctxt;
ret->writecallback = xmlFdWrite;
ret->closecallback = NULL;
ret->closecallback = xmlFdFree;
}
return(ret);