From f02661879ff0efefc6751d927c2e721e64ad79f0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bert=20M=C3=BCnnich?= <ber.t@posteo.de>
Date: Thu, 23 Nov 2017 14:35:32 +0100
Subject: [PATCH] Reject text files resembling TGA images

Fixes issue #295

The imlib2 TGA loader returns an imlib image handle without any actual data
when given a text file like this:

    T
    Content-Type: application/javascript
    Content-Length: 3836
    Last-Modified: Wed, 23 Sep 2015 12:25:47 GMT
    Etag: "56029a4b-efc"
    Expires: Sat, 20 Aug 2016 15:14:33 GMT
    Cache-Control: max-age=604800, public
    Accept-Ranges: bytes

Fortunately, `imlib_image_get_data()` returns NULL in this case, so that we can
use it as an additional check when opening files.
---
 Makefile |  2 +-
 image.c  | 32 +++++++++++++++++++++++---------
 thumbs.c | 10 ++--------
 3 files changed, 26 insertions(+), 18 deletions(-)

diff --git a/Makefile b/Makefile
index 6113957..6c26d3c 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-VERSION = 24
+VERSION = git-20171123
 
 srcdir = .
 VPATH = $(srcdir)
diff --git a/image.c b/image.c
index 75dc346..6803846 100644
--- a/image.c
+++ b/image.c
@@ -293,21 +293,35 @@ bool img_load_gif(img_t *img, const fileinfo_t *file)
 }
 #endif /* HAVE_GIFLIB */
 
+Imlib_Image img_open(const fileinfo_t *file)
+{
+	struct stat st;
+	Imlib_Image im = NULL;
+
+	if (access(file->path, R_OK) == 0 &&
+	    stat(file->path, &st) == 0 && S_ISREG(st.st_mode))
+	{
+		im = imlib_load_image(file->path);
+		if (im != NULL) {
+			imlib_context_set_image(im);
+			if (imlib_image_get_data_for_reading_only() == NULL) {
+				imlib_free_image();
+				im = NULL;
+			}
+		}
+	}
+	if (im == NULL && (file->flags & FF_WARN))
+		error(0, 0, "%s: Error opening image", file->name);
+	return im;
+}
+
 bool img_load(img_t *img, const fileinfo_t *file)
 {
 	const char *fmt;
-	struct stat st;
 
-	if (access(file->path, R_OK) == -1 ||
-	    stat(file->path, &st) == -1 || !S_ISREG(st.st_mode) ||
-	    (img->im = imlib_load_image(file->path)) == NULL)
-	{
-		if (file->flags & FF_WARN)
-			error(0, 0, "%s: Error opening image", file->name);
+	if ((img->im = img_open(file)) == NULL)
 		return false;
-	}
 
-	imlib_context_set_image(img->im);
 	imlib_image_set_changes_on_disk();
 
 #if HAVE_LIBEXIF
diff --git a/thumbs.c b/thumbs.c
index a99c764..37be29f 100644
--- a/thumbs.c
+++ b/thumbs.c
@@ -32,6 +32,7 @@
 #include <libexif/exif-data.h>
 void exif_auto_orientate(const fileinfo_t*);
 #endif
+Imlib_Image img_open(const fileinfo_t*);
 
 static char *cache_dir;
 
@@ -237,7 +238,6 @@ bool tns_load(tns_t *tns, int n, bool force, bool cache_only)
 	char *cfile;
 	thumb_t *t;
 	fileinfo_t *file;
-	struct stat st;
 	Imlib_Image im = NULL;
 
 	if (n < 0 || n >= *tns->cnt)
@@ -331,14 +331,8 @@ bool tns_load(tns_t *tns, int n, bool force, bool cache_only)
 	}
 
 	if (im == NULL) {
-		if (access(file->path, R_OK) == -1 ||
-		    stat(file->path, &st) == -1 || !S_ISREG(st.st_mode) ||
-		    (im = imlib_load_image(file->path)) == NULL)
-		{
-			if (file->flags & FF_WARN)
-				error(0, 0, "%s: Error opening image", file->name);
+		if ((im = img_open(file)) == NULL)
 			return false;
-		}
 	}
 	imlib_context_set_image(im);