Blame SOURCES/libtiff-CVE-2013-1960.patch

7c98bb
diff -Naur tiff-4.0.3.orig/tools/tiff2pdf.c tiff-4.0.3/tools/tiff2pdf.c
7c98bb
--- tiff-4.0.3.orig/tools/tiff2pdf.c	2012-07-25 22:56:43.000000000 -0400
7c98bb
+++ tiff-4.0.3/tools/tiff2pdf.c	2013-05-02 12:04:49.057090227 -0400
7c98bb
@@ -3341,33 +3341,56 @@
7c98bb
 	uint32 height){
7c98bb
 
7c98bb
 	tsize_t i=0;
7c98bb
-	uint16 ri =0;
7c98bb
-	uint16 v_samp=1;
7c98bb
-	uint16 h_samp=1;
7c98bb
-	int j=0;
7c98bb
-	
7c98bb
-	i++;
7c98bb
-	
7c98bb
-	while(i<(*striplength)){
7c98bb
+
7c98bb
+	while (i < *striplength) {
7c98bb
+		tsize_t datalen;
7c98bb
+		uint16 ri;
7c98bb
+		uint16 v_samp;
7c98bb
+		uint16 h_samp;
7c98bb
+		int j;
7c98bb
+		int ncomp;
7c98bb
+
7c98bb
+		/* marker header: one or more FFs */
7c98bb
+		if (strip[i] != 0xff)
7c98bb
+			return(0);
7c98bb
+		i++;
7c98bb
+		while (i < *striplength && strip[i] == 0xff)
7c98bb
+			i++;
7c98bb
+		if (i >= *striplength)
7c98bb
+			return(0);
7c98bb
+		/* SOI is the only pre-SOS marker without a length word */
7c98bb
+		if (strip[i] == 0xd8)
7c98bb
+			datalen = 0;
7c98bb
+		else {
7c98bb
+			if ((*striplength - i) <= 2)
7c98bb
+				return(0);
7c98bb
+			datalen = (strip[i+1] << 8) | strip[i+2];
7c98bb
+			if (datalen < 2 || datalen >= (*striplength - i))
7c98bb
+				return(0);
7c98bb
+		}
7c98bb
 		switch( strip[i] ){
7c98bb
-			case 0xd8:
7c98bb
-				/* SOI - start of image */
7c98bb
+			case 0xd8:	/* SOI - start of image */
7c98bb
 				_TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), 2);
7c98bb
 				*bufferoffset+=2;
7c98bb
-				i+=2;
7c98bb
 				break;
7c98bb
-			case 0xc0:
7c98bb
-			case 0xc1:
7c98bb
-			case 0xc3:
7c98bb
-			case 0xc9:
7c98bb
-			case 0xca:
7c98bb
+			case 0xc0:	/* SOF0 */
7c98bb
+			case 0xc1:	/* SOF1 */
7c98bb
+			case 0xc3:	/* SOF3 */
7c98bb
+			case 0xc9:	/* SOF9 */
7c98bb
+			case 0xca:	/* SOF10 */
7c98bb
 				if(no==0){
7c98bb
-					_TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), strip[i+2]+2);
7c98bb
-					for(j=0;j
7c98bb
-						if( (buffer[*bufferoffset+11+(2*j)]>>4) > h_samp) 
7c98bb
-							h_samp = (buffer[*bufferoffset+11+(2*j)]>>4);
7c98bb
-						if( (buffer[*bufferoffset+11+(2*j)] & 0x0f) > v_samp) 
7c98bb
-							v_samp = (buffer[*bufferoffset+11+(2*j)] & 0x0f);
7c98bb
+					_TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), datalen+2);
7c98bb
+					ncomp = buffer[*bufferoffset+9];
7c98bb
+					if (ncomp < 1 || ncomp > 4)
7c98bb
+						return(0);
7c98bb
+					v_samp=1;
7c98bb
+					h_samp=1;
7c98bb
+					for(j=0;j
7c98bb
+						uint16 samp = buffer[*bufferoffset+11+(3*j)];
7c98bb
+						if( (samp>>4) > h_samp) 
7c98bb
+							h_samp = (samp>>4);
7c98bb
+						if( (samp & 0x0f) > v_samp) 
7c98bb
+							v_samp = (samp & 0x0f);
7c98bb
 					}
7c98bb
 					v_samp*=8;
7c98bb
 					h_samp*=8;
7c98bb
@@ -3381,45 +3404,43 @@
7c98bb
                                           (unsigned char) ((height>>8) & 0xff);
7c98bb
 					buffer[*bufferoffset+6]=
7c98bb
                                             (unsigned char) (height & 0xff);
7c98bb
-					*bufferoffset+=strip[i+2]+2;
7c98bb
-					i+=strip[i+2]+2;
7c98bb
-
7c98bb
+					*bufferoffset+=datalen+2;
7c98bb
+					/* insert a DRI marker */
7c98bb
 					buffer[(*bufferoffset)++]=0xff;
7c98bb
 					buffer[(*bufferoffset)++]=0xdd;
7c98bb
 					buffer[(*bufferoffset)++]=0x00;
7c98bb
 					buffer[(*bufferoffset)++]=0x04;
7c98bb
 					buffer[(*bufferoffset)++]=(ri >> 8) & 0xff;
7c98bb
 					buffer[(*bufferoffset)++]= ri & 0xff;
7c98bb
-				} else {
7c98bb
-					i+=strip[i+2]+2;
7c98bb
 				}
7c98bb
 				break;
7c98bb
-			case 0xc4:
7c98bb
-			case 0xdb:
7c98bb
-				_TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), strip[i+2]+2);
7c98bb
-				*bufferoffset+=strip[i+2]+2;
7c98bb
-				i+=strip[i+2]+2;
7c98bb
+			case 0xc4: /* DHT */
7c98bb
+			case 0xdb: /* DQT */
7c98bb
+				_TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), datalen+2);
7c98bb
+				*bufferoffset+=datalen+2;
7c98bb
 				break;
7c98bb
-			case 0xda:
7c98bb
+			case 0xda: /* SOS */
7c98bb
 				if(no==0){
7c98bb
-					_TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), strip[i+2]+2);
7c98bb
-					*bufferoffset+=strip[i+2]+2;
7c98bb
-					i+=strip[i+2]+2;
7c98bb
+					_TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), datalen+2);
7c98bb
+					*bufferoffset+=datalen+2;
7c98bb
 				} else {
7c98bb
 					buffer[(*bufferoffset)++]=0xff;
7c98bb
 					buffer[(*bufferoffset)++]=
7c98bb
                                             (unsigned char)(0xd0 | ((no-1)%8));
7c98bb
-					i+=strip[i+2]+2;
7c98bb
 				}
7c98bb
-				_TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), (*striplength)-i-1);
7c98bb
-				*bufferoffset+=(*striplength)-i-1;
7c98bb
+				i += datalen + 1;
7c98bb
+				/* copy remainder of strip */
7c98bb
+				_TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i]), *striplength - i);
7c98bb
+				*bufferoffset+= *striplength - i;
7c98bb
 				return(1);
7c98bb
 			default:
7c98bb
-				i+=strip[i+2]+2;
7c98bb
+				/* ignore any other marker */
7c98bb
+				break;
7c98bb
 		}
7c98bb
+		i += datalen + 1;
7c98bb
 	}
7c98bb
-	
7c98bb
 
7c98bb
+	/* failed to find SOS marker */
7c98bb
 	return(0);
7c98bb
 }
7c98bb
 #endif