https://github.com/libsdl-org/libtiff/commit/9752dae8febab08879fc0159e7d387cff14eb3c3
From 97574866cbab026acb1bbd735201f790091b9400 Mon Sep 17 00:00:00 2001
From: Su_Laus <[EMAIL REDACTED]>
Date: Sun, 3 Apr 2022 22:04:58 +0200
Subject: [PATCH] extra flag for anonymous (unknown) tags (fixes #8)
---
libtiff/libtiff.def | 2 ++
libtiff/tif_close.c | 5 ++++-
libtiff/tif_dir.h | 4 ++--
libtiff/tif_dirinfo.c | 17 ++++++++++++++---
libtiff/tif_dirread.c | 2 +-
libtiff/tif_print.c | 4 ++--
libtiff/tiffio.h | 1 +
7 files changed, 26 insertions(+), 9 deletions(-)
diff --git a/libtiff/libtiff.def b/libtiff/libtiff.def
index b2d03fe7..90850fd2 100644
--- a/libtiff/libtiff.def
+++ b/libtiff/libtiff.def
@@ -29,6 +29,7 @@ EXPORTS TIFFAccessTagMethods
TIFFFieldName
TIFFFieldPassCount
TIFFFieldReadCount
+ TIFFFieldIsAnonymous
TIFFFieldTag
TIFFFieldWithName
TIFFFieldWithTag
@@ -177,3 +178,4 @@ EXPORTS TIFFAccessTagMethods
_TIFFMultiply64
_TIFFGetExifFields
_TIFFGetGpsFields
+
diff --git a/libtiff/tif_close.c b/libtiff/tif_close.c
index 576e0843..d886964f 100644
--- a/libtiff/tif_close.c
+++ b/libtiff/tif_close.c
@@ -82,7 +82,10 @@ TIFFCleanup(TIFF* tif)
TIFFField *fld = tif->tif_fields[i];
if (fld->field_name != NULL) {
if (fld->field_bit == FIELD_CUSTOM &&
- strncmp("Tag ", fld->field_name, 4) == 0) {
+ /* catuion: tif_fields[i] must not be the beginning of a fields-array.
+ * Otherwise the following tags are also freed with the first free().
+ */
+ TIFFFieldIsAnonymous(fld)) {
_TIFFfree(fld->field_name);
_TIFFfree(fld);
}
diff --git a/libtiff/tif_dir.h b/libtiff/tif_dir.h
index 1782b35d..09065648 100644
--- a/libtiff/tif_dir.h
+++ b/libtiff/tif_dir.h
@@ -282,11 +282,11 @@ struct _TIFFFieldArray {
};
struct _TIFFField {
- uint32_t field_tag; /* field's tag */
+ uint32_t field_tag; /* field's tag */
short field_readcount; /* read count/TIFF_VARIABLE/TIFF_SPP */
short field_writecount; /* write count/TIFF_VARIABLE */
TIFFDataType field_type; /* type of associated data */
- uint32_t reserved; /* reserved for future extension */
+ uint32_t field_anonymous; /* if true, this is a unknown / anonymous tag */
TIFFSetGetFieldType set_field_type; /* type to be passed to TIFFSetField */
TIFFSetGetFieldType get_field_type; /* type to be passed to TIFFGetField */
unsigned short field_bit; /* bit in fieldsset bit vector */
diff --git a/libtiff/tif_dirinfo.c b/libtiff/tif_dirinfo.c
index 0bd32c3f..2f9efc6d 100644
--- a/libtiff/tif_dirinfo.c
+++ b/libtiff/tif_dirinfo.c
@@ -422,8 +422,11 @@ _TIFFSetupFields(TIFF* tif, const TIFFFieldArray* fieldarray)
TIFFField *fld = tif->tif_fields[i];
if (fld->field_name != NULL) {
if (fld->field_bit == FIELD_CUSTOM &&
- strncmp("Tag ", fld->field_name, 4) == 0) {
+ TIFFFieldIsAnonymous(fld)) {
_TIFFfree(fld->field_name);
+ /* catuion: tif_fields[i] must not be the beginning of a fields-array.
+ * Otherwise the following tags are also freed with the first free().
+ */
_TIFFfree(fld);
}
}
@@ -791,6 +794,12 @@ TIFFFieldWriteCount(const TIFFField* fip)
return fip->field_writecount;
}
+int
+TIFFFieldIsAnonymous(const TIFFField *fip)
+{
+ return fip->field_anonymous;
+}
+
const TIFFField*
_TIFFFindOrRegisterField(TIFF *tif, uint32_t tag, TIFFDataType dt)
@@ -822,7 +831,7 @@ _TIFFCreateAnonField(TIFF *tif, uint32_t tag, TIFFDataType field_type)
fld->field_readcount = TIFF_VARIABLE2;
fld->field_writecount = TIFF_VARIABLE2;
fld->field_type = field_type;
- fld->reserved = 0;
+ fld->field_anonymous = 1; /* indicate that this is an anonymous / unknown tag */
switch (field_type)
{
case TIFF_BYTE:
@@ -895,6 +904,8 @@ _TIFFCreateAnonField(TIFF *tif, uint32_t tag, TIFFDataType field_type)
/*
* note that this name is a special sign to TIFFClose() and
* _TIFFSetupFields() to free the field
+ * Update:
+ * This special sign is replaced by fld->field_anonymous flag.
*/
(void) snprintf(fld->field_name, 32, "Tag %d", (int) tag);
@@ -1105,7 +1116,7 @@ TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], uint32_t n)
tp->field_readcount = info[i].field_readcount;
tp->field_writecount = info[i].field_writecount;
tp->field_type = info[i].field_type;
- tp->reserved = 0;
+ tp->field_anonymous = 0;
tp->set_field_type =
_TIFFSetGetType(info[i].field_type,
info[i].field_readcount,
diff --git a/libtiff/tif_dirread.c b/libtiff/tif_dirread.c
index 3ed6da1d..32972d93 100644
--- a/libtiff/tif_dirread.c
+++ b/libtiff/tif_dirread.c
@@ -4537,7 +4537,7 @@ TIFFReadCustomDirectory(TIFF* tif, toff_t diroff,
switch (dp->tdir_tag)
{
case EXIFTAG_SUBJECTDISTANCE:
- if(fip->field_name != NULL && strncmp(fip->field_name, "Tag ", 4) != 0 ) {
+ if(!TIFFFieldIsAnonymous(fip)) {
/* should only be called on a Exif directory */
/* when exifFields[] is active */
(void)TIFFFetchSubjectDistance(tif, dp);
diff --git a/libtiff/tif_print.c b/libtiff/tif_print.c
index f75c4381..57fa90c1 100644
--- a/libtiff/tif_print.c
+++ b/libtiff/tif_print.c
@@ -81,7 +81,7 @@ _TIFFPrintField(FILE* fd, const TIFFField *fip,
/* Print a user-friendly name for tags of relatively common use, but */
/* which aren't registered by libtiff itself. */
const char* field_name = fip->field_name;
- if( fip->field_name != NULL && strncmp(fip->field_name, "Tag ", 4) == 0 ) {
+ if( TIFFFieldIsAnonymous(fip) ) {
for( size_t i = 0; i < NTAGS; ++i ) {
if( fip->field_tag == tagnames[i].tag ) {
field_name = tagnames[i].name;
@@ -149,7 +149,7 @@ _TIFFPrettyPrintField(TIFF* tif, const TIFFField *fip, FILE* fd, uint32_t tag,
(void) tif;
/* do not try to pretty print auto-defined fields */
- if (fip->field_name != NULL && strncmp(fip->field_name,"Tag ", 4) == 0) {
+ if ( TIFFFieldIsAnonymous(fip) ) {
return 0;
}
diff --git a/libtiff/tiffio.h b/libtiff/tiffio.h
index c6a192c5..2ad58503 100644
--- a/libtiff/tiffio.h
+++ b/libtiff/tiffio.h
@@ -328,6 +328,7 @@ extern TIFFDataType TIFFFieldDataType(const TIFFField*);
extern int TIFFFieldPassCount(const TIFFField*);
extern int TIFFFieldReadCount(const TIFFField*);
extern int TIFFFieldWriteCount(const TIFFField*);
+extern int TIFFFieldIsAnonymous(const TIFFField *);
typedef int (*TIFFVSetMethod)(TIFF*, uint32_t, va_list);
typedef int (*TIFFVGetMethod)(TIFF*, uint32_t, va_list);