File bug-771229_CVE-2012-2814.patch of Package libexif

Update of /cvsroot/libexif/libexif/libexif
In directory vz-cvs-4.sog:/tmp/cvs-serv18066/libexif

Modified Files:
	exif-entry.c 
Log Message:
Fixed some buffer overflows in exif_entry_format_value()
This fixes CVE-2012-2814


Index: libexif/exif-entry.c
===================================================================
--- libexif/exif-entry.c.orig
+++ libexif/exif-entry.c
@@ -451,12 +451,13 @@ exif_entry_format_value(ExifEntry *e, ch
 	ExifRational v_rat;
 	ExifSRational v_srat;
 	ExifSLong v_slong;
-	char b[64];
 	unsigned int i;
+	size_t len;
 	const ExifByteOrder o = exif_data_get_byte_order (e->parent->parent);
 
-	if (!e->size)
+	if (!e->size || !maxlen)
 		return;
+	++maxlen; /* include the terminating NUL */
 	switch (e->format) {
 	case EXIF_FORMAT_UNDEFINED:
 		snprintf (val, maxlen, _("%i bytes undefined data"), e->size);
@@ -465,77 +466,74 @@ exif_entry_format_value(ExifEntry *e, ch
 	case EXIF_FORMAT_SBYTE:
 		v_byte = e->data[0];
 		snprintf (val, maxlen, "0x%02x", v_byte);
-		maxlen -= strlen (val);
+		len = strlen (val);
 		for (i = 1; i < e->components; i++) {
 			v_byte = e->data[i];
-			snprintf (b, sizeof (b), ", 0x%02x", v_byte);
-			strncat (val, b, maxlen);
-			maxlen -= strlen (b);
-			if ((signed)maxlen <= 0) break;
+			snprintf (val+len, maxlen-len, ", 0x%02x", v_byte);
+			len += strlen (val+len);
+			if (len >= maxlen-1) break;
 		}
 		break;
 	case EXIF_FORMAT_SHORT:
 		v_short = exif_get_short (e->data, o);
 		snprintf (val, maxlen, "%u", v_short);
-		maxlen -= strlen (val);
+		len = strlen (val);
 		for (i = 1; i < e->components; i++) {
 			v_short = exif_get_short (e->data +
 				exif_format_get_size (e->format) * i, o);
-			snprintf (b, sizeof (b), ", %u", v_short);
-			strncat (val, b, maxlen);
-			maxlen -= strlen (b);
-			if ((signed)maxlen <= 0) break;
+			snprintf (val+len, maxlen-len, ", %u", v_short);
+			len += strlen (val+len);
+			if (len >= maxlen-1) break;
 		}
 		break;
 	case EXIF_FORMAT_SSHORT:
 		v_sshort = exif_get_sshort (e->data, o);
 		snprintf (val, maxlen, "%i", v_sshort);
-		maxlen -= strlen (val);
+		len = strlen (val);
 		for (i = 1; i < e->components; i++) {
 			v_sshort = exif_get_short (e->data +
 				exif_format_get_size (e->format) *
 				i, o);
-			snprintf (b, sizeof (b), ", %i", v_sshort);
-			strncat (val, b, maxlen);
-			maxlen -= strlen (b);
-			if ((signed)maxlen <= 0) break;
+			snprintf (val+len, maxlen-len, ", %i", v_sshort);
+			len += strlen (val+len);
+			if (len >= maxlen-1) break;
 		}
 		break;
 	case EXIF_FORMAT_LONG:
 		v_long = exif_get_long (e->data, o);
 		snprintf (val, maxlen, "%lu", (unsigned long) v_long);
-		maxlen -= strlen (val);
+		len = strlen (val);
 		for (i = 1; i < e->components; i++) {
 			v_long = exif_get_long (e->data +
 				exif_format_get_size (e->format) *
 				i, o);
-			snprintf (b, sizeof (b), ", %lu", (unsigned long) v_long);
-			strncat (val, b, maxlen);
-			maxlen -= strlen (b);
-			if ((signed)maxlen <= 0) break;
+			snprintf (val+len, maxlen-len, ", %lu", (unsigned long) v_long);
+			len += strlen (val+len);
+			if (len >= maxlen-1) break;
 		}
 		break;
 	case EXIF_FORMAT_SLONG:
 		v_slong = exif_get_slong (e->data, o);
 		snprintf (val, maxlen, "%li", (long) v_slong);
-		maxlen -= strlen (val);
+		len = strlen (val);
 		for (i = 1; i < e->components; i++) {
 			v_slong = exif_get_slong (e->data +
 				exif_format_get_size (e->format) * i, o);
-			snprintf (b, sizeof (b), ", %li", (long) v_slong);
-			strncat (val, b, maxlen);
-			maxlen -= strlen (b);
-			if ((signed)maxlen <= 0) break;
+			snprintf (val+len, maxlen-len, ", %li", (long) v_slong);
+			len += strlen (val+len);
+			if (len >= maxlen-1) break;
 		}
 		break;
 	case EXIF_FORMAT_ASCII:
-		strncpy (val, (char *) e->data, MIN (maxlen, e->size));
+		strncpy (val, (char *) e->data, MIN (maxlen-1, e->size));
+		val[MIN (maxlen-1, e->size)] = 0;
 		break;
 	case EXIF_FORMAT_RATIONAL:
+		len = 0;
 		for (i = 0; i < e->components; i++) {
 			if (i > 0) {
-				strncat (val, ", ", maxlen);
-				maxlen -= 2;
+				snprintf (val+len, maxlen-len, ", ");
+				len += strlen (val+len);
 			}
 			v_rat = exif_get_rational (
 				e->data + 8 * i, o);
@@ -547,40 +545,39 @@ exif_entry_format_value(ExifEntry *e, ch
 				 * range 13..120 will show 2 decimal points.
 				 */
 				int decimals = (int)(log10(v_rat.denominator)-0.08+1.0);
-				snprintf (b, sizeof (b), "%2.*f",
+				snprintf (val+len, maxlen-len, "%2.*f",
 					  decimals,
 					  (double) v_rat.numerator /
 					  (double) v_rat.denominator);
 			} else
-				snprintf (b, sizeof (b), "%lu/%lu",
+				snprintf (val+len, maxlen-len, "%lu/%lu",
 				  (unsigned long) v_rat.numerator,
 				  (unsigned long) v_rat.denominator);
-			strncat (val, b, maxlen);
-			maxlen -= strlen (b);
-			if ((signed) maxlen <= 0) break;
+			len += strlen (val+len);
+			if (len >= maxlen-1) break;
 		}
 		break;
 	case EXIF_FORMAT_SRATIONAL:
+		len = 0;
 		for (i = 0; i < e->components; i++) {
 			if (i > 0) {
-				strncat (val, ", ", maxlen);
-				maxlen -= 2;
+				snprintf (val+len, maxlen-len, ", ");
+				len += strlen (val+len);
 			}
 			v_srat = exif_get_srational (
 				e->data + 8 * i, o);
 			if (v_srat.denominator) {
 				int decimals = (int)(log10(fabs(v_srat.denominator))-0.08+1.0);
-				snprintf (b, sizeof (b), "%2.*f",
+				snprintf (val+len, maxlen-len, "%2.*f",
 					  decimals,
 					  (double) v_srat.numerator /
 					  (double) v_srat.denominator);
 			} else
-				snprintf (b, sizeof (b), "%li/%li",
+				snprintf (val+len, maxlen-len, "%li/%li",
 				  (long) v_srat.numerator,
 				  (long) v_srat.denominator);
-			strncat (val, b, maxlen);
-			maxlen -= strlen (b);
-			if ((signed) maxlen <= 0) break;
+			len += strlen (val+len);
+			if (len >= maxlen-1) break;
 		}
 		break;
 	case EXIF_FORMAT_DOUBLE:
openSUSE Build Service is sponsored by