summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEirik Aavitsland <eirik.aavitsland@qt.io>2021-11-16 07:41:20 +0100
committerEirik Aavitsland <eirik.aavitsland@qt.io>2021-11-17 14:27:45 +0100
commit01272c0948be9f1c6b8a3eff328b931f47d38649 (patch)
treecd90dd311a088ab2837686959903286315fa6d2e
parent1d5a2e924bfda9cf5eb8118812cb4652b97178b7 (diff)
Reject truncated and corrupt ascii pnm imagesv5.12.125.12.12
In contrast to the binary decoder code, the ascii decoder would not abort and fail on premature end of file. Change-Id: If27bce0afa8d1de6c4dbeb2bc0e623c1dcc2f1e0 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> (cherry picked from commit 997c052db9e2bef47cf8217c1537a99c2f086858) Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
-rw-r--r--src/gui/image/qppmhandler.cpp47
1 files changed, 26 insertions, 21 deletions
diff --git a/src/gui/image/qppmhandler.cpp b/src/gui/image/qppmhandler.cpp
index 53e3fa293d..36a449c841 100644
--- a/src/gui/image/qppmhandler.cpp
+++ b/src/gui/image/qppmhandler.cpp
@@ -63,7 +63,7 @@ static void discard_pbm_line(QIODevice *d)
} while (res > 0 && buf[res-1] != '\n');
}
-static int read_pbm_int(QIODevice *d)
+static int read_pbm_int(QIODevice *d, bool *ok)
{
char c;
int val = -1;
@@ -91,6 +91,8 @@ static int read_pbm_int(QIODevice *d)
else
break;
}
+ if (val < 0)
+ *ok = false;
return val;
}
@@ -107,16 +109,17 @@ static bool read_pbm_header(QIODevice *device, char& type, int& w, int& h, int&
if (type < '1' || type > '6')
return false;
- w = read_pbm_int(device); // get image width
- h = read_pbm_int(device); // get image height
+ bool ok = true;
+ w = read_pbm_int(device, &ok); // get image width
+ h = read_pbm_int(device, &ok); // get image height
if (type == '1' || type == '4')
mcc = 1; // ignore max color component
else
- mcc = read_pbm_int(device); // get max color component
+ mcc = read_pbm_int(device, &ok); // get max color component
- if (w <= 0 || w > 32767 || h <= 0 || h > 32767 || mcc <= 0 || mcc > 0xffff)
- return false; // weird P.M image
+ if (!ok || w <= 0 || w > 32767 || h <= 0 || h > 32767 || mcc <= 0 || mcc > 0xffff)
+ return false; // weird P.M image
return true;
}
@@ -227,18 +230,18 @@ static bool read_pbm_body(QIODevice *device, char type, int w, int h, int mcc, Q
} else { // read ascii data
uchar *p;
int n;
- char buf;
- for (y = 0; (y < h) && (device->peek(&buf, 1) == 1); y++) {
+ bool ok = true;
+ for (y = 0; (y < h) && ok; y++) {
p = outImage->scanLine(y);
n = pbm_bpl;
if (nbits == 1) {
int b;
int bitsLeft = w;
- while (n--) {
+ while (n-- && ok) {
b = 0;
for (int i=0; i<8; i++) {
if (i < bitsLeft)
- b = (b << 1) | (read_pbm_int(device) & 1);
+ b = (b << 1) | (read_pbm_int(device, &ok) & 1);
else
b = (b << 1) | (0 & 1); // pad it our self if we need to
}
@@ -247,36 +250,38 @@ static bool read_pbm_body(QIODevice *device, char type, int w, int h, int mcc, Q
}
} else if (nbits == 8) {
if (mcc == 255) {
- while (n--) {
- *p++ = read_pbm_int(device);
+ while (n-- && ok) {
+ *p++ = read_pbm_int(device, &ok);
}
} else {
while (n--) {
- *p++ = read_pbm_int(device) * 255 / mcc;
+ *p++ = read_pbm_int(device, &ok) * 255 / mcc;
}
}
} else { // 32 bits
n /= 4;
int r, g, b;
if (mcc == 255) {
- while (n--) {
- r = read_pbm_int(device);
- g = read_pbm_int(device);
- b = read_pbm_int(device);
+ while (n-- && ok) {
+ r = read_pbm_int(device, &ok);
+ g = read_pbm_int(device, &ok);
+ b = read_pbm_int(device, &ok);
*((QRgb*)p) = qRgb(r, g, b);
p += 4;
}
} else {
- while (n--) {
- r = read_pbm_int(device);
- g = read_pbm_int(device);
- b = read_pbm_int(device);
+ while (n-- && ok) {
+ r = read_pbm_int(device, &ok);
+ g = read_pbm_int(device, &ok);
+ b = read_pbm_int(device, &ok);
*((QRgb*)p) = scale_pbm_color(mcc, r, g, b);
p += 4;
}
}
}
}
+ if (!ok)
+ return false;
}
if (format == QImage::Format_Mono) {