Fetch libexif 0.6.21 to include the security fixes.

BUG=none
TEST=none
Review URL: https://chromiumcodereview.appspot.com/10792004

git-svn-id: http://src.chromium.org/svn/trunk/deps/third_party/libexif/sources@146817 4ff67af0-8c30-449e-8e8b-ad334ec8d88c
diff --git a/config.h b/config.h
index 7857662..b443000 100644
--- a/config.h
+++ b/config.h
@@ -69,19 +69,19 @@
 #define PACKAGE_NAME "EXIF library"
 
 /* Define to the full name and version of this package. */
-#define PACKAGE_STRING "EXIF library 0.6.20"
+#define PACKAGE_STRING "EXIF library 0.6.21"
 
 /* Define to the one symbol short name of this package. */
 #define PACKAGE_TARNAME "libexif"
 
 /* Define to the version of this package. */
-#define PACKAGE_VERSION "0.6.20"
+#define PACKAGE_VERSION "0.6.21"
 
 /* Define to 1 if you have the ANSI C header files. */
 #define STDC_HEADERS 1
 
 /* Version number of package */
-#define VERSION "0.6.20"
+#define VERSION "0.6.21"
 
 #elif !defined(__APPLE__)
 /* config.h.  Generated by configure.  */
@@ -157,19 +157,19 @@
 #define PACKAGE_NAME "EXIF library"
 
 /* Define to the full name and version of this package. */
-#define PACKAGE_STRING "EXIF library 0.6.20"
+#define PACKAGE_STRING "EXIF library 0.6.21"
 
 /* Define to the one symbol short name of this package. */
 #define PACKAGE_TARNAME "libexif"
 
 /* Define to the version of this package. */
-#define PACKAGE_VERSION "0.6.20"
+#define PACKAGE_VERSION "0.6.21"
 
 /* Define to 1 if you have the ANSI C header files. */
 #define STDC_HEADERS 1
 
 /* Version number of package */
-#define VERSION "0.6.20"
+#define VERSION "0.6.21"
 
 /* Define to empty if `const' does not conform to ANSI C. */
 /* #undef const */
@@ -251,19 +251,19 @@
 #define PACKAGE_NAME "EXIF library"
 
 /* Define to the full name and version of this package. */
-#define PACKAGE_STRING "EXIF library 0.6.20"
+#define PACKAGE_STRING "EXIF library 0.6.21"
 
 /* Define to the one symbol short name of this package. */
 #define PACKAGE_TARNAME "libexif"
 
 /* Define to the version of this package. */
-#define PACKAGE_VERSION "0.6.20"
+#define PACKAGE_VERSION "0.6.21"
 
 /* Define to 1 if you have the ANSI C header files. */
 #define STDC_HEADERS 1
 
 /* Version number of package */
-#define VERSION "0.6.20"
+#define VERSION "0.6.21"
 
 /* Define to empty if `const' does not conform to ANSI C. */
 /* #undef const */
@@ -339,19 +339,19 @@
 #define PACKAGE_NAME "EXIF library"
 
 /* Define to the full name and version of this package. */
-#define PACKAGE_STRING "EXIF library 0.6.20"
+#define PACKAGE_STRING "EXIF library 0.6.21"
 
 /* Define to the one symbol short name of this package. */
 #define PACKAGE_TARNAME "libexif"
 
 /* Define to the version of this package. */
-#define PACKAGE_VERSION "0.6.20"
+#define PACKAGE_VERSION "0.6.21"
 
 /* Define to 1 if you have the ANSI C header files. */
 #define STDC_HEADERS 1
 
 /* Version number of package */
-#define VERSION "0.6.20"
+#define VERSION "0.6.21"
 
 /* Define to empty if `const' does not conform to ANSI C. */
 /* #undef const */
diff --git a/libexif/canon/mnote-canon-entry.c b/libexif/canon/mnote-canon-entry.c
index 6e3be19..b92f69c 100644
--- a/libexif/canon/mnote-canon-entry.c
+++ b/libexif/canon/mnote-canon-entry.c
@@ -216,10 +216,12 @@
   {21,  29, N_("Canon EF 50mm f/1.8 MkII")},
   {21,  31, N_("Tamron SP AF 300mm f/2.8 LD IF")},
   {21,  32, N_("Canon EF 24mm f/2.8 or Sigma 15mm f/2.8 EX Fisheye")},
+  {21,  37, N_("Canon EF 35-80mm f/4-5.6")},
   {21,  39, N_("Canon EF 75-300mm f/4-5.6")},
   {21,  40, N_("Canon EF 28-80mm f/3.5-5.6")},
   {21,  43, N_("Canon EF 28-105mm f/4-5.6")},
   {21,  45, N_("Canon EF-S 18-55mm f/3.5-5.6")},
+  {21,  52, N_("Canon EF-S 18-55mm f/3.5-5.6 IS II")},
   {21, 124, N_("Canon MP-E 65mm f/2.8 1-5x Macro Photo")},
   {21, 125, N_("Canon TS-E 24mm f/3.5L")},
   {21, 126, N_("Canon TS-E 45mm f/2.8")},
@@ -282,6 +284,7 @@
   {21, 238, N_("Canon EF 70-300mm F4-5.6 IS USM")},
   {21, 241, N_("Canon EF 50mm F1.2L USM")},
   {21, 242, N_("Canon EF 70-200mm f/4L IS USM")},
+  {21, 251, N_("Canon EF 70-200mm f/2.8L IS II USM")},
   {28, 0, N_("Manual")},
   {28, 1, N_("TTL")},
   {28, 2, N_("A-TTL")},
diff --git a/libexif/canon/mnote-canon-tag.c b/libexif/canon/mnote-canon-tag.c
index 6ced674..22d22d5 100644
--- a/libexif/canon/mnote-canon-tag.c
+++ b/libexif/canon/mnote-canon-tag.c
@@ -161,7 +161,7 @@
 	unsigned int i;
 
 #if defined(BIND_TEXTDOMAIN)
-	bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+        bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
 #endif
 	for (i = 0; i < sizeof (table) / sizeof (table[0]); i++)
 		if (table[i].tag == t) return (_(table[i].title));
@@ -194,10 +194,10 @@
 
 	for (i = 0; i < sizeof (table) / sizeof (table[0]); i++)
 		if (table[i].tag == t) {
-			if (!*table[i].description)
+			if (!table[i].description || !*table[i].description)
 				return "";
 #if defined(BIND_TEXTDOMAIN)
-                	bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+			bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
 #endif
 			return _(table[i].description);
 		}
diff --git a/libexif/exif-byte-order.h b/libexif/exif-byte-order.h
index ab5c9ad..10ded49 100644
--- a/libexif/exif-byte-order.h
+++ b/libexif/exif-byte-order.h
@@ -1,5 +1,7 @@
-/* exif-byte-order.h
- *
+/*! \file exif-byte-order.h
+ * \brief Defines the ExifByteOrder enum and the associated functions.
+ */
+/* 
  * Copyright (c) 2002 Lutz Mueller <lutz@users.sourceforge.net>
  *
  * This library is free software; you can redistribute it and/or
diff --git a/libexif/exif-data.c b/libexif/exif-data.c
index 80533b6..67df4db 100644
--- a/libexif/exif-data.c
+++ b/libexif/exif-data.c
@@ -781,15 +781,15 @@
 
 void
 exif_data_load_data (ExifData *data, const unsigned char *d_orig,
-		     unsigned int ds_orig)
+		     unsigned int ds)
 {
 	unsigned int l;
 	ExifLong offset;
 	ExifShort n;
 	const unsigned char *d = d_orig;
-	unsigned int ds = ds_orig, len;
+	unsigned int len, fullds;
 
-	if (!data || !data->priv || !d || !ds) 
+	if (!data || !data->priv || !d || !ds)
 		return;
 
 	exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
@@ -807,21 +807,21 @@
 		exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
 			  "Found EXIF header.");
 	} else {
-		while (1) {
-			while ((d[0] == 0xff) && ds) {
+		while (ds >= 3) {
+			while (ds && (d[0] == 0xff)) {
 				d++;
 				ds--;
 			}
 
 			/* JPEG_MARKER_SOI */
-			if (d[0] == JPEG_MARKER_SOI) {
+			if (ds && d[0] == JPEG_MARKER_SOI) {
 				d++;
 				ds--;
 				continue;
 			}
 
 			/* JPEG_MARKER_APP0 */
-			if (d[0] == JPEG_MARKER_APP0) {
+			if (ds >= 3 && d[0] == JPEG_MARKER_APP0) {
 				d++;
 				ds--;
 				l = (d[0] << 8) | d[1];
@@ -833,7 +833,7 @@
 			}
 
 			/* JPEG_MARKER_APP1 */
-			if (d[0] == JPEG_MARKER_APP1)
+			if (ds && d[0] == JPEG_MARKER_APP1)
 				break;
 
 			/* Unknown marker or data. Give up. */
@@ -841,12 +841,12 @@
 				  "ExifData", _("EXIF marker not found."));
 			return;
 		}
-		d++;
-		ds--;
-		if (ds < 2) {
+		if (ds < 3) {
 			LOG_TOO_SMALL;
 			return;
 		}
+		d++;
+		ds--;
 		len = (d[0] << 8) | d[1];
 		exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
 			  "We have to deal with %i byte(s) of EXIF data.",
@@ -872,9 +872,18 @@
 	exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
 		  "Found EXIF header.");
 
-	/* Byte order (offset 6, length 2) */
+	/* Sanity check the data length */
 	if (ds < 14)
 		return;
+
+	/* The JPEG APP1 section can be no longer than 64 KiB (including a
+	   16-bit length), so cap the data length to protect against overflow
+	   in future offset calculations */
+	fullds = ds;
+	if (ds > 0xfffe)
+		ds = 0xfffe;
+
+	/* Byte order (offset 6, length 2) */
 	if (!memcmp (d + 6, "II", 2))
 		data->priv->order = EXIF_BYTE_ORDER_INTEL;
 	else if (!memcmp (d + 6, "MM", 2))
@@ -894,24 +903,25 @@
 	exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", 
 		  "IFD 0 at %i.", (int) offset);
 
+	/* Sanity check the offset, being careful about overflow */
+	if (offset > ds || offset + 6 + 2 > ds)
+		return;
+
 	/* Parse the actual exif data (usually offset 14 from start) */
 	exif_data_load_data_content (data, EXIF_IFD_0, d + 6, ds - 6, offset, 0);
 
 	/* IFD 1 offset */
-	if (offset + 6 + 2 > ds) {
-		return;
-	}
 	n = exif_get_short (d + 6 + offset, data->priv->order);
-	if (offset + 6 + 2 + 12 * n + 4 > ds) {
+	if (offset + 6 + 2 + 12 * n + 4 > ds)
 		return;
-	}
+
 	offset = exif_get_long (d + 6 + offset + 2 + 12 * n, data->priv->order);
 	if (offset) {
 		exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
 			  "IFD 1 at %i.", (int) offset);
 
 		/* Sanity check. */
-		if (offset > ds - 6) {
+		if (offset > ds || offset + 6 > ds) {
 			exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA,
 				  "ExifData", "Bogus offset of IFD1.");
 		} else {
@@ -925,7 +935,7 @@
 	 * space between IFDs. Here is the only place where we have access
 	 * to that data.
 	 */
-	interpret_maker_note(data, d, ds);
+	interpret_maker_note(data, d, fullds);
 
 	/* Fixup tags if requested */
 	if (data->priv->options & EXIF_DATA_OPTION_FOLLOW_SPECIFICATION)
diff --git a/libexif/exif-data.h b/libexif/exif-data.h
index 1bcc4e5..eeee782 100644
--- a/libexif/exif-data.h
+++ b/libexif/exif-data.h
@@ -95,8 +95,9 @@
 /*! Load the #ExifData structure from the raw JPEG or EXIF data in the given
  * memory buffer. If the EXIF data contains a recognized MakerNote, it is
  * loaded and stored as well for later retrieval by #exif_data_get_mnote_data.
- * If the EXIF_DATA_OPTION_FOLLOW_SPECIFICATION has been set on this #ExifData,
- * then the tags are fixed after loading.
+ * If the #EXIF_DATA_OPTION_FOLLOW_SPECIFICATION option has been set on this
+ * #ExifData, then the tags are automatically fixed after loading (by calling
+ * #exif_data_fix).
  *
  * \param[in,out] data EXIF data
  * \param[in] d pointer to raw JPEG or EXIF data
diff --git a/libexif/exif-entry.c b/libexif/exif-entry.c
index 7f3ae55..d998fed 100644
--- a/libexif/exif-entry.c
+++ b/libexif/exif-entry.c
@@ -1351,10 +1351,23 @@
 	case EXIF_TAG_XP_AUTHOR:
 	case EXIF_TAG_XP_KEYWORDS:
 	case EXIF_TAG_XP_SUBJECT:
-		/* Warning! The texts are converted from UTF16 to UTF8 */
-		/* FIXME: use iconv to convert into the locale encoding */
-		exif_convert_utf16_to_utf8(val, (unsigned short*)e->data, MIN(maxlen, e->size));
-		break;
+        {
+                /* Sanity check the size to prevent overflow */
+                if (e->size+sizeof(unsigned short) < e->size) break;
+                
+                /* The tag may not be U+0000-terminated , so make a local
+                U+0000-terminated copy before converting it */
+                unsigned short *utf16 = exif_mem_alloc (e->priv->mem, e->size+sizeof(unsigned short));
+                if (!utf16) break;
+                memcpy(utf16, e->data, e->size);
+                utf16[e->size/sizeof(unsigned short)] = 0;
+
+                /* Warning! The texts are converted from UTF16 to UTF8 */
+                /* FIXME: use iconv to convert into the locale encoding */
+                exif_convert_utf16_to_utf8(val, utf16, maxlen);
+                exif_mem_free(e->priv->mem, utf16);
+                break;
+       }
 
 	default:
 		/* Use a generic value formatting */
diff --git a/libexif/exif-tag.c b/libexif/exif-tag.c
index 433d6cc..b0650d5 100644
--- a/libexif/exif-tag.c
+++ b/libexif/exif-tag.c
@@ -193,7 +193,7 @@
 	{EXIF_TAG_GPS_DEST_DISTANCE_REF, "GPSDestDistanceRef", N_("Reference for Distance to Destination"),
          N_("Indicates the unit used to express the distance to the "
             "destination point. 'K', 'M' and 'N' represent kilometers, miles "
-            "and knots."), ESL_GPS},
+            "and nautical miles."), ESL_GPS},
 	{EXIF_TAG_GPS_DEST_DISTANCE, "GPSDestDistance", N_("Distance to Destination"),
 	 N_("Indicates the distance to the destination point."), ESL_GPS},
 	{EXIF_TAG_GPS_PROCESSING_METHOD, "GPSProcessingMethod", N_("Name of GPS Processing Method"),
diff --git a/libexif/exif-utils.h b/libexif/exif-utils.h
index 38d0f67..5ce84ac 100644
--- a/libexif/exif-utils.h
+++ b/libexif/exif-utils.h
@@ -32,10 +32,9 @@
 #include <libexif/_stdint.h>
 #include "config.h"
 
-
 /* If these definitions don't work for you, please let us fix the 
  * macro generating _stdint.h */
-
+	
 /*! EXIF Unsigned Byte data type */
 typedef unsigned char	ExifByte;          /* 1 byte  */
 	
diff --git a/libexif/fuji/mnote-fuji-tag.c b/libexif/fuji/mnote-fuji-tag.c
index 4078037..8ba73e7 100644
--- a/libexif/fuji/mnote-fuji-tag.c
+++ b/libexif/fuji/mnote-fuji-tag.c
@@ -98,7 +98,7 @@
 
 	for (i = 0; i < sizeof (table) / sizeof (table[0]); i++)
 		if (table[i].tag == t) {
-			if (!*table[i].description)
+			if (!table[i].description || !*table[i].description)
 				return "";
 #if defined(BIND_TEXTDOMAIN)
 			bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
diff --git a/libexif/olympus/mnote-olympus-entry.c b/libexif/olympus/mnote-olympus-entry.c
index 9db5224..96c919d 100644
--- a/libexif/olympus/mnote-olympus-entry.c
+++ b/libexif/olympus/mnote-olympus-entry.c
@@ -76,6 +76,9 @@
 	}                                                               \
 }
 
+#define R2L(n) ((n).denominator ? (long)(n).numerator/(n).denominator : 0L)
+#define R2D(n) ((n).denominator ? (double)(n).numerator/(n).denominator : 0.0)
+
 static const struct {
 	ExifTag tag;
 	ExifFormat fmt;
@@ -287,6 +290,9 @@
 	if ((!entry->data) && (entry->components > 0)) 
 		return (v);
 
+	if ((!entry->data) && (entry->size > 0))
+		return NULL;  /* internal inconsistency error */
+
 	switch (entry->tag) {
 	
 	/* Nikon */
@@ -369,20 +375,20 @@
 		CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen);
 		CC (entry->components, 4, v, maxlen);
 		vr = exif_get_rational (entry->data, entry->order);
-		r = (double)vr.numerator / vr.denominator;
+		r = R2D(vr);
 		vr = exif_get_rational (entry->data+8, entry->order);
-		b = (double)vr.numerator / vr.denominator;
+		b = R2D(vr);
 		snprintf (v, maxlen, _("Red Correction %f, blue Correction %f"), r,b);
 		break;
 	case MNOTE_NIKON_TAG_MANUALFOCUSDISTANCE:
 		CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen);
 		CC (entry->components, 1, v, maxlen);
 		vr = exif_get_rational (entry->data, entry->order);
-		if (vr.numerator) {
-			r = (double)vr.numerator / vr.denominator;
-			snprintf (v, maxlen, _("%2.2f meters"), r);
-		} else {
+		if (!vr.numerator || !vr.denominator) {
 			strncpy (v, _("No manual focus selection"), maxlen);
+		} else {
+			r = R2D(vr);
+			snprintf (v, maxlen, _("%2.2f meters"), r);
 		}
 		break;
 	case MNOTE_NIKON_TAG_SENSORPIXELSIZE:
@@ -390,8 +396,8 @@
 		CC (entry->components, 2, v, maxlen);
 		vr = exif_get_rational (entry->data, entry->order);
 		vr2 = exif_get_rational (entry->data+8, entry->order);
-		r = (double)vr.numerator / vr.denominator;
-		b = (double)vr2.numerator / vr2.denominator;
+		r = R2D(vr);
+		b = R2D(vr2);
 		snprintf (v, maxlen, "%2.2f x %2.2f um", r, b);
 		break;
 	case MNOTE_NIKON_TAG_BRACKETING:
@@ -447,10 +453,10 @@
 		if (entry->format == EXIF_FORMAT_RATIONAL) {
 			CC (entry->components, 1, v, maxlen);
 			vr = exif_get_rational (entry->data, entry->order);
-			if (!vr.numerator) {
+			if (!vr.numerator || !vr.denominator) {
 				strncpy (v, _("None"), maxlen);
 			} else {
-				r = (double)vr.numerator / vr.denominator;
+				r = R2D(vr);
 				snprintf (v, maxlen, "%2.2f", r);
 			}
 			break;
@@ -565,13 +571,13 @@
 			double c,d;
 			unsigned long a,b;
 			vr = exif_get_rational (entry->data, entry->order);
-			a = vr.numerator / vr.denominator;
+			a = R2L(vr);
 			vr = exif_get_rational (entry->data+8, entry->order);
-			b = vr.numerator / vr.denominator;
+			b = R2L(vr);
 			vr = exif_get_rational (entry->data+16, entry->order);
-			c = (double)vr.numerator / vr.denominator;
+			c = R2D(vr);
 			vr = exif_get_rational (entry->data+24, entry->order);
-			d = (double)vr.numerator / vr.denominator;
+			d = R2D(vr);
 			snprintf (v, maxlen, "%ld-%ldmm 1:%3.1f - %3.1f",a,b,c,d);
 		}
 		break;
@@ -679,7 +685,7 @@
 		CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen);
 		CC (entry->components, 1, v, maxlen);
 		vr = exif_get_rational (entry->data, entry->order);
-		if (vr.numerator == 0) {
+		if (!vr.numerator || !vr.denominator) {
 			strncpy (v, _("Unknown"), maxlen);
 		}
 		else {
@@ -790,7 +796,7 @@
 			if (!vr.denominator) {
 				strncpy (v, _("Infinite"), maxlen);
 			} else {
-				r = (double)vr.numerator / vr.denominator;
+				r = R2D(vr);
 				snprintf (v, maxlen, "%2.3f", r);
 			}
 			break;
@@ -800,7 +806,7 @@
 			if (!vsr.denominator) {
 				strncpy (v, _("Infinite"), maxlen);
 			} else {
-				r = (double)vsr.numerator / vsr.denominator;
+				r = R2D(vsr);
 				snprintf (v, maxlen, "%2.3f", r);
 			}
 			break;