Hi, I intend to upload a 0-day NMU for this. Patch is attached. Unfortunately this NMU will update to the newest upstream version. I am not really comfortable with this but I have several reasons to do so.
The maintainer is MIA but the package is not orphaned, the upstream author is not really responsive in providing patches, there is no patch available and without having a deep knowledge of what the code does it is also not really possible to extract one out of the diff between the versions and writing one from scratch seems to be not possible for the same reason. Patch attached. Kind regards Nico -- Nico Golde - http://www.ngolde.de - [EMAIL PROTECTED] - GPG: 0x73647CFF For security reasons, all text in this mail is double-rot13 encrypted.
diff -Nru /tmp/FwWif1KFzu/exiftags-1.00/canon.c /tmp/pv5QyHY9pH/exiftags-1.0.1/canon.c --- /tmp/FwWif1KFzu/exiftags-1.00/canon.c 2005-01-11 21:12:35.000000000 +0100 +++ /tmp/pv5QyHY9pH/exiftags-1.0.1/canon.c 2007-12-16 04:06:13.000000000 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2004, Eric M. Johnston <[EMAIL PROTECTED]> + * Copyright (c) 2001-2007, Eric M. Johnston <[EMAIL PROTECTED]> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: canon.c,v 1.52 2005/01/11 20:12:35 ejohnst Exp $ + * $Id: canon.c,v 1.54 2007/12/16 03:06:13 ejohnst Exp $ */ /* @@ -38,6 +38,7 @@ * EOS 1D and 1Ds contributions from Stan Jirman <[EMAIL PROTECTED]>. * EOS 10D contributions from Jason Montojo <[EMAIL PROTECTED]>. * EOS 20D contributions from Per Kristian Hove <[EMAIL PROTECTED]>. + * EOS 5D contributions from Albert Max Lai <[EMAIL PROTECTED]>. * */ @@ -277,6 +278,8 @@ "Custom Function", NULL }, { 0x0093, TIFF_SHORT, 0, ED_UNK, "Canon93Tag", "Canon Tag93 Offset", NULL }, + { 0x0095, TIFF_ASCII, 64, ED_PAS, "LensName", + "Lens Name", NULL }, { 0x00a0, TIFF_SHORT, 0, ED_UNK, "CanonA0Tag", "Canon TagA0 Offset", NULL }, { 0xffff, TIFF_UNKN, 0, ED_UNK, "CanonUnknown", @@ -697,6 +700,19 @@ { -1, "Unknown" }, }; +static struct descrip ccstm_5dflashsync[] = { + { 0, "Auto" }, + { 1, "1/200 (Fixed)" }, + { -1, "Unknown" }, +}; + +static struct descrip ccstm_5dfscr[] = { + { 0, "Ee-A" }, + { 1, "Ee-D" }, + { 2, "Ee-S" }, + { -1, "Unknown" }, +}; + /* D30/D60 custom functions. */ @@ -785,6 +801,51 @@ "Canon 1D/1Ds Custom Unknown", NULL }, }; +/* 5D custom functions. */ + +static struct exiftag canon_5dcustom[] = { + { 0, TIFF_SHORT, 0, ED_VRB, "5DCustom", + "Focusing Screen", ccstm_5dfscr }, + { 1, TIFF_SHORT, 0, ED_VRB, "5DCustom", + "SET button function when shooting", ccstm_10dsetbut }, + { 2, TIFF_SHORT, 0, ED_VRB, "5DCustom", + "Long exposure noise reduction", ccstm_offon }, + { 3, TIFF_SHORT, 0, ED_VRB, "5DCustom", + "Flash sync speed in Av mode", ccstm_5dflashsync }, + { 4, TIFF_SHORT, 0, ED_VRB, "5DCustom", + "Shutter button/AE lock button", ccstm_10dshutter }, + { 5, TIFF_SHORT, 0, ED_VRB, "5DCustom", + "AF-assist beam", ccstm_assistflash }, + { 6, TIFF_SHORT, 0, ED_VRB, "5DCustom", + "Exposure level increments", ccstm_20dexplvl }, + { 7, TIFF_SHORT, 0, ED_VRB, "5DCustom", + "Flash firing", ccstm_20dflash }, + { 8, TIFF_SHORT, 0, ED_VRB, "5DCustom", + "ISO expansion", ccstm_offon }, + { 9, TIFF_SHORT, 0, ED_VRB, "5DCustom", + "AEB sequence/auto cancellation", ccstm_aebseq }, + { 10, TIFF_SHORT, 0, ED_VRB, "5DCustom", + "Superimposed display", ccstm_onoff }, + { 11, TIFF_SHORT, 0, ED_VRB, "5DCustom", + "Menu button display position", ccstm_10dmenubut }, + { 12, TIFF_SHORT, 0, ED_VRB, "5DCustom", + "Mirror lockup", ccstm_disen }, + { 13, TIFF_SHORT, 0, ED_VRB, "5DCustom", + "AF point selection method", ccstm_20dafpsel }, + { 14, TIFF_SHORT, 0, ED_VRB, "5DCustom", + "E-TTL II", ccstm_20dettl }, + { 15, TIFF_SHORT, 0, ED_VRB, "5DCustom", + "Shutter curtain sync", ccstm_shutsync }, + { 16, TIFF_SHORT, 0, ED_VRB, "5DCustom", + "Safety shift in Av or Tv", ccstm_disen }, + { 17, TIFF_SHORT, 0, ED_VRB, "5DCustom", + "Lens AF stop button", ccstm_lensaf1 }, + { 18, TIFF_SHORT, 0, ED_VRB, "5DCustom", + "Add original decision data", ccstm_offon }, + { 0xffff, TIFF_SHORT, 0, ED_UNK, "5DCustomUnknown", + "Canon 5D Custom Unknown", NULL }, +}; + /* 10D custom functions. */ static struct exiftag canon_10dcustom[] = { @@ -1350,6 +1411,9 @@ else if (strstr(t->model, "20D")) canon_custom(prop, t->mkrmd.btiff + prop->value, t->mkrmd.order, canon_20dcustom); + else if (strstr(t->model, "5D")) + canon_custom(prop, t->mkrmd.btiff + prop->value, + t->mkrmd.order, canon_5dcustom); else exifwarn2("Custom function unsupported; please " "report to author", t->model); @@ -1376,8 +1440,6 @@ struct ifd * canon_ifd(u_int32_t offset, struct tiffmeta *md) { - struct ifd *myifd; - readifd(offset, &myifd, canon_tags, md); - return(myifd); + return (readifds(offset, canon_tags, md)); } diff -Nru /tmp/FwWif1KFzu/exiftags-1.00/CHANGES /tmp/pv5QyHY9pH/exiftags-1.0.1/CHANGES --- /tmp/FwWif1KFzu/exiftags-1.00/CHANGES 2005-01-27 08:15:00.000000000 +0100 +++ /tmp/pv5QyHY9pH/exiftags-1.0.1/CHANGES 2007-12-16 04:45:59.000000000 +0100 @@ -1,3 +1,14 @@ +20071215 version: exiftags 1.01 +20071215 fixed to compile on HP-UX +20071215 added Canon EOS-5D custom function support (thanks: Albert Max Lai) +20071215 custom timestamp prefs in exiftime listing (thanks: Stuart Scharf) +20071215 suppress warnings on invalid user comments +20071214 allow output of invalid tags in debug +20071214 fixed looping from recursive IFD ref, resolves CVE-2007-6356 + (thanks: Christian Schmid; Meder Kydyraliev, Google Security Team) +20071214 fixed handling of field offset overflow, resolves CVE-2007-6354 & + CVE-2007-6355 (thanks: Meder Kydyraliev, Google Security Team) + 20050126 version: exiftags 1.00 20050107 added Canon tags, minor tweaks (thanks: Henrik Levkowetz) 20050104 fixed handling of short ASCII strings @@ -98,4 +109,4 @@ 20020216 version: exifdump 0.90 20020120 version: exifdump 0.80 -$Id: CHANGES,v 1.21 2005/01/27 07:15:00 ejohnst Exp $ +$Id: CHANGES,v 1.23 2007/12/16 03:45:59 ejohnst Exp $ diff -Nru /tmp/FwWif1KFzu/exiftags-1.00/debian/changelog /tmp/pv5QyHY9pH/exiftags-1.0.1/debian/changelog --- /tmp/FwWif1KFzu/exiftags-1.00/debian/changelog 2008-01-04 15:45:55.000000000 +0100 +++ /tmp/pv5QyHY9pH/exiftags-1.0.1/debian/changelog 2008-01-03 20:14:48.000000000 +0100 @@ -1,3 +1,16 @@ +exiftags (1.0.1-0.1) unstable; urgency=high + + * Non-maintainer upload by security team. + * New upstream release (Closes: #457062): + - CVE-2007-6356: exiftags before 1.01 allows attackers to cause a denial + of service (infinite loop) via recursive IFD references in the EXIF data + in a JPEG image. + - CVE-2007-6355: Unspecified vulnerability in exiftags before 1.01 has + unknown impact and attack vectors, resulting from a "field + offset overflow," + + -- Nico Golde <[EMAIL PROTECTED]> Thu, 03 Jan 2008 20:10:57 +0100 + exiftags (1.00-1) unstable; urgency=low * New upstream release diff -Nru /tmp/FwWif1KFzu/exiftags-1.00/exif.c /tmp/pv5QyHY9pH/exiftags-1.0.1/exif.c --- /tmp/FwWif1KFzu/exiftags-1.00/exif.c 2005-01-05 00:28:25.000000000 +0100 +++ /tmp/pv5QyHY9pH/exiftags-1.0.1/exif.c 2007-12-16 01:25:08.000000000 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2005, Eric M. Johnston <[EMAIL PROTECTED]> + * Copyright (c) 2001-2007, Eric M. Johnston <[EMAIL PROTECTED]> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: exif.c,v 1.74 2005/01/04 23:28:25 ejohnst Exp $ + * $Id: exif.c,v 1.77 2007/12/16 00:25:08 ejohnst Exp $ */ /* @@ -136,12 +136,14 @@ * (At least we're able to ID invalid comments...) */ - if (prop->tagset[i].type && prop->tagset[i].type != prop->type + if (prop->tagset[i].type && prop->tagset[i].type != + prop->type) { #ifdef WINXP_BUGS - && prop->tag != EXIF_T_USERCOMMENT + if (prop->tag != EXIF_T_USERCOMMENT) #endif - ) - exifwarn2("field type mismatch", prop->name); + exifwarn2("field type mismatch", prop->name); + prop->lvl = ED_BAD; + } /* * Check the field count. @@ -151,11 +153,16 @@ if (prop->tagset[i].count && prop->tagset[i].count != #ifdef SIGMA_BUGS - prop->count && prop->tag != EXIF_T_FILESRC) + prop->count && prop->tag != EXIF_T_FILESRC) { #else - prop->count) + prop->count) { #endif exifwarn2("field count mismatch", prop->name); + + /* Let's be forgiving with ASCII fields. */ + if (prop->type != TIFF_ASCII) + prop->lvl = ED_BAD; + } } /* Debuggage. */ @@ -231,6 +238,11 @@ enum byteorder o = t->md.order; struct exifprop *h = t->props; + /* Skip bad properties. */ + + if (prop->lvl == ED_BAD) + return; + /* * Process tags from special IFDs. */ @@ -480,6 +492,11 @@ unsigned char *btiff = dir->md.btiff; enum byteorder o = dir->md.order; + /* If the tag's already marked as bad, no sense in continuing. */ + + if (prop->lvl == ED_BAD) + return; + /* Set description if we have a lookup table. */ for (i = 0; prop->tagset[i].tag < EXIF_T_UNKNOWN && @@ -498,15 +515,6 @@ case EXIF_T_EXIFIFD: case EXIF_T_GPSIFD: case EXIF_T_INTEROP: - /* - * Prevent looping when the tag refers to its own IFD... - * (Occurs in a screwed-up Agfa example.) - */ - if (prop->par && prop->tag == prop->par->tag) { - exifwarn2("IFD tag refers to itself", prop->name); - break; - } - md = &dir->md; while (dir->next) dir = dir->next; @@ -582,9 +590,11 @@ * the manufacturer tag first to figure out makerifd(). */ - if (makers[t->mkrval].ifdfun) - dir->next = makers[t->mkrval].ifdfun(prop->value, md); - else + if (makers[t->mkrval].ifdfun) { + if (!offsanity(prop, 1, dir)) + dir->next = + makers[t->mkrval].ifdfun(prop->value, md); + } else exifwarn("maker note not supported"); if (!dir->next) @@ -600,11 +610,8 @@ /* Sanity check the offset. */ - if (prop->value + prop->count > - (u_int32_t)(dir->md.etiff - btiff)) { - exifwarn2("invalid field offset", prop->name); - break; - } + if (offsanity(prop, 1, dir)) + return; strncpy(buf, (const char *)(btiff + prop->value), sizeof(buf)); buf[sizeof(buf) - 1] = '\0'; @@ -641,9 +648,14 @@ /* Check for a comment type and sane offset. */ - if (prop->count < 8 || (prop->value + prop->count > - (u_int32_t)(dir->md.etiff - btiff))) - break; + if (prop->count < 8) { + exifwarn("invalid user comment length"); + prop->lvl = ED_BAD; + return; + } + + if (offsanity(prop, 1, dir)) + return; /* Ignore the 'comments' WinXP creates when rotating. */ #ifdef WINXP_BUGS @@ -700,13 +712,12 @@ } /* Sanity check the offset. */ - if ((prop->value + prop->count <= - (u_int32_t)(dir->md.etiff - btiff))) { + if (!offsanity(prop, 1, dir)) { exifstralloc(&prop->str, prop->count + 1); strncpy(prop->str, (const char *)(btiff + prop->value), prop->count); - return; } + return; } /* @@ -717,8 +728,7 @@ */ if ((prop->type == TIFF_RTNL || prop->type == TIFF_SRTNL) && - (prop->value + prop->count * 8 <= - (u_int32_t)(dir->md.etiff - btiff))) { + !offsanity(prop, 8, dir)) { exifstralloc(&prop->str, 32); @@ -747,8 +757,7 @@ */ if ((prop->type == TIFF_SHORT || prop->type == TIFF_SSHORT) && - prop->count > 2 && (prop->value + prop->count * 2 <= - (u_int32_t)(dir->md.etiff - btiff))) { + prop->count > 2 && !offsanity(prop, 2, dir)) { if (prop->count > 8) return; @@ -775,12 +784,13 @@ /* - * Delete dynamic Exif property memory. + * Delete dynamic Exif property and IFD memory. */ void exiffree(struct exiftags *t) { struct exifprop *tmpprop; + struct ifdoff *tmpoff; if (!t) return; @@ -789,6 +799,10 @@ t->props = t->props->next; free(tmpprop); } + while ((tmpoff = (struct ifdoff *)(t->md.ifdoffs))) { + t->md.ifdoffs = (void *)tmpoff->next; + free(tmpoff); + } free(t); } diff -Nru /tmp/FwWif1KFzu/exiftags-1.00/exifcom.c /tmp/pv5QyHY9pH/exiftags-1.0.1/exifcom.c --- /tmp/FwWif1KFzu/exiftags-1.00/exifcom.c 2005-01-27 08:15:00.000000000 +0100 +++ /tmp/pv5QyHY9pH/exiftags-1.0.1/exifcom.c 2007-12-16 03:11:44.000000000 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2005, Eric M. Johnston <[EMAIL PROTECTED]> + * Copyright (c) 2002-2007, Eric M. Johnston <[EMAIL PROTECTED]> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: exifcom.c,v 1.15 2005/01/27 07:15:00 ejohnst Exp $ + * $Id: exifcom.c,v 1.16 2007/12/16 02:11:44 ejohnst Exp $ */ /* @@ -56,7 +56,7 @@ #include "exif.h" -static const char *version = "1.00"; +static const char *version = "1.01"; static int fnum, bflag, iflag, nflag, vflag; static const char *com; static const char *delim = ": "; diff -Nru /tmp/FwWif1KFzu/exiftags-1.00/exifgps.c /tmp/pv5QyHY9pH/exiftags-1.0.1/exifgps.c --- /tmp/FwWif1KFzu/exiftags-1.00/exifgps.c 2005-01-05 01:28:22.000000000 +0100 +++ /tmp/pv5QyHY9pH/exiftags-1.0.1/exifgps.c 2007-12-15 21:57:10.000000000 +0100 @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: exifgps.c,v 1.13 2005/01/05 00:28:22 ejohnst Exp $ + * $Id: exifgps.c,v 1.14 2007/12/15 20:57:10 ejohnst Exp $ */ /* @@ -245,9 +245,9 @@ case 0x0004: case 0x0014: case 0x0016: - if (prop->count != 3 || prop->value + prop->count * 8 > - (u_int32_t)(t->md.etiff - t->md.btiff)) { + if (prop->count != 3) { exifwarn("unexpected GPS coordinate values"); + prop->lvl = ED_BAD; break; } diff -Nru /tmp/FwWif1KFzu/exiftags-1.00/exif.h /tmp/pv5QyHY9pH/exiftags-1.0.1/exif.h --- /tmp/FwWif1KFzu/exiftags-1.00/exif.h 2004-12-23 21:38:52.000000000 +0100 +++ /tmp/pv5QyHY9pH/exiftags-1.0.1/exif.h 2007-12-16 04:44:32.000000000 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2004, Eric M. Johnston <[EMAIL PROTECTED]> + * Copyright (c) 2001-2007, Eric M. Johnston <[EMAIL PROTECTED]> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: exif.h,v 1.36 2004/12/23 20:38:52 ejohnst Exp $ + * $Id: exif.h,v 1.38 2007/12/16 03:44:32 ejohnst Exp $ */ /* @@ -48,7 +48,7 @@ /* - * XXX Only checking for Solaris & Windows now. Other platforms will + * XXX Only checking for Solaris, HP, & Windows now. Other platforms will * probably need something similar if they don't have u_int16_t or u_int32_t. */ @@ -57,6 +57,11 @@ typedef unsigned int u_int32_t; #endif +#if (defined(__hpux)) +typedef uint16_t u_int16_t; +typedef uint32_t u_int32_t; +#endif + #ifdef WIN32 typedef unsigned __int16 u_int16_t; typedef unsigned __int32 u_int32_t; @@ -219,6 +224,7 @@ enum byteorder order; /* Endianness of IFD. */ unsigned char *btiff; /* Beginning of TIFF (offset base). */ unsigned char *etiff; /* End of TIFF. */ + void *ifdoffs; /* List of IFD offsets (internal only). */ }; diff -Nru /tmp/FwWif1KFzu/exiftags-1.00/exifint.h /tmp/pv5QyHY9pH/exiftags-1.0.1/exifint.h --- /tmp/FwWif1KFzu/exiftags-1.00/exifint.h 2004-08-21 00:31:45.000000000 +0200 +++ /tmp/pv5QyHY9pH/exiftags-1.0.1/exifint.h 2007-12-16 01:48:22.000000000 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2003, Eric M. Johnston <[EMAIL PROTECTED]> + * Copyright (c) 2001-2007, Eric M. Johnston <[EMAIL PROTECTED]> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: exifint.h,v 1.29 2004/08/20 22:31:45 ejohnst Exp $ + * $Id: exifint.h,v 1.32 2007/12/16 00:48:22 ejohnst Exp $ */ /* @@ -88,6 +88,14 @@ }; +/* List of IFD offsets, to detect loops. */ + +struct ifdoff { + unsigned char *offset; /* Offset to IFD. */ + struct ifdoff *next; /* Next IFD in list. */ +}; + + /* Macro for making sense of a fraction. */ #define fixfract(str, n, d, t) { \ @@ -119,6 +127,7 @@ /* Utility functions from exifutil.c. */ +extern int offsanity(struct exifprop *prop, u_int16_t size, struct ifd *dir); extern u_int16_t exif2byte(unsigned char *b, enum byteorder o); extern int16_t exif2sbyte(unsigned char *b, enum byteorder o); extern u_int32_t exif4byte(unsigned char *b, enum byteorder o); diff -Nru /tmp/FwWif1KFzu/exiftags-1.00/exiftags.1 /tmp/pv5QyHY9pH/exiftags-1.0.1/exiftags.1 --- /tmp/FwWif1KFzu/exiftags-1.00/exiftags.1 2005-01-05 01:31:03.000000000 +0100 +++ /tmp/pv5QyHY9pH/exiftags-1.0.1/exiftags.1 2007-12-16 04:06:40.000000000 +0100 @@ -1,6 +1,6 @@ .TH EXIFTAGS 1 .\" -.\" Copyright (c) 2001-2005, Eric M. Johnston <[EMAIL PROTECTED]> +.\" Copyright (c) 2001-2007, Eric M. Johnston <[EMAIL PROTECTED]> .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -29,7 +29,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $Id: exiftags.1,v 1.27 2005/01/05 00:31:03 ejohnst Exp $ +.\" $Id: exiftags.1,v 1.29 2007/12/16 03:06:40 ejohnst Exp $ .\" .SH NAME .B exiftags @@ -77,7 +77,8 @@ .IR delim . The default is ': '. .IP -u -Output unknown or unsupported properties contained in the file. +Output unknown or unsupported properties contained in the file. Also, +output invalid properties when debugging information is requested. .IP -v Output verbose properties contained in the file. .SH MAKER NOTES @@ -148,6 +149,7 @@ .PP Special thanks to the following folks for submitting sample camera files: Bradley Bailey, Kirk Bauer, Marcy Brown, Frank Fortunato, Per Kristian Hove, -Stan Jirman, Kaye Kirsch, Kevin Layer, Henrik Levkowetz, Jamie Mayberry, -Jason Montojo, Nick Reid, Michael Shostak, Nathan Treadway, Mathieu Vanasse, +Brian Jackson, Stan Jirman, Kaye Kirsch, Meder Kydyraliev, Kevin Layer, +Henrik Levkowetz, Jamie Mayberry, Jason Montojo, Nick Reid, Frank Reiff, +Christian Schmid, Michael Shostak, Nathan Treadway, Mathieu Vanasse, Mark Westling, Phillip Wherry, and Christian Zuckschwerdt. diff -Nru /tmp/FwWif1KFzu/exiftags-1.00/exiftags.c /tmp/pv5QyHY9pH/exiftags-1.0.1/exiftags.c --- /tmp/FwWif1KFzu/exiftags-1.00/exiftags.c 2005-01-27 08:15:00.000000000 +0100 +++ /tmp/pv5QyHY9pH/exiftags-1.0.1/exiftags.c 2007-12-16 03:12:01.000000000 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2005, Eric M. Johnston <[EMAIL PROTECTED]> + * Copyright (c) 2001-2007, Eric M. Johnston <[EMAIL PROTECTED]> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: exiftags.c,v 1.26 2005/01/27 07:15:00 ejohnst Exp $ + * $Id: exiftags.c,v 1.28 2007/12/16 02:12:01 ejohnst Exp $ */ /* @@ -57,7 +57,7 @@ int quiet; -static const char *version = "1.00"; +static const char *version = "1.01"; static int fnum; static const char *delim = ": "; @@ -87,6 +87,9 @@ case ED_VRB: printf("Other Properties:\n\n"); break; + case ED_BAD: + printf("Invalid Properties:\n\n"); + break; } } @@ -97,9 +100,9 @@ if (list->lvl == ED_PAS) list->lvl = pas ? ED_CAM : ED_IMG; - /* For now, just treat overridden & bad values as verbose. */ + /* For now, just treat overridden values as verbose. */ - if (list->lvl == ED_OVR || list->lvl == ED_BAD) + if (list->lvl == ED_OVR) list->lvl = ED_VRB; if (list->lvl == lvl) { @@ -159,6 +162,8 @@ printprops(t->props, ED_VRB, pas); if (dumplvl & ED_UNK) printprops(t->props, ED_UNK, pas); + if (dumplvl & ED_BAD) + printprops(t->props, ED_BAD, pas); } exiffree(t); free(exifbuf); @@ -185,7 +190,8 @@ fprintf(stderr, " -c\tDisplay camera-specific properties.\n"); fprintf(stderr, " -i\tDisplay image-specific properties.\n"); fprintf(stderr, " -v\tDisplay verbose properties.\n"); - fprintf(stderr, " -u\tDisplay unknown/unsupported properties.\n"); + fprintf(stderr, " -u\tDisplay unknown/unsupported properties (also " + "invalid props w/debug).\n"); fprintf(stderr, " -l\tCamera has a removable lens.\n"); fprintf(stderr, " -d\tDisplay parse debug information.\n"); fprintf(stderr, " -q\tSuppress section headers.\n"); @@ -253,6 +259,9 @@ if (!dumplvl && !debug) dumplvl |= (ED_CAM | ED_IMG); + if (debug && (dumplvl & ED_UNK)) + dumplvl |= ED_BAD; + if (*argv) { for (fnum = 0; *argv; ++argv) { if ((fp = fopen(*argv, mode)) == NULL) { diff -Nru /tmp/FwWif1KFzu/exiftags-1.00/exiftime.1 /tmp/pv5QyHY9pH/exiftags-1.0.1/exiftime.1 --- /tmp/FwWif1KFzu/exiftags-1.00/exiftime.1 2004-04-10 09:45:04.000000000 +0200 +++ /tmp/pv5QyHY9pH/exiftags-1.0.1/exiftime.1 2007-12-16 03:19:25.000000000 +0100 @@ -1,6 +1,6 @@ .TH EXIFTIME 1 .\" -.\" Copyright (c) 2004, Eric M. Johnston <[EMAIL PROTECTED]> +.\" Copyright (c) 2004-2007, Eric M. Johnston <[EMAIL PROTECTED]> .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -29,7 +29,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $Id: exiftime.1,v 1.1 2004/04/10 07:45:04 ejohnst Exp $ +.\" $Id: exiftime.1,v 1.2 2007/12/16 02:19:25 ejohnst Exp $ .\" .SH NAME .B exiftime @@ -103,10 +103,15 @@ .IP -l List each input .I file -in ascending order by its Image Created tag. In the absence of -an Image Created tag, first Image Generated, then Image Digitized are used. -If no date and time tags are present, the OS's epoch is used. This flag -overrides all others. +in ascending order by timestamp. By default, it uses the Image Created tag. +In the absence of an Image Created tag, first Image Generated then Image +Digitized are used. Alternatively, the +.B -t +flag may be used to specify the timestamp preference for ordering. If no +date and time tags are present, the OS's epoch is used. This flag +overrides all others but the +.B -t +flag. .IP -q Do not output details of a date and time adjustment to standard out when using the @@ -236,6 +241,16 @@ example2.jpg: Image Generated: 2004:01:22 17:07:02 -> 2004:01:27 17:00:02 .fi +.PP +The command +.IP +.nf +exiftime -l -tdg *.jpg +.fi +.PP +will list all files that match "*.jpg", one per line, in ascending timestamp +order. It'll attempt to use the following timestamp values, in order: Image +Digitized, Image Generated, Image Created, and, finally, the OS's epoch. .SH DIAGNOSTICS The .B exiftime diff -Nru /tmp/FwWif1KFzu/exiftags-1.00/exiftime.c /tmp/pv5QyHY9pH/exiftags-1.0.1/exiftime.c --- /tmp/FwWif1KFzu/exiftags-1.00/exiftime.c 2005-01-27 08:15:01.000000000 +0100 +++ /tmp/pv5QyHY9pH/exiftags-1.0.1/exiftime.c 2007-12-16 03:18:51.000000000 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2005, Eric M. Johnston <[EMAIL PROTECTED]> + * Copyright (c) 2004-2007, Eric M. Johnston <[EMAIL PROTECTED]> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: exiftime.c,v 1.12 2005/01/27 07:15:01 ejohnst Exp $ + * $Id: exiftime.c,v 1.13 2007/12/16 02:18:51 ejohnst Exp $ */ /* @@ -63,7 +63,7 @@ time_t ts; }; -static const char *version = "1.00"; +static const char *version = "1.01"; static int iflag, lflag, qflag, wflag, ttags; static const char *delim = ": "; static const char *fname; @@ -91,8 +91,9 @@ fprintf(stderr, "Available options:\n"); fprintf(stderr, " -f\tAnswer 'yes' to any confirmation prompts.\n"); fprintf(stderr, " -i\tConfirm overwrites (default).\n"); - fprintf(stderr, " -l\tList files ordered by image created timestamp; " - "overrides -t, -v, -w.\n"); + fprintf(stderr, " -l\tList files ordered by timestamp, using image " + "created by default;\n\toverrides -v, -w. Use -t to change " + "timestamp preference.\n"); fprintf(stderr, " -q\tBe quiet when writing timestamps.\n"); fprintf(stderr, " -s\tSet delimiter to provided string " "(default: \": \").\n"); @@ -146,26 +147,24 @@ /* - * Grab the timestamps for listing. Doesn't modify the file. + * Grab the timestamps for listing in the specified order of preference. + * Doesn't modify the file. */ static int -listts(struct exiftags *t, struct linfo *li) +listts(struct exiftags *t, struct linfo *li, u_int16_t *tpref) { struct exifprop *p; struct tm tv; - /* - * Try for DateTime, DateTimeOriginal, then DateTimeDigitized. - * If none found, print error and list first. - */ + /* If no timestamp is found, print error and list first. */ - p = findprop(t->props, tags, EXIF_T_DATETIME); + p = findprop(t->props, tags, tpref[0]); if (!p || !p->str || etstrptm(p->str, &tv)) { - p = findprop(t->props, tags, EXIF_T_DATETIMEORIG); + p = findprop(t->props, tags, tpref[1]); if (!p || !p->str || etstrptm(p->str, &tv)) { - p = findprop(t->props, tags, EXIF_T_DATETIMEDIGI); + p = findprop(t->props, tags, tpref[2]); if (!p || !p->str || etstrptm(p->str, &tv)) { exifwarn("no timestamp available"); @@ -356,7 +355,7 @@ * Scan the JPEG file for Exif data and parse it. */ static int -doit(FILE *fp, int n) +doit(FILE *fp, int n, u_int16_t *tpref) { int mark, gotapp1, first, rc; unsigned int len, rlen; @@ -395,7 +394,7 @@ if (t && t->props) { gotapp1 = TRUE; if (lflag) - rc = listts(t, &lorder[n]); + rc = listts(t, &lorder[n], tpref); else rc = procall(fp, app1, t, exifbuf); } @@ -412,6 +411,34 @@ } +/* + * Fill in array of timestamps in order of preference. + */ +void +settpref(u_int16_t *tpref, u_int16_t tag) +{ + int i; + + /* Recursively fill in the remaining timestamps. */ + + if (tag == EXIF_T_UNKNOWN) { + settpref(tpref, EXIF_T_DATETIME); + settpref(tpref, EXIF_T_DATETIMEORIG); + settpref(tpref, EXIF_T_DATETIMEDIGI); + return; + } + + for (i = 0; i < 3; i++) { + if (tpref[i] == tag) + break; + if (tpref[i] == EXIF_T_UNKNOWN) { + tpref[i] = tag; + break; + } + } +} + + int main(int argc, char **argv) { @@ -419,6 +446,7 @@ int eval, fnum, wantall; char *rmode, *wmode; FILE *fp; + u_int16_t tpref[3]; progname = argv[0]; debug = FALSE; @@ -426,6 +454,7 @@ lflag = qflag = wflag = FALSE; iflag = TRUE; v = NULL; + tpref[0] = tpref[1] = tpref[2] = EXIF_T_UNKNOWN; #ifdef WIN32 rmode = "rb"; wmode = "r+b"; @@ -455,12 +484,15 @@ while (*optarg) { switch (*optarg) { case 'c': + settpref(tpref, EXIF_T_DATETIME); ttags |= ET_CREATE; break; case 'd': + settpref(tpref, EXIF_T_DATETIMEDIGI); ttags |= ET_DIGI; break; case 'g': + settpref(tpref, EXIF_T_DATETIMEORIG); ttags |= ET_GEN; break; case 'a': @@ -489,6 +521,10 @@ if (!*argv) usage(); + /* Finish up timestamp preferences. */ + + settpref(tpref, EXIF_T_UNKNOWN); + /* Don't be quiet if we're not writing. */ if (qflag && !wflag) @@ -525,7 +561,7 @@ if (lflag) lorder[fnum].fn = fname; - if (doit(fp, fnum)) + if (doit(fp, fnum, tpref)) eval = 1; fclose(fp); } diff -Nru /tmp/FwWif1KFzu/exiftags-1.00/exifutil.c /tmp/pv5QyHY9pH/exiftags-1.0.1/exifutil.c --- /tmp/FwWif1KFzu/exiftags-1.00/exifutil.c 2004-11-06 19:36:46.000000000 +0100 +++ /tmp/pv5QyHY9pH/exiftags-1.0.1/exifutil.c 2007-12-16 02:14:26.000000000 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2003, Eric M. Johnston <[EMAIL PROTECTED]> + * Copyright (c) 2001-2007, Eric M. Johnston <[EMAIL PROTECTED]> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: exifutil.c,v 1.26 2004/11/06 18:36:46 ejohnst Exp $ + * $Id: exifutil.c,v 1.31 2007/12/16 01:14:26 ejohnst Exp $ */ /* @@ -81,6 +81,60 @@ /* + * Sanity check a tag's count & value when used as an offset within + * the TIFF. Checks for overflows. Returns 0 if OK; !0 if not OK. + */ +int +offsanity(struct exifprop *prop, u_int16_t size, struct ifd *dir) +{ + u_int32_t tifflen; + const char *name; + + /* XXX Hrm. Should be OK with 64-bit addresses. */ + tifflen = dir->md.etiff - dir->md.btiff; + if (prop->name) + name = prop->name; + else + name = "Unknown"; + + if (!prop->count) { + if (prop->value > tifflen) { + exifwarn2("invalid field offset", name); + prop->lvl = ED_BAD; + return (1); + } + return (0); + } + + /* Does count * size overflow? */ + + if (size > (u_int32_t)(-1) / prop->count) { + exifwarn2("invalid field count", name); + prop->lvl = ED_BAD; + return (1); + } + + /* Does count * size + value overflow? */ + + if ((u_int32_t)(-1) - prop->value < prop->count * size) { + exifwarn2("invalid field offset", name); + prop->lvl = ED_BAD; + return (1); + } + + /* Is the offset valid? */ + + if (prop->value + prop->count * size > tifflen) { + exifwarn2("invalid field offset", name); + prop->lvl = ED_BAD; + return (1); + } + + return (0); +} + + +/* * Read an unsigned 2-byte int from the buffer. */ u_int16_t @@ -206,8 +260,8 @@ findprop(struct exifprop *prop, struct exiftag *tagset, u_int16_t tag) { - for (; prop && (prop->tagset != tagset || prop->tag != tag); - prop = prop->next); + for (; prop && (prop->tagset != tagset || prop->tag != tag || + prop->lvl == ED_BAD); prop = prop->next); return (prop); } @@ -300,7 +354,7 @@ for (i = 0; ftypes[i].type && ftypes[i].type != prop->type; i++); if (afield) { - printf(" %s (0x%04X): %s, %d; %d\n", prop->name, + printf(" %s (0x%04X): %s, %u; %u\n", prop->name, prop->tag, ftypes[i].name, prop->count, prop->value); printf(" "); @@ -327,10 +381,45 @@ readifd(u_int32_t offset, struct ifd **dir, struct exiftag *tagset, struct tiffmeta *md) { - u_int32_t ifdsize; + u_int32_t ifdsize, tifflen; unsigned char *b; + struct ifdoff *ifdoffs, *lastoff; + tifflen = md->etiff - md->btiff; b = md->btiff; + ifdoffs = (struct ifdoff *)(md->ifdoffs); + lastoff = NULL; + *dir = NULL; + + /* + * Check to see if we've already visited this offset. Otherwise + * we could loop. (Need to add in TIFF start for Nikon makernotes.) + */ + + while (ifdoffs && ifdoffs->offset != b + offset) { + lastoff = ifdoffs; + ifdoffs = ifdoffs->next; + } + if (ifdoffs) { + /* We'll only complain if debugging. */ + if (debug) exifwarn("loop in IFD reference"); + return (0); + } + + ifdoffs = (struct ifdoff *)malloc(sizeof(struct ifdoff)); + if (!ifdoffs) { + exifwarn2("can't allocate IFD offset record", + (const char *)strerror(errno)); + return (0); + } + ifdoffs->offset = offset + b; + ifdoffs->next = NULL; + + /* The 0th (first) IFD establishes our list on the master tiffmeta. */ + if (lastoff) + lastoff->next = ifdoffs; + else + md->ifdoffs = (void *)ifdoffs; /* * Verify that we have a valid offset. Some maker note IFDs prepend @@ -338,14 +427,15 @@ * (Number of directory entries is in the first 2 bytes.) */ - if (b + offset + 2 > md->etiff) { - *dir = NULL; + if ((u_int32_t)(-1) - offset < 2 || offset + 2 > tifflen) return (0); - } *dir = (struct ifd *)malloc(sizeof(struct ifd)); - if (!*dir) - exifdie((const char *)strerror(errno)); + if (!*dir) { + exifwarn2("can't allocate IFD record", + (const char *)strerror(errno)); + return (0); + } (*dir)->num = exif2byte(b + offset, md->order); (*dir)->par = NULL; @@ -353,12 +443,22 @@ (*dir)->md = *md; (*dir)->next = NULL; + /* Make sure ifdsize doesn't overflow. */ + + if ((*dir)->num && + sizeof(struct field) > (u_int32_t)(-1) / (*dir)->num) { + free(*dir); + *dir = NULL; + return (0); + } + ifdsize = (*dir)->num * sizeof(struct field); b += offset + 2; - /* Sanity check our sizes. */ + /* Sanity check our size (and check for overflows). */ - if (b + ifdsize > md->etiff) { + if ((u_int32_t)(-1) - (offset + 2) < ifdsize || + offset + 2 + ifdsize > tifflen) { free(*dir); *dir = NULL; return (0); @@ -393,11 +493,6 @@ { struct ifd *firstifd, *curifd; - /* - * XXX Note: we really should be checking to see if this IFD - * has already been visited... - */ - /* Fetch our first one. */ offset = readifd(offset, &firstifd, tagset, md); diff -Nru /tmp/FwWif1KFzu/exiftags-1.00/Makefile /tmp/pv5QyHY9pH/exiftags-1.0.1/Makefile --- /tmp/FwWif1KFzu/exiftags-1.00/Makefile 2008-01-04 15:45:55.000000000 +0100 +++ /tmp/pv5QyHY9pH/exiftags-1.0.1/Makefile 2005-01-05 01:30:32.000000000 +0100 @@ -19,10 +19,10 @@ CFLAGS=$(DEBUG) DESTDIR= -prefix=/usr/ -datadir=$(DESTDIR)$(prefix)/share/ +prefix=/usr/local +datadir=$(DESTDIR)$(prefix) bindir=$(DESTDIR)$(prefix)/bin -mandir=$(datadir)/man/man1 +mandir=$(datadir)/man OBJS=exif.o tagdefs.o exifutil.o exifgps.o jpeg.o HDRS=exif.h exifint.h jpeg.h makers.h @@ -51,6 +51,6 @@ install: all cp exiftags exifcom exiftime $(bindir) chmod 0755 $(bindir)/exiftags $(bindir)/exifcom $(bindir)/exiftime - mkdir -p $(mandir) - cp exiftags.1 exifcom.1 exiftime.1 $(mandir) - chmod 0644 $(mandir)/exiftags.1 $(mandir)/exifcom.1 $(mandir)/exiftime.1 + cp exiftags.1 exifcom.1 exiftime.1 $(mandir)/man1 + chmod 0644 $(mandir)/man1/exiftags.1 $(mandir)/man1/exifcom.1 \ + $(mandir)/man1/exiftime.1 diff -Nru /tmp/FwWif1KFzu/exiftags-1.00/minolta.c /tmp/pv5QyHY9pH/exiftags-1.0.1/minolta.c --- /tmp/FwWif1KFzu/exiftags-1.00/minolta.c 2004-12-23 21:38:52.000000000 +0100 +++ /tmp/pv5QyHY9pH/exiftags-1.0.1/minolta.c 2007-12-15 22:01:23.000000000 +0100 @@ -1,6 +1,6 @@ /* * Copyright (c) 2003, Javier Crespo <[EMAIL PROTECTED]> - * Copyright (c) 2003, Eric M. Johnston <[EMAIL PROTECTED]> + * Copyright (c) 2003-2007, Eric M. Johnston <[EMAIL PROTECTED]> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: minolta.c,v 1.28 2004/12/23 20:38:52 ejohnst Exp $ + * $Id: minolta.c,v 1.29 2007/12/15 21:01:23 ejohnst Exp $ * */ @@ -664,7 +664,8 @@ prop->str = NULL; exifstralloc(&prop->str, strlen(na) + 1); strcpy(prop->str, na); - prop->lvl = ED_BAD; + if (!(prop->lvl & ED_UNK)) + prop->lvl = ED_VRB; } diff -Nru /tmp/FwWif1KFzu/exiftags-1.00/README /tmp/pv5QyHY9pH/exiftags-1.0.1/README --- /tmp/FwWif1KFzu/exiftags-1.00/README 2005-01-27 08:15:00.000000000 +0100 +++ /tmp/pv5QyHY9pH/exiftags-1.0.1/README 2007-12-16 03:20:55.000000000 +0100 @@ -1,5 +1,5 @@ -exiftags-1.00 -20050126 +exiftags-1.01 +20071215 Eric M. Johnston, [EMAIL PROTECTED] This package consists of three utilities for displaying and modifying @@ -49,4 +49,4 @@ [EMAIL PROTECTED] The latest version of this software will be posted at http://johnst.org/sw/exiftags/. -$Id: README,v 1.16 2005/01/27 07:15:00 ejohnst Exp $ +$Id: README,v 1.17 2007/12/16 02:20:55 ejohnst Exp $
pgpQrhGgCrAnf.pgp
Description: PGP signature