libtiff: tiffcrop: disable incompatibility of -Z, -X, -Y, -z options with any PAGE_MODE_x option (fixes #411 and #413)

From 4746f16253b784287bc8a5003990c1c3b9a03a62 Mon Sep 17 00:00:00 2001
From: Su_Laus <[EMAIL REDACTED]>
Date: Thu, 25 Aug 2022 16:11:41 +0200
Subject: [PATCH] tiffcrop: disable incompatibility of -Z, -X, -Y, -z options
 with any PAGE_MODE_x option (fixes #411 and #413)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

tiffcrop does not support –Z, -z, -X and –Y options together with any other PAGE_MODE_x options like  -H, -V, -P, -J, -K or –S.

Code analysis:

With the options –Z, -z, the crop.selections are set to a value > 0. Within main(), this triggers the call of processCropSelections(), which copies the sections from the read_buff into seg_buffs[].
In the following code in main(), the only supported step, where that seg_buffs are further handled are within an if-clause with  if (page.mode == PAGE_MODE_NONE) .

Execution of the else-clause often leads to buffer-overflows.

Therefore, the above option combination is not supported and will be disabled to prevent those buffer-overflows.

The MR solves issues #411 and #413.
---
 doc/tools/tiffcrop.rst |  8 ++++++++
 tools/tiffcrop.c       | 32 +++++++++++++++++++++++++-------
 2 files changed, 33 insertions(+), 7 deletions(-)

diff --git a/doc/tools/tiffcrop.rst b/doc/tools/tiffcrop.rst
index ee0d2d81..b5e8e744 100644
--- a/doc/tools/tiffcrop.rst
+++ b/doc/tools/tiffcrop.rst
@@ -415,6 +415,14 @@ Options
   Note: :program:`tiffcrop` may be compiled with :command:`-DDEVELMODE` to enable
   additional very low level debug reporting.
 
+However, not all option combinations are permitted.
+
+  Note 1: The (-X|-Y), -Z, -z and -S options are mutually exclusive.
+  In no case should the options be applied to a given selection successively.
+
+  Note 2: Any of the -X, -Y, -Z and -z options together with other PAGE_MODE_x options
+  such as -H, -V, -P, -J or -K are not supported and may cause buffer overflows.
+  
 Examples
 --------
 
diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c
index 8fd856dc..41a2ea36 100644
--- a/tools/tiffcrop.c
+++ b/tools/tiffcrop.c
@@ -107,13 +107,15 @@
  *                selects which functions dump data, with higher numbers selecting
  *                lower level, scanline level routines. Debug reports a limited set
  *                of messages to monitor progress without enabling dump logs.
- * 
- * Note:    The (-X|-Y), -Z, -z and -S options are mutually exclusive.
+ *
+ * Note 1:  The (-X|-Y), -Z, -z and -S options are mutually exclusive.
  *          In no case should the options be applied to a given selection successively.
- */
+ * Note 2:  Any of the -X, -Y, -Z and -z options together with other PAGE_MODE_x options
+ *          such as -H, -V, -P, -J or -K are not supported and may cause buffer overflows.
+  */
 
-static   char tiffcrop_version_id[] = "2.5.1";
-static   char tiffcrop_rev_date[] = "15-08-2022";
+static   char tiffcrop_version_id[] = "2.5.3";
+static   char tiffcrop_rev_date[] = "26-08-2022";
 
 #include "tif_config.h"
 #include "libport.h"
@@ -781,9 +783,12 @@ static const char usage_info[] =
 "             The four debug/dump options are independent, though it makes little sense to\n"
 "             specify a dump file without specifying a detail level.\n"
 "\n"
-"Note:        The (-X|-Y), -Z, -z and -S options are mutually exclusive.\n"
+"Note 1:      The (-X|-Y), -Z, -z and -S options are mutually exclusive.\n"
 "             In no case should the options be applied to a given selection successively.\n"
 "\n"
+"Note 2:      Any of the -X, -Y, -Z and -z options together with other PAGE_MODE_x options\n"
+"             such as - H, -V, -P, -J or -K are not supported and may cause buffer overflows.\n"
+"\n"
 ;
 
 /* This function could be modified to pass starting sample offset 
@@ -2138,9 +2143,20 @@ void  process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32
     R = (crop_data->crop_mode & CROP_REGIONS) ? 1 : 0;
     S = (page->mode & PAGE_MODE_ROWSCOLS) ? 1 : 0;
     if (XY + Z + R + S > 1) {
-        TIFFError("tiffcrop input error", "The crop options(-X|-Y), -Z, -z and -S are mutually exclusive.->Exit");
+        TIFFError("tiffcrop input error", "The crop options(-X|-Y), -Z, -z and -S are mutually exclusive.->exit");
         exit(EXIT_FAILURE);
     }
+
+    /* Check for not allowed combination:
+     * Any of the -X, -Y, -Z and -z options together with other PAGE_MODE_x options
+     * such as -H, -V, -P, -J or -K are not supported and may cause buffer overflows.
+.    */
+    if ((XY + Z + R > 0) && page->mode != PAGE_MODE_NONE) {
+        TIFFError("tiffcrop input error",
+            "Any of the crop options -X, -Y, -Z and -z together with other PAGE_MODE_x options such as - H, -V, -P, -J or -K is not supported and may cause buffer overflows..->exit");
+        exit(EXIT_FAILURE);
+    }
+
   }  /* end process_command_opts */
 
 /* Start a new output file if one has not been previously opened or
@@ -2411,6 +2427,7 @@ main(int argc, char* argv[])
         exit (EXIT_FAILURE);
 	}
 
+      /* Crop input image and copy zones and regions from input image into seg_buffs or crop_buff. */
       if (crop.selections > 0)
         {
         if (processCropSelections(&image, &crop, &read_buff, seg_buffs))
@@ -2427,6 +2444,7 @@ main(int argc, char* argv[])
           exit (EXIT_FAILURE);
 	  }
 	}
+      /* Format and write selected image parts to output file(s). */
       if (page.mode == PAGE_MODE_NONE)
         {  /* Whole image or sections not based on output page size */
         if (crop.selections > 0)