summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEirik Aavitsland <eirik.aavitsland@qt.io>2021-11-16 07:41:20 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-11-17 13:28:44 +0000
commitfe6e775ad93e77c9700131ea6959bc2f36ace8af (patch)
treed864f4c5b13552a060d1ec4c0da284c21d33d34d /src
parent80c063f8976e1d3f9ad9441b59b047cd4496abac (diff)
Reject truncated and corrupt ascii pnm images
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: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src')
-rw-r--r--src/gui/image/qppmhandler.cpp49
1 files changed, 27 insertions, 22 deletions
diff --git a/src/gui/image/qppmhandler.cpp b/src/gui/image/qppmhandler.cpp
index 71dbefe354..447731814c 100644
--- a/src/gui/image/qppmhandler.cpp
+++ b/src/gui/image/qppmhandler.cpp
@@ -68,7 +68,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;
@@ -102,6 +102,8 @@ static int read_pbm_int(QIODevice *d)
else
break;
}
+ if (val < 0)
+ *ok = false;
return hasOverflow ? -1 : val;
}
@@ -118,16 +120,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;
}
@@ -235,18 +238,18 @@ static bool read_pbm_body(QIODevice *device, char type, int w, int h, int mcc, Q
} else { // read ascii data
uchar *p;
qsizetype 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
}
@@ -255,36 +258,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) & 0xffff) * 255 / mcc;
+ while (n-- && ok) {
+ *p++ = (read_pbm_int(device, &ok) & 0xffff) * 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) {