diff options
author | Eirik Aavitsland <eirik.aavitsland@qt.io> | 2021-11-16 07:41:20 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-11-17 13:28:44 +0000 |
commit | fe6e775ad93e77c9700131ea6959bc2f36ace8af (patch) | |
tree | d864f4c5b13552a060d1ec4c0da284c21d33d34d /src | |
parent | 80c063f8976e1d3f9ad9441b59b047cd4496abac (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.cpp | 49 |
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) { |