This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch master
in repository legacy-imlib2.

View the commit online.

commit aec432b3ce2ea63bb3f28884988edede1d67659a
Author: Kim Woelders <k...@woelders.dk>
AuthorDate: Sun Jun 25 10:02:11 2023 +0200

    image: Fix potentially using incorrect file size
    
    During load from file we would do stat(file), then fopen(file),
    and assume the stat'ed size corresponds to the fopen'ed file.
    However, the file may be changed between stat() and fopen(), which may
    cause trouble.
    This should now be fixed by always using fstat() on the opened file
    descriptor.
---
 src/lib/file.c  | 15 ++++++++++++++-
 src/lib/file.h  |  3 ++-
 src/lib/image.c | 36 ++++++++++++++++++------------------
 3 files changed, 34 insertions(+), 20 deletions(-)

diff --git a/src/lib/file.c b/src/lib/file.c
index 32e233a..1e366ea 100644
--- a/src/lib/file.c
+++ b/src/lib/file.c
@@ -324,7 +324,7 @@ __imlib_ItemInList(char **list, int size, char *item)
 #include <errno.h>
 
 FILE               *
-__imlib_FileOpen(const char *path, const char *mode)
+__imlib_FileOpen(const char *path, const char *mode, struct stat *st)
 {
    FILE               *fp;
 
@@ -337,5 +337,18 @@ __imlib_FileOpen(const char *path, const char *mode)
            break;
      }
 
+   /* Only stat if all is good and we want to read */
+   if (!fp || !st)
+      goto done;
+   if (mode[0] == 'w')
+      goto done;
+
+   if (fstat(fileno(fp), st) < 0)
+     {
+        fclose(fp);
+        fp = NULL;
+     }
+
+ done:
    return fp;
 }
diff --git a/src/lib/file.h b/src/lib/file.h
index 013ddc2..44abf11 100644
--- a/src/lib/file.h
+++ b/src/lib/file.h
@@ -49,6 +49,7 @@ char              **__imlib_ModulesList(char **path, int *num_ret);
 char               *__imlib_ModuleFind(char **path, const char *name);
 
 #include <stdio.h>
-FILE               *__imlib_FileOpen(const char *path, const char *mode);
+FILE               *__imlib_FileOpen(const char *path, const char *mode,
+                                     struct stat *st);
 
 #endif
diff --git a/src/lib/image.c b/src/lib/image.c
index 9e4ad7c..7c38f47 100644
--- a/src/lib/image.c
+++ b/src/lib/image.c
@@ -97,27 +97,22 @@ __imlib_FileContextOpen(ImlibImageFileInfo * fi, FILE * fp,
      {
         fi->keep_fp = true;
         fi->fp = fp;
+        /* fsize must be given */
      }
    else if (fdata)
      {
         fi->keep_mem = true;
+        /* fsize must be given */
      }
    else
      {
-        fi->fp = __imlib_FileOpen(fi->name, "rb");
+        fi->fp = __imlib_FileOpen(fi->name, "rb", &st);
         if (!fi->fp)
            return -1;
+        fsize = st.st_size;
      }
 
-   if (fi->fsize == 0)
-     {
-        if (fsize == 0)
-          {
-             __imlib_FileStat(fi->name, &st);
-             fsize = st.st_size;
-          }
-        fi->fsize = fsize;
-     }
+   fi->fsize = fsize;
 
    if (!fdata)
      {
@@ -485,6 +480,7 @@ __imlib_LoadImage(const char *file, ImlibLoadArgs * ila)
    int                 err, loader_ret;
    ImlibLoaderCtx      ilc;
    struct stat         st;
+   FILE               *fp;
    char               *im_file, *im_key;
 
    if (!file || file[0] == '\0')
@@ -529,6 +525,7 @@ __imlib_LoadImage(const char *file, ImlibLoadArgs * ila)
           }
      }
 
+   fp = ila->fp;
    im_file = im_key = NULL;
    if (ila->fdata)
      {
@@ -536,29 +533,30 @@ __imlib_LoadImage(const char *file, ImlibLoadArgs * ila)
         st.st_size = ila->fsize;
         st.st_mtime = st.st_ctime = 0;
      }
-   else if (ila->fp)
+   else if (fp)
      {
-        err = fstat(fileno(ila->fp), &st);
+        err = fstat(fileno(fp), &st);
      }
    else
      {
-        err = __imlib_FileStat(file, &st);
-        if (err)
+        fp = __imlib_FileOpen(file, "rb", &st);
+        if (!fp)
           {
              im_key = __imlib_FileKey(file);
              if (im_key)
                {
                   im_file = __imlib_FileRealFile(file);
-                  err = __imlib_FileStat(im_file, &st);
+                  fp = __imlib_FileOpen(im_file, "rb", &st);
                }
           }
+        err = fp == NULL;
      }
 
    if (err)
       err = errno;
    else if (st.st_size == 0)
       err = IMLIB_ERR_BAD_IMAGE;
-   else if (!ila->fdata && __imlib_StatIsDir(&st))
+   else if (fp && __imlib_StatIsDir(&st))
       err = EISDIR;
 
    if (err)
@@ -577,13 +575,15 @@ __imlib_LoadImage(const char *file, ImlibLoadArgs * ila)
    im->frame = ila->frame;
 
    if (__imlib_ImageFileContextPush(im, im_file ? im_file : im->file) ||
-       __imlib_FileContextOpen(im->fi, ila->fp, ila->fdata, st.st_size))
+       __imlib_FileContextOpen(im->fi, fp, ila->fdata, st.st_size))
      {
         ila->err = errno;
         __imlib_ConsumeImage(im);
         return NULL;
      }
 
+   im->fi->keep_fp = ila->fp != NULL;
+
    im->moddate = __imlib_StatModDate(&st);
 
    im->data_memory_func = imlib_context_get_image_data_memory_function();
@@ -885,7 +885,7 @@ __imlib_SaveImage(ImlibImage * im, const char *file, ImlibLoadArgs * ila)
 
    if (!fp)
      {
-        fp = __imlib_FileOpen(file, "wb");
+        fp = __imlib_FileOpen(file, "wb", NULL);
         if (!fp)
           {
              ila->err = errno;

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to