From bcefcdae255b5377d7cb12d2c2c6e28f96724e0b Mon Sep 17 00:00:00 2001 From: Matthias Melcher Date: Fri, 24 Apr 2026 19:24:09 +0200 Subject: [PATCH] Fix Fl_ICO_Image reading from memory block, #1420 --- src/Fl_ICO_Image.cxx | 11 ++++++++++- src/Fl_Image_Reader.h | 19 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/Fl_ICO_Image.cxx b/src/Fl_ICO_Image.cxx index 9de71737b..3abb90c8b 100644 --- a/src/Fl_ICO_Image.cxx +++ b/src/Fl_ICO_Image.cxx @@ -153,7 +153,16 @@ void Fl_ICO_Image::load_ico_(Fl_Image_Reader &rdr, int id) b[4]=='\r' && b[5]=='\n' && b[6]==0x1A && b[7]=='\n') { #if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ) - Fl_PNG_Image *png = new Fl_PNG_Image(rdr.name(), icondirentry_[pickedID].dwImageOffset); + Fl_PNG_Image *png; + if (rdr.is_data()) { + size_t offset = icondirentry_[pickedID].dwImageOffset; + size_t size = rdr.data_size(); + if (size) size -= offset; + // `size` points at the end of the .ico data. The PNG may end before that. + png = new Fl_PNG_Image(rdr.name(), rdr.data_start()+offset, size); + } else { + png = new Fl_PNG_Image(rdr.name(), icondirentry_[pickedID].dwImageOffset); + } int loaded = png ? png->fail() : ERR_FILE_ACCESS; if (loaded < 0) { diff --git a/src/Fl_Image_Reader.h b/src/Fl_Image_Reader.h index 4a20d6602..113766ba8 100644 --- a/src/Fl_Image_Reader.h +++ b/src/Fl_Image_Reader.h @@ -83,6 +83,25 @@ public: // skip a given number of bytes void skip(unsigned int n) { seek((unsigned int)tell() + n); } + // return 1 if we are reading from a file, 0 otherwise + char is_file() const { return is_file_; } + + // return 1 if we are reading from a block of memory, 0 otherwise + char is_data() const { return is_data_; } + + // return the start address of the data block if reading from memory, otherwise nullptr + const unsigned char *data_start() const { return start_; } + + // return the size of the data block if reading from memoryand the size of + // the block is known, otherwise 0 + size_t data_size() const { + if (is_data_ && end_ && end_ != (const unsigned char *)(-1L)) { + return (size_t)(end_ - start_); + } else { + return 0; + } + } + private: // open() sets this if we read from a file char is_file_;