From 565b8923affdc0851d85eafe63a048a58bf1a60b Mon Sep 17 00:00:00 2001
From: Even Rouault <[EMAIL REDACTED]>
Date: Tue, 13 Dec 2022 15:15:18 +0100
Subject: [PATCH] Add tests for IFD loop detection
---
test/CMakeLists.txt | 6 +
test/Makefile.am | 8 +-
test/images/test_ifd_loop_to_first.tif | Bin 0 -> 312 bytes
test/images/test_ifd_loop_to_self.tif | Bin 0 -> 558 bytes
test/images/test_two_ifds.tif | Bin 0 -> 312 bytes
test/test_ifd_loop_detection.c | 179 +++++++++++++++++++++++++
6 files changed, 192 insertions(+), 1 deletion(-)
create mode 100644 test/images/test_ifd_loop_to_first.tif
create mode 100644 test/images/test_ifd_loop_to_self.tif
create mode 100644 test/images/test_two_ifds.tif
create mode 100644 test/test_ifd_loop_detection.c
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 742aba5b..907aed8f 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -185,6 +185,12 @@ target_sources(test_append_to_strip PRIVATE test_append_to_strip.c)
target_link_libraries(test_append_to_strip PRIVATE tiff tiff_port)
list(APPEND simple_tests test_append_to_strip)
+add_executable(test_ifd_loop_detection ../placeholder.h)
+target_sources(test_ifd_loop_detection PRIVATE test_ifd_loop_detection.c)
+target_link_libraries(test_ifd_loop_detection PRIVATE tiff tiff_port)
+target_compile_definitions(test_ifd_loop_detection PRIVATE SOURCE_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}\")
+list(APPEND simple_tests test_ifd_loop_detection)
+
if(WEBP_SUPPORT AND EMSCRIPTEN)
# Emscripten is pretty finnicky about linker flags.
# It needs --shared-memory if and only if atomics or bulk-memory is used.
diff --git a/test/Makefile.am b/test/Makefile.am
index f7c2477e..4ba5e07c 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -76,7 +76,7 @@ if TIFF_TESTS
check_PROGRAMS = \
ascii_tag long_tag short_tag strip_rw rewrite custom_dir custom_dir_EXIF_231 \
defer_strile_loading defer_strile_writing test_directory test_open_options \
- test_append_to_strip testtypes test_signed_tags $(JPEG_DEPENDENT_CHECK_PROG) $(STATIC_CHECK_PROGS)
+ test_append_to_strip test_ifd_loop_detection testtypes test_signed_tags $(JPEG_DEPENDENT_CHECK_PROG) $(STATIC_CHECK_PROGS)
endif
# Test scripts to execute
@@ -210,6 +210,9 @@ IMAGES_EXTRA_DIST = \
images/test_float64_predictor2_le_lzw.tif \
images/test_float64_predictor2_be_lzw.tif \
images/tiff_with_subifd_chain.tif \
+ images/test_ifd_loop_to_self.tif \
+ images/test_ifd_loop_to_first.tif \
+ images/test_two_ifds.tif \
$(PNMIMAGES) \
$(TIFFIMAGES)
@@ -250,6 +253,9 @@ test_open_options_SOURCES = test_open_options.c
test_open_options_LDADD = $(LIBTIFF)
test_append_to_strip_SOURCES = test_append_to_strip.c
test_append_to_strip_LDADD = $(LIBTIFF)
+test_ifd_loop_detection_CFLAGS = -DSOURCE_DIR=\"@srcdir@\"
+test_ifd_loop_detection_SOURCES = test_ifd_loop_detection.c
+test_ifd_loop_detection_LDADD = $(LIBTIFF)
AM_CPPFLAGS = -I$(top_srcdir)/libtiff
diff --git a/test/images/test_ifd_loop_to_first.tif b/test/images/test_ifd_loop_to_first.tif
new file mode 100644
index 0000000000000000000000000000000000000000..015c8d90d0d631c23792e8fc2c9e98af45f7809e
GIT binary patch
literal 312
zcmebD)MDUbU|`5*;9+23WM*IlvcVXM%>-q00OgpG#MzM8f{ZL+eIPYLNaCVMY%wIZ
bI8;5zE*T{8U?lb;pd7W_wSbE50)-a<l`sWq
literal 0
HcmV?d00001
diff --git a/test/images/test_ifd_loop_to_self.tif b/test/images/test_ifd_loop_to_self.tif
new file mode 100644
index 0000000000000000000000000000000000000000..26b585e960dbc259506326396796dbf238393436
GIT binary patch
literal 558
zcmYk4ty0B6424@R!yqs){1~2qH@R3`ZDeF*?2!?O2*lczD=V+W-q%6G$)%#Z(`hC-
zIr(<m<MD0!nx{z}1_S`*hPt&hzS6pdx(l2&X-17R69%WwOidH+Y<A;TOEnhJ%FN6>
zy*pIV{4_?UCHo9bs^zTTBO^d}qr8R;r=nCrFVJ3GRv{1Ug6Ixmt|muF2uFepEIQ9n
zt5`Kzh{2TqKS4xWbSPI%8!1&0Jq@LmgpSBMx6mCD1fYy;8Vl_g;_@s7Cg|CmHpby1
z1-ZDLMnpF(VheM0;N`TH1f=zM0!Kq9@c8*XL&FojC$Cbu*R^G9ZAIO9Efc+)rui`O
y!%UBS=3RWX#kb5KwzzaRyZC;-zVw#nVV8f}#m`$@{x6&UlSZ#Q&BrdTzvK_+G|CPD
literal 0
HcmV?d00001
diff --git a/test/images/test_two_ifds.tif b/test/images/test_two_ifds.tif
new file mode 100644
index 0000000000000000000000000000000000000000..4334649ea787c9b71f36eb918f715af88b296e2e
GIT binary patch
literal 312
zcmebD)MDUbU|`5*;9+23WM*IlvcVXM%>-q00OgpG#MzM8f{ZL+eIPYLNaCVMY%wIZ
cI8;5zE*T{8U?lb;pd7W_wSbE50vg2t0F?*@UjP6A
literal 0
HcmV?d00001
diff --git a/test/test_ifd_loop_detection.c b/test/test_ifd_loop_detection.c
new file mode 100644
index 00000000..52b089bf
--- /dev/null
+++ b/test/test_ifd_loop_detection.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2022, Even Rouault <even.rouault at spatialys.com>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library
+ *
+ * Test IFD loop detection
+ */
+
+#include "tif_config.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "tiffio.h"
+
+int main()
+{
+ int ret = 0;
+ {
+ TIFF *tif =
+ TIFFOpen(SOURCE_DIR "/images/test_ifd_loop_to_self.tif", "r");
+ assert(tif);
+ if (TIFFReadDirectory(tif))
+ {
+ fprintf(stderr, "(1) Expected TIFFReadDirectory() to fail\n");
+ ret = 1;
+ }
+ TIFFClose(tif);
+ }
+ {
+ TIFF *tif =
+ TIFFOpen(SOURCE_DIR "/images/test_ifd_loop_to_self.tif", "r");
+ assert(tif);
+ int n = TIFFNumberOfDirectories(tif);
+ if (n != 1)
+ {
+ fprintf(
+ stderr,
+ "(2) Expected TIFFNumberOfDirectories() to return 1. Got %d\n",
+ n);
+ ret = 1;
+ }
+ TIFFClose(tif);
+ }
+ {
+ TIFF *tif =
+ TIFFOpen(SOURCE_DIR "/images/test_ifd_loop_to_first.tif", "r");
+ assert(tif);
+ if (TIFFReadDirectory(tif) != 1)
+ {
+ fprintf(stderr, "(3) Expected TIFFReadDirectory() to succeed\n");
+ ret = 1;
+ }
+ if (TIFFReadDirectory(tif))
+ {
+ fprintf(stderr, "(4) Expected TIFFReadDirectory() to fail\n");
+ ret = 1;
+ }
+ if (TIFFSetDirectory(tif, 1) != 1)
+ {
+ fprintf(stderr, "(5) Expected TIFFSetDirectory() to succeed\n");
+ ret = 1;
+ }
+ if (TIFFReadDirectory(tif))
+ {
+ fprintf(stderr, "(6) Expected TIFFReadDirectory() to fail\n");
+ ret = 1;
+ }
+ if (TIFFSetDirectory(tif, 0) != 1)
+ {
+ fprintf(stderr, "(7) Expected TIFFSetDirectory() to succeed\n");
+ ret = 1;
+ }
+ if (TIFFReadDirectory(tif) != 1)
+ {
+ fprintf(stderr, "(8) Expected TIFFReadDirectory() to succeed\n");
+ ret = 1;
+ }
+ if (TIFFReadDirectory(tif))
+ {
+ fprintf(stderr, "(9) Expected TIFFReadDirectory() to fail\n");
+ ret = 1;
+ }
+ TIFFClose(tif);
+ }
+ {
+ TIFF *tif =
+ TIFFOpen(SOURCE_DIR "/images/test_ifd_loop_to_first.tif", "r");
+ assert(tif);
+ int n = TIFFNumberOfDirectories(tif);
+ if (n != 2)
+ {
+ fprintf(
+ stderr,
+ "(10) Expected TIFFNumberOfDirectories() to return 2. Got %d\n",
+ n);
+ ret = 1;
+ }
+ TIFFClose(tif);
+ }
+ {
+ TIFF *tif = TIFFOpen(SOURCE_DIR "/images/test_two_ifds.tif", "r");
+ assert(tif);
+ if (TIFFReadDirectory(tif) != 1)
+ {
+ fprintf(stderr, "(11) Expected TIFFReadDirectory() to succeed\n");
+ ret = 1;
+ }
+ if (TIFFReadDirectory(tif))
+ {
+ fprintf(stderr, "(12) Expected TIFFReadDirectory() to fail\n");
+ ret = 1;
+ }
+ if (TIFFSetDirectory(tif, 1) != 1)
+ {
+ fprintf(stderr, "(13) Expected TIFFSetDirectory() to succeed\n");
+ ret = 1;
+ }
+ if (TIFFReadDirectory(tif))
+ {
+ fprintf(stderr, "(14) Expected TIFFReadDirectory() to fail\n");
+ ret = 1;
+ }
+ if (TIFFSetDirectory(tif, 0) != 1)
+ {
+ fprintf(stderr, "(15) Expected TIFFSetDirectory() to succeed\n");
+ ret = 1;
+ }
+ if (TIFFReadDirectory(tif) != 1)
+ {
+ fprintf(stderr, "(16) Expected TIFFReadDirectory() to succeed\n");
+ ret = 1;
+ }
+ if (TIFFReadDirectory(tif))
+ {
+ fprintf(stderr, "(17) Expected TIFFReadDirectory() to fail\n");
+ ret = 1;
+ }
+ TIFFClose(tif);
+ }
+ {
+ TIFF *tif = TIFFOpen(SOURCE_DIR "/images/test_two_ifds.tif", "r");
+ assert(tif);
+ int n = TIFFNumberOfDirectories(tif);
+ if (n != 2)
+ {
+ fprintf(
+ stderr,
+ "(18) Expected TIFFNumberOfDirectories() to return 2. Got %d\n",
+ n);
+ ret = 1;
+ }
+ TIFFClose(tif);
+ }
+ return ret;
+}