$NetBSD: patch-be,v 1.3 2006/03/29 17:22:46 joerg Exp $

--- pdftops/Stream.cxx.orig	2004-02-02 17:41:09.000000000 -0500
+++ pdftops/Stream.cxx
@@ -12,6 +12,7 @@
 #pragma implementation
 #endif
 
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stddef.h>
@@ -409,13 +410,26 @@ StreamPredictor::StreamPredictor(Stream 
   width = widthA;
   nComps = nCompsA;
   nBits = nBitsA;
+  predLine = NULL;
+  ok = gFalse;
 
   nVals = width * nComps;
+  if (width <= 0 || nComps <= 0 || nBits <= 0 ||
+      nComps >= INT_MAX / nBits ||
+      width >= INT_MAX / nComps / nBits ||
+      nVals * nBits + 7 < 0) {
+    return;
+  }
   pixBytes = (nComps * nBits + 7) >> 3;
   rowBytes = ((nVals * nBits + 7) >> 3) + pixBytes;
+  if (rowBytes <= 0) {
+    return;
+  }
   predLine = (Guchar *)gmalloc(rowBytes);
   memset(predLine, 0, rowBytes);
   predIdx = rowBytes;
+
+  ok = gTrue;
 }
 
 StreamPredictor::~StreamPredictor() {
@@ -991,6 +1005,10 @@ LZWStream::LZWStream(Stream *strA, int p
     FilterStream(strA) {
   if (predictor != 1) {
     pred = new StreamPredictor(this, predictor, columns, colors, bits);
+    if (!pred->isOK()) {
+      delete pred;
+      pred = NULL;
+    }
   } else {
     pred = NULL;
   }
@@ -1239,6 +1257,9 @@ CCITTFaxStream::CCITTFaxStream(Stream *s
   endOfLine = endOfLineA;
   byteAlign = byteAlignA;
   columns = columnsA;
+  if (columns + 4 <= 0) {
+    columns = INT_MAX - 4;
+  }
   rows = rowsA;
   endOfBlock = endOfBlockA;
   black = blackA;
@@ -2891,6 +2912,11 @@ GBool DCTStream::readBaselineSOF() {
   height = read16();
   width = read16();
   numComps = str->getChar();
+  if (numComps <= 0 || numComps > 4) {
+    error(getPos(), "Bad number of components in DCT stream", prec);
+    numComps = 0;
+    return gFalse;
+  }
   if (prec != 8) {
     error(getPos(), "Bad DCT precision %d", prec);
     return gFalse;
@@ -2917,6 +2943,11 @@ GBool DCTStream::readProgressiveSOF() {
   height = read16();
   width = read16();
   numComps = str->getChar();
+  if (numComps <= 0 || numComps > 4) {
+    error(getPos(), "Bad number of components in DCT stream", prec);
+    numComps = 0;
+    return gFalse;
+  }
   if (prec != 8) {
     error(getPos(), "Bad DCT precision %d", prec);
     return gFalse;
@@ -2939,6 +2970,11 @@ GBool DCTStream::readScanInfo() {
 
   length = read16() - 2;
   scanInfo.numComps = str->getChar();
+  if (scanInfo.numComps <= 0 || scanInfo.numComps > 4) {
+    error(getPos(), "Bad number of components in DCT stream");
+    scanInfo.numComps = 0;
+    return gFalse;
+  }
   --length;
   if (length != 2 * scanInfo.numComps + 3) {
     error(getPos(), "Bad DCT scan info block");
@@ -2980,22 +3016,32 @@ GBool DCTStream::readScanInfo() {
 }
 
 GBool DCTStream::readQuantTables() {
-  int length;
-  int i;
-  int index;
+  int length, prec, i, index;
 
   length = read16() - 2;
   while (length > 0) {
     index = str->getChar();
-    if ((index & 0xf0) || index >= 4) {
+    prec = (index >> 4) & 0x0f;
+    index &= 0x0f;
+    if (prec > 1 || index >= 4) {
       error(getPos(), "Bad DCT quantization table");
       return gFalse;
     }
-    if (index == numQuantTables)
+    if (index == numQuantTables) {
       numQuantTables = index + 1;
-    for (i = 0; i < 64; ++i)
-      quantTables[index][dctZigZag[i]] = str->getChar();
-    length -= 65;
+    }
+    for (i = 0; i < 64; ++i) {
+      if (prec) {
+	quantTables[index][dctZigZag[i]] = read16();
+      } else {
+	quantTables[index][dctZigZag[i]] = str->getChar();
+      }
+    }
+    if (prec) {
+      length -= 129;
+    } else {
+      length -= 65;
+    }
   }
   return gTrue;
 }
@@ -3023,6 +3069,7 @@ GBool DCTStream::readHuffmanTables() {
 	numACHuffTables = index+1;
       tbl = &acHuffTables[index];
     } else {
+      index &= 0x0f;
       if (index >= numDCHuffTables)
 	numDCHuffTables = index+1;
       tbl = &dcHuffTables[index];
@@ -3136,7 +3183,7 @@ int DCTStream::readMarker() {
   do {
     do {
       c = str->getChar();
-    } while (c != 0xff);
+    } while (c != 0xff && c != EOF);
     do {
       c = str->getChar();
     } while (c == 0xff);
@@ -3249,6 +3296,10 @@ FlateStream::FlateStream(Stream *strA, i
     FilterStream(strA) {
   if (predictor != 1) {
     pred = new StreamPredictor(this, predictor, columns, colors, bits);
+    if (!pred->isOK()) {
+      delete pred;
+      pred = NULL;
+    }
   } else {
     pred = NULL;
   }
