check byteArray bounds in bmp-decompressors;
authorClaus Gittinger <cg@exept.de>
Mon, 15 Jun 1998 17:08:11 +0200
changeset 2152 b071479dac57
parent 2151 d771faffbc1d
child 2153 eb2d1caa5dfd
check byteArray bounds in bmp-decompressors; also care for unsigned chars
ImageRdr.st
ImageReader.st
--- a/ImageRdr.st	Mon Jun 15 15:19:29 1998 +0200
+++ b/ImageRdr.st	Mon Jun 15 17:08:11 1998 +0200
@@ -547,8 +547,8 @@
 	    /* add to output */
 	    if (to >= toEnd) {
 		fprintf(stderr, "ImageReader [warning]: LZW outBuffer overrun\n");
-	        ret = 0;
-	        break;
+		ret = 0;
+		break;
 	    }
 	    *to++ = code;
 	    oldCode = code;
@@ -587,11 +587,11 @@
             
 		/* writeString(string[oldCode] + first(string[oldCode]) ) */
 		len = stringLen[oldCode];
-	        if ((to+len) >= toEnd) {
+		if ((to+len) >= toEnd) {
 		    fprintf(stderr, "ImageReader [warning]: LZW outBuffer overrun\n");
-	            ret = 0;
-	            goto out;
-	        }
+		    ret = 0;
+		    goto out;
+		}
 		bcopy(strings[oldCode], to, len);
 		to += len;
 		*to++ = strings[oldCode][0];
@@ -642,8 +642,8 @@
     free(stringLen);
 
     if (from > fromEnd) {
-        fprintf(stderr, "ImageReader [warning]: LZW inBuffer overrun\n");
-        ret = 0;
+	fprintf(stderr, "ImageReader [warning]: LZW inBuffer overrun\n");
+	ret = 0;
     }
     return ret;
 }
@@ -754,7 +754,7 @@
 		nBits += 8;
 	    }
 	    if (inCount <= 0)
-	        break;
+		break;
 	    code = bits & mask;
 	    bits >>= codeLen;
 	    nBits -= codeLen;
@@ -762,8 +762,8 @@
 	    /* add to output */
 	    if (to >= toEnd) {
 		fprintf(stderr, "ImageReader [warning]: GIF outBuffer overrun\n");
-	        ret = 0;
-	        break;
+		ret = 0;
+		break;
 	    }
 	    *to++ = code;
 	    oldCode = fin = curCode = code;
@@ -788,16 +788,16 @@
 #if 0
 	    if ((to+outCount) >= toEnd) {
 		fprintf(stderr, "ImageReader [warning]: GIF outBuffer overrun\n");
-	        ret = 0;
-	        break;
+		ret = 0;
+		break;
 	    }
 #endif
 	    for (i = outCount - 1; i >= 0; i--) {
-	        if (to >= toEnd) {
+		if (to >= toEnd) {
 		    fprintf(stderr, "ImageReader [warning]: GIF outBuffer overrun\n");
-	            ret = 0;
-	            break;
-	        }
+		    ret = 0;
+		    break;
+		}
 		*to++ = outCode[i];
 	    }
 	    outCount = 0;
@@ -822,8 +822,8 @@
     free(outCode);
 
     if (from > fromEnd) {
-        fprintf(stderr, "ImageReader [warning]: GIF inBuffer overrun\n");
-        ret = 0;
+	fprintf(stderr, "ImageReader [warning]: GIF inBuffer overrun\n");
+	ret = 0;
     }
     return ret;
 }
@@ -832,10 +832,11 @@
  * BMP file read/decompression
  */
 static int
-loadBMP1to8(w, h, fp, dest)
+loadBMP1to8(w, h, fp, dest, szDest)
     int w, h;
     FILE *fp;
     unsigned char *dest;
+    int szDest;
 {
     int   i,j,c,bitnum,padw;
     unsigned char *pp;
@@ -848,9 +849,14 @@
 	for (j=bitnum=0; j<padw; j++,bitnum++) {
 	    if ((bitnum&7) == 0) { /* read the next byte */
 		c = getc(fp);
+		if (c == EOF) return 0;
 		bitnum = 0;
 	    }
 	    if (j<w) {
+		if (pp >= (dest+szDest)) {
+		    fprintf(stderr, "ImageReader [warning]: BMP outBuffer overrun\n");
+		    return 0;
+		}
 		*pp++ = (c & 0x80) ? 1 : 0;
 		c <<= 1;
 	    }
@@ -862,10 +868,11 @@
 }
 
 static int
-loadBMP2to8(w, h, fp, dest)
+loadBMP2to8(w, h, fp, dest, szDest)
     int w, h;
     FILE *fp;
     unsigned char *dest;
+    int szDest;
 {
     int   i,j,c,bitnum,padw;
     unsigned char *pp;
@@ -878,9 +885,14 @@
 	for (j=bitnum=0; j<padw; j++,bitnum++) {
 	    if ((bitnum&3) == 0) { /* read the next byte */
 		c = getc(fp);
+		if (c == EOF) return 0;
 		bitnum = 0;
 	    }
 	    if (j<w) {
+		if (pp >= (dest+szDest)) {
+		    fprintf(stderr, "ImageReader [warning]: BMP outBuffer overrun\n");
+		    return 0;
+		}
 		*pp++ = (c & 0xC0) >> 6;
 		c <<= 2;
 	    }
@@ -892,10 +904,11 @@
 }
 
 static int
-loadBMP4to8(w, h, comp, fp, dest)
+loadBMP4to8(w, h, comp, fp, dest, szDest)
     int w, h;
     FILE *fp;
     unsigned char *dest;
+    int szDest;
 {
     int   i,j,c,c1,padw,x,y,nybnum;
     unsigned char *pp;
@@ -911,10 +924,15 @@
 	    for (j=nybnum=0; j<padw; j++,nybnum++) {
 		if ((nybnum & 1) == 0) { /* read next byte */
 		    c = getc(fp);
+		    if (c == EOF) return 0;
 		    nybnum = 0;
 		}
 
 		if (j<w) {
+		    if (pp >= (dest+szDest)) {
+			fprintf(stderr, "ImageReader [warning]: BMP outBuffer overrun\n");
+			return 0;
+		    }
 		    *pp++ = (c & 0xf0) >> 4;
 		    c <<= 4;
 		}
@@ -930,31 +948,50 @@
 		c = getc(fp); if (c == EOF) return 0;
 
 		if (c) {                                   /* encoded mode */
+		    c &= 0xFF;
 		    c1 = getc(fp);
-		    for (i=0; i<c; i++,x++,pp++) 
+		    if (c1 == EOF) return 0;
+		    for (i=0; i<c; i++,x++,pp++) {
+			if (pp >= (dest+szDest)) {
+			    fprintf(stderr, "ImageReader [warning]: BMP outBuffer overrun\n");
+			    return 0;
+			}
 			*pp = (i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f);
+		    }
 		} else {    
 		    /* c==0x00  :  escape codes */
-		    c = getc(fp);  if (c == EOF) return 0;
+		    c = getc(fp);  
+		    if (c == EOF) return 0;
 
 		    if (c == 0x00) {                    /* end of line */
 			x=0;  y++;  pp = dest + x + (h-y-1)*w;
 		    } else 
 			if (c == 0x01) break;               /* end of pic8 */
 
-			else 
-			    if (c == 0x02) {                /* delta */
-				c = getc(fp);  x += c;
-				c = getc(fp);  y += c;
-				pp = dest + x + (h-y-1)*w;
-			    } else {                        /* absolute mode */
-				for (i=0; i<c; i++, x++, pp++) {
-				    if ((i&1) == 0) c1 = getc(fp);
-				    *pp = (i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f);
+			else if (c == 0x02) {                /* delta */
+			    c = getc(fp);  
+			    if (c == EOF) return 0;
+			    x += (c & 0xFF);
+			    c = getc(fp);  
+			    if (c == EOF) return 0;
+			    y += (c & 0xFF);
+			    pp = dest + x + (h-y-1)*w;
+			} else {                        /* absolute mode */
+			    c &= 0xFF;
+			    for (i=0; i<c; i++, x++, pp++) {
+				if ((i&1) == 0) {
+				    c1 = getc(fp);
+				    if (c1 == EOF) return 0;
 				}
+				if (pp >= (dest+szDest)) {
+				    fprintf(stderr, "ImageReader [warning]: BMP outBuffer overrun\n");
+				    return 0;
+				}
+				*pp = (i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f);
+			    }
 
-				if (((c&3)==1) || ((c&3)==2)) getc(fp);  /* read pad byte */
-			    }
+			    if (((c&3)==1) || ((c&3)==2)) getc(fp);  /* read pad byte */
+			}
 		}  /* escape processing */
 		if (ferror(fp)) return 0;
 	    }  /* while */
@@ -967,10 +1004,11 @@
 }
 
 static int
-loadBMP8(w, h, comp, fp, dest)
+loadBMP8(w, h, comp, fp, dest, szDest)
     int w, h;
     FILE *fp;
     unsigned char *dest;
+    int szDest;
 {
     int   i,j,c,c1,padw,x,y;
     unsigned char *pp;
@@ -985,7 +1023,13 @@
 		c = getc(fp);  
 		if (c==EOF) return 0;
 
-		if (j<w) *pp++ = c;
+		if (j<w) {
+		    if (pp >= (dest+szDest)) {
+			fprintf(stderr, "ImageReader [warning]: BMP outBuffer overrun\n");
+			return 0;
+		    }
+		    *pp++ = c;
+		}
 	    }
 	    if (ferror(fp)) return 0;
 	}
@@ -1000,7 +1044,16 @@
 
 		if (c) {                                   /* encoded mode */
 		    c1 = getc(fp);
-		    for (i=0; i<c; i++,x++,pp++) *pp = c1;
+		    if (c1 == EOF) return 0;
+		    c &= 0xFF;
+
+		    for (i=0; i<c; i++,x++,pp++) {
+			if (pp >= (dest+szDest)) {
+			    fprintf(stderr, "ImageReader [warning]: BMP outBuffer overrun\n");
+			    return 0;
+			}
+			*pp = c1;
+		    }
 		} else {    
 		    /* c==0x00  :  escape codes */
 		    c = getc(fp);  
@@ -1010,14 +1063,23 @@
 			x=0;  y++;  pp = dest + x + (h-y-1)*w;
 		    } else 
 			if (c == 0x01) break;               /* end of pic8 */
-
 			else if (c == 0x02) {               /* delta */
-			    c = getc(fp);  x += c;
-			    c = getc(fp);  y += c;
+			    c = getc(fp);
+			    if (c == EOF) return 0;
+			    x += (c & 0xFF);
+			    c = getc(fp);  
+			    if (c == EOF) return 0;
+			    y += (c & 0xFF);
 			    pp = dest + x + (h-y-1)*w;
 			} else {                            /* absolute mode */
+			    c &= 0xFF;
 			    for (i=0; i<c; i++, x++, pp++) {
 				c1 = getc(fp);
+				if (c1 == EOF) return 0;
+				if (pp >= (dest+szDest)) {
+				    fprintf(stderr, "ImageReader [warning]: BMP outBuffer overrun\n");
+				    return 0;
+				}
 				*pp = c1;
 			    }
 
@@ -1166,9 +1228,9 @@
      && __isByteArray(dstBytes)
      && __bothSmallInteger(offset, count)) {
 	if (__decodeCCITTgroup3__(__ByteArrayInstPtr(srcBytes)->ba_element,
-			          __ByteArrayInstPtr(dstBytes)->ba_element
-			          + __intVal(offset) - 1,
-			          __intVal(count))) {
+				  __ByteArrayInstPtr(dstBytes)->ba_element
+				  + __intVal(offset) - 1,
+				  __intVal(count))) {
 	    RETURN ( self );
 	}
     }
@@ -1187,10 +1249,10 @@
      && __bothSmallInteger(codeLen, offset)
      && __isSmallInteger(count)) {
 	if (__decodeGIF__(__ByteArrayInstPtr(srcBytes)->ba_element,
-		          __ByteArrayInstPtr(dstBytes)->ba_element
+			  __ByteArrayInstPtr(dstBytes)->ba_element
 						+__intVal(offset) - 1,
-		          __intVal(count),
-		          __intVal(codeLen),
+			  __intVal(count),
+			  __intVal(codeLen),
 			  __byteArraySize(srcBytes),
 			  __byteArraySize(dstBytes)
 			 )) {
@@ -1211,9 +1273,9 @@
      && __isByteArray(dstBytes)
      && __bothSmallInteger(offset, count)) {
 	if (__decodeLZW__(__ByteArrayInstPtr(srcBytes)->ba_element,
-		          __ByteArrayInstPtr(dstBytes)->ba_element
-		                              + __intVal(offset) - 1,
-		          __intVal(count),
+			  __ByteArrayInstPtr(dstBytes)->ba_element
+					      + __intVal(offset) - 1,
+			  __intVal(count),
 			  __byteArraySize(srcBytes),
 			  __byteArraySize(dstBytes)
 			)) {
@@ -1299,7 +1361,9 @@
 	RETURN (false);
     }
     if (loadBMP1to8(__intVal(width), __intVal(height), 
-		 __FILEVal(f), __ByteArrayInstPtr(aByteArray)->ba_element)) {
+		 __FILEVal(f), 
+		__ByteArrayInstPtr(aByteArray)->ba_element,
+		__byteArraySize(aByteArray) )) {
 	RETURN (true);
     }
     RETURN (false);
@@ -1323,7 +1387,9 @@
 	RETURN (false);
     }
     if (loadBMP2to8(__intVal(width), __intVal(height), 
-	     __FILEVal(f), __ByteArrayInstPtr(aByteArray)->ba_element)) {
+	     __FILEVal(f), 
+	     __ByteArrayInstPtr(aByteArray)->ba_element,
+	     __byteArraySize(aByteArray) )) {
 	RETURN (true);
     }
     RETURN (false);
@@ -1348,7 +1414,9 @@
 	RETURN (false);
     }
     if (loadBMP4to8(__intVal(width), __intVal(height), __intVal(compression), 
-	     __FILEVal(f), __ByteArrayInstPtr(aByteArray)->ba_element)) {
+	     __FILEVal(f), 
+	     __ByteArrayInstPtr(aByteArray)->ba_element,
+	     __byteArraySize(aByteArray) )) {
 	RETURN (true);
     }
     RETURN (false);
@@ -1373,7 +1441,9 @@
 	RETURN (false);
     }
     if (loadBMP8(__intVal(width), __intVal(height), __intVal(compression), 
-	     __FILEVal(f), __ByteArrayInstPtr(aByteArray)->ba_element)) {
+	     __FILEVal(f), 
+	     __ByteArrayInstPtr(aByteArray)->ba_element,
+	     __byteArraySize(aByteArray) )) {
 	RETURN (true);
     }
     RETURN (false);
@@ -1729,7 +1799,7 @@
      If my file contained multiple images, return the first one."
 
     imageSequence size > 0 ifTrue:[
-        ^ self images first.
+	^ self images first.
     ].
 
     ^ self makeImage.
@@ -1760,12 +1830,12 @@
     |img|
 
     imageSequence notNil ifTrue:[
-        ^ (imageSequence collect:[:aFrame | aFrame image])
+	^ (imageSequence collect:[:aFrame | aFrame image])
     ].
 
     img := self makeImage.
     img isNil ifTrue:[
-        ^ img
+	^ img
     ].
     ^ Array with:img
 
@@ -1783,20 +1853,20 @@
     image := (Image implementorForDepth:depth) new.
     image depth:depth.
     inStream isFileStream ifTrue:[
-        image fileName:inStream pathName.
+	image fileName:inStream pathName.
     ].
     image 
-        width:width 
-        height:height
-        photometric:photometric
-        samplesPerPixel:samplesPerPixel
-        bitsPerSample:bitsPerSample
-        colorMap:colorMap
-        bits:data
-        mask:mask.
+	width:width 
+	height:height
+	photometric:photometric
+	samplesPerPixel:samplesPerPixel
+	bitsPerSample:bitsPerSample
+	colorMap:colorMap
+	bits:data
+	mask:mask.
 
     imageSequence notNil ifTrue:[
-        image imageSequence:imageSequence.
+	image imageSequence:imageSequence.
     ].
 
     ^ image
@@ -1883,8 +1953,8 @@
     "report a format error - no image could be read"
 
     Image 
-        badImageFormatQuerySignal
-            raiseErrorString:(self class name , ' [info]: ' , aMessage).
+	badImageFormatQuerySignal
+	    raiseErrorString:(self class name , ' [info]: ' , aMessage).
     ^ nil
 
     "Created: / 3.2.1998 / 17:50:06 / cg"
@@ -1985,5 +2055,5 @@
 !ImageReader class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview/Attic/ImageRdr.st,v 1.64 1998-04-01 13:07:15 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview/Attic/ImageRdr.st,v 1.65 1998-06-15 15:08:11 cg Exp $'
 ! !
--- a/ImageReader.st	Mon Jun 15 15:19:29 1998 +0200
+++ b/ImageReader.st	Mon Jun 15 17:08:11 1998 +0200
@@ -547,8 +547,8 @@
 	    /* add to output */
 	    if (to >= toEnd) {
 		fprintf(stderr, "ImageReader [warning]: LZW outBuffer overrun\n");
-	        ret = 0;
-	        break;
+		ret = 0;
+		break;
 	    }
 	    *to++ = code;
 	    oldCode = code;
@@ -587,11 +587,11 @@
             
 		/* writeString(string[oldCode] + first(string[oldCode]) ) */
 		len = stringLen[oldCode];
-	        if ((to+len) >= toEnd) {
+		if ((to+len) >= toEnd) {
 		    fprintf(stderr, "ImageReader [warning]: LZW outBuffer overrun\n");
-	            ret = 0;
-	            goto out;
-	        }
+		    ret = 0;
+		    goto out;
+		}
 		bcopy(strings[oldCode], to, len);
 		to += len;
 		*to++ = strings[oldCode][0];
@@ -642,8 +642,8 @@
     free(stringLen);
 
     if (from > fromEnd) {
-        fprintf(stderr, "ImageReader [warning]: LZW inBuffer overrun\n");
-        ret = 0;
+	fprintf(stderr, "ImageReader [warning]: LZW inBuffer overrun\n");
+	ret = 0;
     }
     return ret;
 }
@@ -754,7 +754,7 @@
 		nBits += 8;
 	    }
 	    if (inCount <= 0)
-	        break;
+		break;
 	    code = bits & mask;
 	    bits >>= codeLen;
 	    nBits -= codeLen;
@@ -762,8 +762,8 @@
 	    /* add to output */
 	    if (to >= toEnd) {
 		fprintf(stderr, "ImageReader [warning]: GIF outBuffer overrun\n");
-	        ret = 0;
-	        break;
+		ret = 0;
+		break;
 	    }
 	    *to++ = code;
 	    oldCode = fin = curCode = code;
@@ -788,16 +788,16 @@
 #if 0
 	    if ((to+outCount) >= toEnd) {
 		fprintf(stderr, "ImageReader [warning]: GIF outBuffer overrun\n");
-	        ret = 0;
-	        break;
+		ret = 0;
+		break;
 	    }
 #endif
 	    for (i = outCount - 1; i >= 0; i--) {
-	        if (to >= toEnd) {
+		if (to >= toEnd) {
 		    fprintf(stderr, "ImageReader [warning]: GIF outBuffer overrun\n");
-	            ret = 0;
-	            break;
-	        }
+		    ret = 0;
+		    break;
+		}
 		*to++ = outCode[i];
 	    }
 	    outCount = 0;
@@ -822,8 +822,8 @@
     free(outCode);
 
     if (from > fromEnd) {
-        fprintf(stderr, "ImageReader [warning]: GIF inBuffer overrun\n");
-        ret = 0;
+	fprintf(stderr, "ImageReader [warning]: GIF inBuffer overrun\n");
+	ret = 0;
     }
     return ret;
 }
@@ -832,10 +832,11 @@
  * BMP file read/decompression
  */
 static int
-loadBMP1to8(w, h, fp, dest)
+loadBMP1to8(w, h, fp, dest, szDest)
     int w, h;
     FILE *fp;
     unsigned char *dest;
+    int szDest;
 {
     int   i,j,c,bitnum,padw;
     unsigned char *pp;
@@ -848,9 +849,14 @@
 	for (j=bitnum=0; j<padw; j++,bitnum++) {
 	    if ((bitnum&7) == 0) { /* read the next byte */
 		c = getc(fp);
+		if (c == EOF) return 0;
 		bitnum = 0;
 	    }
 	    if (j<w) {
+		if (pp >= (dest+szDest)) {
+		    fprintf(stderr, "ImageReader [warning]: BMP outBuffer overrun\n");
+		    return 0;
+		}
 		*pp++ = (c & 0x80) ? 1 : 0;
 		c <<= 1;
 	    }
@@ -862,10 +868,11 @@
 }
 
 static int
-loadBMP2to8(w, h, fp, dest)
+loadBMP2to8(w, h, fp, dest, szDest)
     int w, h;
     FILE *fp;
     unsigned char *dest;
+    int szDest;
 {
     int   i,j,c,bitnum,padw;
     unsigned char *pp;
@@ -878,9 +885,14 @@
 	for (j=bitnum=0; j<padw; j++,bitnum++) {
 	    if ((bitnum&3) == 0) { /* read the next byte */
 		c = getc(fp);
+		if (c == EOF) return 0;
 		bitnum = 0;
 	    }
 	    if (j<w) {
+		if (pp >= (dest+szDest)) {
+		    fprintf(stderr, "ImageReader [warning]: BMP outBuffer overrun\n");
+		    return 0;
+		}
 		*pp++ = (c & 0xC0) >> 6;
 		c <<= 2;
 	    }
@@ -892,10 +904,11 @@
 }
 
 static int
-loadBMP4to8(w, h, comp, fp, dest)
+loadBMP4to8(w, h, comp, fp, dest, szDest)
     int w, h;
     FILE *fp;
     unsigned char *dest;
+    int szDest;
 {
     int   i,j,c,c1,padw,x,y,nybnum;
     unsigned char *pp;
@@ -911,10 +924,15 @@
 	    for (j=nybnum=0; j<padw; j++,nybnum++) {
 		if ((nybnum & 1) == 0) { /* read next byte */
 		    c = getc(fp);
+		    if (c == EOF) return 0;
 		    nybnum = 0;
 		}
 
 		if (j<w) {
+		    if (pp >= (dest+szDest)) {
+			fprintf(stderr, "ImageReader [warning]: BMP outBuffer overrun\n");
+			return 0;
+		    }
 		    *pp++ = (c & 0xf0) >> 4;
 		    c <<= 4;
 		}
@@ -930,31 +948,50 @@
 		c = getc(fp); if (c == EOF) return 0;
 
 		if (c) {                                   /* encoded mode */
+		    c &= 0xFF;
 		    c1 = getc(fp);
-		    for (i=0; i<c; i++,x++,pp++) 
+		    if (c1 == EOF) return 0;
+		    for (i=0; i<c; i++,x++,pp++) {
+			if (pp >= (dest+szDest)) {
+			    fprintf(stderr, "ImageReader [warning]: BMP outBuffer overrun\n");
+			    return 0;
+			}
 			*pp = (i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f);
+		    }
 		} else {    
 		    /* c==0x00  :  escape codes */
-		    c = getc(fp);  if (c == EOF) return 0;
+		    c = getc(fp);  
+		    if (c == EOF) return 0;
 
 		    if (c == 0x00) {                    /* end of line */
 			x=0;  y++;  pp = dest + x + (h-y-1)*w;
 		    } else 
 			if (c == 0x01) break;               /* end of pic8 */
 
-			else 
-			    if (c == 0x02) {                /* delta */
-				c = getc(fp);  x += c;
-				c = getc(fp);  y += c;
-				pp = dest + x + (h-y-1)*w;
-			    } else {                        /* absolute mode */
-				for (i=0; i<c; i++, x++, pp++) {
-				    if ((i&1) == 0) c1 = getc(fp);
-				    *pp = (i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f);
+			else if (c == 0x02) {                /* delta */
+			    c = getc(fp);  
+			    if (c == EOF) return 0;
+			    x += (c & 0xFF);
+			    c = getc(fp);  
+			    if (c == EOF) return 0;
+			    y += (c & 0xFF);
+			    pp = dest + x + (h-y-1)*w;
+			} else {                        /* absolute mode */
+			    c &= 0xFF;
+			    for (i=0; i<c; i++, x++, pp++) {
+				if ((i&1) == 0) {
+				    c1 = getc(fp);
+				    if (c1 == EOF) return 0;
 				}
+				if (pp >= (dest+szDest)) {
+				    fprintf(stderr, "ImageReader [warning]: BMP outBuffer overrun\n");
+				    return 0;
+				}
+				*pp = (i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f);
+			    }
 
-				if (((c&3)==1) || ((c&3)==2)) getc(fp);  /* read pad byte */
-			    }
+			    if (((c&3)==1) || ((c&3)==2)) getc(fp);  /* read pad byte */
+			}
 		}  /* escape processing */
 		if (ferror(fp)) return 0;
 	    }  /* while */
@@ -967,10 +1004,11 @@
 }
 
 static int
-loadBMP8(w, h, comp, fp, dest)
+loadBMP8(w, h, comp, fp, dest, szDest)
     int w, h;
     FILE *fp;
     unsigned char *dest;
+    int szDest;
 {
     int   i,j,c,c1,padw,x,y;
     unsigned char *pp;
@@ -985,7 +1023,13 @@
 		c = getc(fp);  
 		if (c==EOF) return 0;
 
-		if (j<w) *pp++ = c;
+		if (j<w) {
+		    if (pp >= (dest+szDest)) {
+			fprintf(stderr, "ImageReader [warning]: BMP outBuffer overrun\n");
+			return 0;
+		    }
+		    *pp++ = c;
+		}
 	    }
 	    if (ferror(fp)) return 0;
 	}
@@ -1000,7 +1044,16 @@
 
 		if (c) {                                   /* encoded mode */
 		    c1 = getc(fp);
-		    for (i=0; i<c; i++,x++,pp++) *pp = c1;
+		    if (c1 == EOF) return 0;
+		    c &= 0xFF;
+
+		    for (i=0; i<c; i++,x++,pp++) {
+			if (pp >= (dest+szDest)) {
+			    fprintf(stderr, "ImageReader [warning]: BMP outBuffer overrun\n");
+			    return 0;
+			}
+			*pp = c1;
+		    }
 		} else {    
 		    /* c==0x00  :  escape codes */
 		    c = getc(fp);  
@@ -1010,14 +1063,23 @@
 			x=0;  y++;  pp = dest + x + (h-y-1)*w;
 		    } else 
 			if (c == 0x01) break;               /* end of pic8 */
-
 			else if (c == 0x02) {               /* delta */
-			    c = getc(fp);  x += c;
-			    c = getc(fp);  y += c;
+			    c = getc(fp);
+			    if (c == EOF) return 0;
+			    x += (c & 0xFF);
+			    c = getc(fp);  
+			    if (c == EOF) return 0;
+			    y += (c & 0xFF);
 			    pp = dest + x + (h-y-1)*w;
 			} else {                            /* absolute mode */
+			    c &= 0xFF;
 			    for (i=0; i<c; i++, x++, pp++) {
 				c1 = getc(fp);
+				if (c1 == EOF) return 0;
+				if (pp >= (dest+szDest)) {
+				    fprintf(stderr, "ImageReader [warning]: BMP outBuffer overrun\n");
+				    return 0;
+				}
 				*pp = c1;
 			    }
 
@@ -1166,9 +1228,9 @@
      && __isByteArray(dstBytes)
      && __bothSmallInteger(offset, count)) {
 	if (__decodeCCITTgroup3__(__ByteArrayInstPtr(srcBytes)->ba_element,
-			          __ByteArrayInstPtr(dstBytes)->ba_element
-			          + __intVal(offset) - 1,
-			          __intVal(count))) {
+				  __ByteArrayInstPtr(dstBytes)->ba_element
+				  + __intVal(offset) - 1,
+				  __intVal(count))) {
 	    RETURN ( self );
 	}
     }
@@ -1187,10 +1249,10 @@
      && __bothSmallInteger(codeLen, offset)
      && __isSmallInteger(count)) {
 	if (__decodeGIF__(__ByteArrayInstPtr(srcBytes)->ba_element,
-		          __ByteArrayInstPtr(dstBytes)->ba_element
+			  __ByteArrayInstPtr(dstBytes)->ba_element
 						+__intVal(offset) - 1,
-		          __intVal(count),
-		          __intVal(codeLen),
+			  __intVal(count),
+			  __intVal(codeLen),
 			  __byteArraySize(srcBytes),
 			  __byteArraySize(dstBytes)
 			 )) {
@@ -1211,9 +1273,9 @@
      && __isByteArray(dstBytes)
      && __bothSmallInteger(offset, count)) {
 	if (__decodeLZW__(__ByteArrayInstPtr(srcBytes)->ba_element,
-		          __ByteArrayInstPtr(dstBytes)->ba_element
-		                              + __intVal(offset) - 1,
-		          __intVal(count),
+			  __ByteArrayInstPtr(dstBytes)->ba_element
+					      + __intVal(offset) - 1,
+			  __intVal(count),
 			  __byteArraySize(srcBytes),
 			  __byteArraySize(dstBytes)
 			)) {
@@ -1299,7 +1361,9 @@
 	RETURN (false);
     }
     if (loadBMP1to8(__intVal(width), __intVal(height), 
-		 __FILEVal(f), __ByteArrayInstPtr(aByteArray)->ba_element)) {
+		 __FILEVal(f), 
+		__ByteArrayInstPtr(aByteArray)->ba_element,
+		__byteArraySize(aByteArray) )) {
 	RETURN (true);
     }
     RETURN (false);
@@ -1323,7 +1387,9 @@
 	RETURN (false);
     }
     if (loadBMP2to8(__intVal(width), __intVal(height), 
-	     __FILEVal(f), __ByteArrayInstPtr(aByteArray)->ba_element)) {
+	     __FILEVal(f), 
+	     __ByteArrayInstPtr(aByteArray)->ba_element,
+	     __byteArraySize(aByteArray) )) {
 	RETURN (true);
     }
     RETURN (false);
@@ -1348,7 +1414,9 @@
 	RETURN (false);
     }
     if (loadBMP4to8(__intVal(width), __intVal(height), __intVal(compression), 
-	     __FILEVal(f), __ByteArrayInstPtr(aByteArray)->ba_element)) {
+	     __FILEVal(f), 
+	     __ByteArrayInstPtr(aByteArray)->ba_element,
+	     __byteArraySize(aByteArray) )) {
 	RETURN (true);
     }
     RETURN (false);
@@ -1373,7 +1441,9 @@
 	RETURN (false);
     }
     if (loadBMP8(__intVal(width), __intVal(height), __intVal(compression), 
-	     __FILEVal(f), __ByteArrayInstPtr(aByteArray)->ba_element)) {
+	     __FILEVal(f), 
+	     __ByteArrayInstPtr(aByteArray)->ba_element,
+	     __byteArraySize(aByteArray) )) {
 	RETURN (true);
     }
     RETURN (false);
@@ -1729,7 +1799,7 @@
      If my file contained multiple images, return the first one."
 
     imageSequence size > 0 ifTrue:[
-        ^ self images first.
+	^ self images first.
     ].
 
     ^ self makeImage.
@@ -1760,12 +1830,12 @@
     |img|
 
     imageSequence notNil ifTrue:[
-        ^ (imageSequence collect:[:aFrame | aFrame image])
+	^ (imageSequence collect:[:aFrame | aFrame image])
     ].
 
     img := self makeImage.
     img isNil ifTrue:[
-        ^ img
+	^ img
     ].
     ^ Array with:img
 
@@ -1783,20 +1853,20 @@
     image := (Image implementorForDepth:depth) new.
     image depth:depth.
     inStream isFileStream ifTrue:[
-        image fileName:inStream pathName.
+	image fileName:inStream pathName.
     ].
     image 
-        width:width 
-        height:height
-        photometric:photometric
-        samplesPerPixel:samplesPerPixel
-        bitsPerSample:bitsPerSample
-        colorMap:colorMap
-        bits:data
-        mask:mask.
+	width:width 
+	height:height
+	photometric:photometric
+	samplesPerPixel:samplesPerPixel
+	bitsPerSample:bitsPerSample
+	colorMap:colorMap
+	bits:data
+	mask:mask.
 
     imageSequence notNil ifTrue:[
-        image imageSequence:imageSequence.
+	image imageSequence:imageSequence.
     ].
 
     ^ image
@@ -1883,8 +1953,8 @@
     "report a format error - no image could be read"
 
     Image 
-        badImageFormatQuerySignal
-            raiseErrorString:(self class name , ' [info]: ' , aMessage).
+	badImageFormatQuerySignal
+	    raiseErrorString:(self class name , ' [info]: ' , aMessage).
     ^ nil
 
     "Created: / 3.2.1998 / 17:50:06 / cg"
@@ -1985,5 +2055,5 @@
 !ImageReader class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview/ImageReader.st,v 1.64 1998-04-01 13:07:15 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview/ImageReader.st,v 1.65 1998-06-15 15:08:11 cg Exp $'
 ! !