|
|
e84ad30 |
qt-bugs@ issue : N154454
|
|
|
e84ad30 |
bugs.kde.org number : none
|
|
|
e84ad30 |
applied: no
|
|
|
e84ad30 |
author: Dirk Mueller <mueller@kde.org>
|
|
|
e84ad30 |
|
|
|
e84ad30 |
This patch makes the utf8 decoders in Qt reject overlong
|
|
|
e84ad30 |
sequences, like required.
|
|
|
e84ad30 |
|
|
|
e84ad30 |
--- src/codecs/qutfcodec.cpp
|
|
|
e84ad30 |
+++ src/codecs/qutfcodec.cpp
|
|
|
e84ad30 |
@@ -154,6 +154,7 @@
|
|
|
e84ad30 |
|
|
|
e84ad30 |
class QUtf8Decoder : public QTextDecoder {
|
|
|
e84ad30 |
uint uc;
|
|
|
e84ad30 |
+ uint min_uc;
|
|
|
e84ad30 |
int need;
|
|
|
e84ad30 |
bool headerDone;
|
|
|
e84ad30 |
public:
|
|
|
e84ad30 |
@@ -167,8 +168,9 @@
|
|
|
e84ad30 |
result.setLength( len ); // worst case
|
|
|
e84ad30 |
QChar *qch = (QChar *)result.unicode();
|
|
|
e84ad30 |
uchar ch;
|
|
|
e84ad30 |
+ int error = -1;
|
|
|
e84ad30 |
for (int i=0; i
|
|
|
e84ad30 |
- ch = *chars++;
|
|
|
e84ad30 |
+ ch = chars[i];
|
|
|
e84ad30 |
if (need) {
|
|
|
e84ad30 |
if ( (ch&0xc0) == 0x80 ) {
|
|
|
e84ad30 |
uc = (uc << 6) | (ch & 0x3f);
|
|
|
e84ad30 |
@@ -182,6 +184,8 @@
|
|
|
e84ad30 |
*qch++ = QChar(high);
|
|
|
e84ad30 |
*qch++ = QChar(low);
|
|
|
e84ad30 |
headerDone = TRUE;
|
|
|
e84ad30 |
+ } else if ((uc < min_uc) || (uc >= 0xd800 && uc <= 0xdfff) || (uc >= 0xfffe)) {
|
|
|
e84ad30 |
+ *qch++ = QChar::replacement;
|
|
|
e84ad30 |
} else {
|
|
|
e84ad30 |
if (headerDone || QChar(uc) != QChar::byteOrderMark)
|
|
|
e84ad30 |
*qch++ = uc;
|
|
|
e84ad30 |
@@ -190,6 +194,7 @@
|
|
|
e84ad30 |
}
|
|
|
e84ad30 |
} else {
|
|
|
e84ad30 |
// error
|
|
|
e84ad30 |
+ i = error;
|
|
|
e84ad30 |
*qch++ = QChar::replacement;
|
|
|
e84ad30 |
need = 0;
|
|
|
e84ad30 |
}
|
|
|
e84ad30 |
@@ -200,12 +205,21 @@
|
|
|
e84ad30 |
} else if ((ch & 0xe0) == 0xc0) {
|
|
|
e84ad30 |
uc = ch & 0x1f;
|
|
|
e84ad30 |
need = 1;
|
|
|
e84ad30 |
+ error = i;
|
|
|
e84ad30 |
+ min_uc = 0x80;
|
|
|
e84ad30 |
} else if ((ch & 0xf0) == 0xe0) {
|
|
|
e84ad30 |
uc = ch & 0x0f;
|
|
|
e84ad30 |
need = 2;
|
|
|
e84ad30 |
+ error = i;
|
|
|
e84ad30 |
+ min_uc = 0x800;
|
|
|
e84ad30 |
} else if ((ch&0xf8) == 0xf0) {
|
|
|
e84ad30 |
uc = ch & 0x07;
|
|
|
e84ad30 |
need = 3;
|
|
|
e84ad30 |
+ error = i;
|
|
|
e84ad30 |
+ min_uc = 0x10000;
|
|
|
e84ad30 |
+ } else {
|
|
|
e84ad30 |
+ // error
|
|
|
e84ad30 |
+ *qch++ = QChar::replacement;
|
|
|
e84ad30 |
}
|
|
|
e84ad30 |
}
|
|
|
e84ad30 |
}
|
|
|
e84ad30 |
--- src/tools/qstring.cpp
|
|
|
e84ad30 |
+++ src/tools/qstring.cpp
|
|
|
e84ad30 |
@@ -5805,6 +5805,7 @@
|
|
|
e84ad30 |
result.setLength( len ); // worst case
|
|
|
e84ad30 |
QChar *qch = (QChar *)result.unicode();
|
|
|
e84ad30 |
uint uc = 0;
|
|
|
e84ad30 |
+ uint min_uc = 0;
|
|
|
e84ad30 |
int need = 0;
|
|
|
e84ad30 |
int error = -1;
|
|
|
e84ad30 |
uchar ch;
|
|
|
e84ad30 |
@@ -5822,6 +5823,12 @@
|
|
|
e84ad30 |
unsigned short low = uc%0x400 + 0xdc00;
|
|
|
e84ad30 |
*qch++ = QChar(high);
|
|
|
e84ad30 |
*qch++ = QChar(low);
|
|
|
e84ad30 |
+ } else if (uc < min_uc || (uc >= 0xd800 && uc <= 0xdfff) || (uc >= 0xfffe)) {
|
|
|
e84ad30 |
+ // overlong seqence, UTF16 surrogate or BOM
|
|
|
e84ad30 |
+ i = error;
|
|
|
e84ad30 |
+ qch = addOne(qch, result);
|
|
|
e84ad30 |
+ *qch++ = QChar(0xdbff);
|
|
|
e84ad30 |
+ *qch++ = QChar(0xde00+((uchar)utf8[i]));
|
|
|
e84ad30 |
} else {
|
|
|
e84ad30 |
*qch++ = uc;
|
|
|
e84ad30 |
}
|
|
|
e84ad30 |
@@ -5844,14 +5851,17 @@
|
|
|
e84ad30 |
uc = ch & 0x1f;
|
|
|
e84ad30 |
need = 1;
|
|
|
e84ad30 |
error = i;
|
|
|
e84ad30 |
+ min_uc = 0x80;
|
|
|
e84ad30 |
} else if ((ch & 0xf0) == 0xe0) {
|
|
|
e84ad30 |
uc = ch & 0x0f;
|
|
|
e84ad30 |
need = 2;
|
|
|
e84ad30 |
error = i;
|
|
|
e84ad30 |
+ min_uc = 0x800;
|
|
|
e84ad30 |
} else if ((ch&0xf8) == 0xf0) {
|
|
|
e84ad30 |
uc = ch & 0x07;
|
|
|
e84ad30 |
need = 3;
|
|
|
e84ad30 |
error = i;
|
|
|
e84ad30 |
+ min_uc = 0x10000;
|
|
|
e84ad30 |
} else {
|
|
|
e84ad30 |
// Error
|
|
|
e84ad30 |
qch = addOne(qch, result);
|