From 51906190a1acba9a649e7d5dc0038a776ab61397 Mon Sep 17 00:00:00 2001 From: Kim Woelders Date: Thu, 29 Sep 2022 12:00:50 +0200 Subject: [PATCH] image: Don't munmap external memory When loading image from memory (imlib_load_image[_frame]_mem()) the memory was unintentionally munmapped after loading. This would cause trouble if loading multiple times from the same mmap'ed memory, but not from malloced memory as the munmap would then just fail silently. https://git.enlightenment.org/old/legacy-imlib2/issues/1 --- src/lib/image.c | 27 +++++++++++++++------------ test/test_load.cpp | 15 +++++++++------ 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/lib/image.c b/src/lib/image.c index 0ed53a7..4e54b9a 100644 --- a/src/lib/image.c +++ b/src/lib/image.c @@ -29,6 +29,7 @@ struct _ImlibImageFileInfo { off_t fsize; /* vvv Private vvv */ bool keep_fp; + bool keep_mem; /* ^^^ Private ^^^ */ }; @@ -97,7 +98,11 @@ __imlib_FileContextOpen(ImlibImageFileInfo * fi, FILE * fp, fi->keep_fp = true; fi->fp = fp; } - else if (!fdata) + else if (fdata) + { + fi->keep_mem = true; + } + else { fi->fp = fopen(fi->name, "rb"); if (!fi->fp) @@ -129,18 +134,16 @@ __imlib_FileContextOpen(ImlibImageFileInfo * fi, FILE * fp, static void __imlib_FileContextClose(ImlibImageFileInfo * fi) { - if (!fi->keep_fp) + if (fi->fdata && !fi->keep_mem) { - if (fi->fdata) - { - munmap((void *)fi->fdata, fi->fsize); - fi->fdata = NULL; - } - if (fi->fp) - { - fclose(fi->fp); - fi->fp = NULL; - } + munmap((void *)fi->fdata, fi->fsize); + fi->fdata = NULL; + } + + if (fi->fp && !fi->keep_fp) + { + fclose(fi->fp); + fi->fp = NULL; } } diff --git a/test/test_load.cpp b/test/test_load.cpp index f8fde9f..7e0740b 100644 --- a/test/test_load.cpp +++ b/test/test_load.cpp @@ -200,12 +200,15 @@ test_load(void) fdata = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0); ASSERT_TRUE(fdata != NULL); ASSERT_TRUE(fdata != MAP_FAILED); - D("Load mem %d '%s'\n", fd, fileo); - snprintf(fileo, sizeof(fileo), ".%s", pfxs[i]); - im = imlib_load_image_mem(pfxs[i], &err, fdata, st.st_size); - EXPECT_TRUE(im) << "Load mem: " << fileo; - if (im) - image_free(im); + for (int n = 0; n < 3; n++) + { + D("Load mem[%d] %d '%s'\n", n, fd, fileo); + snprintf(fileo, sizeof(fileo), ".%s", pfxs[i]); + im = imlib_load_image_mem(pfxs[i], &err, fdata, st.st_size); + EXPECT_TRUE(im) << "Load mem: " << fileo; + if (im) + image_free(im); + } munmap(fdata, st.st_size); err = close(fd); EXPECT_EQ(err, 0);