summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qurlidna.cpp
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2013-06-07 18:56:58 -0700
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-06-08 05:06:47 +0200
commit736a052d93d9c75e51e8f3da733bc8e4a50c39ce (patch)
treeb574fe29ebef32afac55c277e4c3716116e42693 /src/corelib/io/qurlidna.cpp
parent86312275197c3fde948035a59c0358162701f9f2 (diff)
QUrl stringprep: fix handling of prohibited characters
RFC 3454 says about prohibited characters (section 2, "Preparation Overview"): 3) Prohibit -- Check for any characters that are not allowed in the output. If any are found, return an error. This is described in section 5. In other words, we mustn't simply strip the output of prohibited characters. We must generate an error if they are present. We do that by clearing the data. We already had tests for prohibited output, but they were indistinguishable from being stripped. So instead add some extra characters so that we can tell whether the label was cleared. Change-Id: I2d95217c27be5e2d54deed0036cb009e3b7f4886 Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
Diffstat (limited to 'src/corelib/io/qurlidna.cpp')
-rw-r--r--src/corelib/io/qurlidna.cpp25
1 files changed, 14 insertions, 11 deletions
diff --git a/src/corelib/io/qurlidna.cpp b/src/corelib/io/qurlidna.cpp
index 9bb6b2a42d..fa0a229f4f 100644
--- a/src/corelib/io/qurlidna.cpp
+++ b/src/corelib/io/qurlidna.cpp
@@ -1502,18 +1502,20 @@ static bool isMappedToNothing(uint uc)
}
-static void stripProhibitedOutput(QString *str, int from)
+static bool containsProhibitedOuptut(const QString *str, int from)
{
- ushort *out = (ushort *)str->data() + from;
- const ushort *in = out;
+ const ushort *in = reinterpret_cast<const ushort *>(str->begin() + from);
const ushort *end = (ushort *)str->data() + str->size();
- while (in < end) {
+ for ( ; in < end; ++in) {
uint uc = *in;
if (QChar(uc).isHighSurrogate() && in < end - 1) {
ushort low = *(in + 1);
if (QChar(low).isLowSurrogate()) {
++in;
uc = QChar::surrogateToUcs4(uc, low);
+ } else {
+ // unpaired surrogates are prohibited
+ return true;
}
}
if (uc <= 0xFFFF) {
@@ -1538,7 +1540,7 @@ static void stripProhibitedOutput(QString *str, int from)
|| (uc >= 0xFDD0 && uc <= 0xFDEF)
|| uc == 0xFEFF
|| (uc >= 0xFFF9 && uc <= 0xFFFF))) {
- *out++ = *in;
+ continue;
}
} else {
if (!((uc >= 0x1D173 && uc <= 0x1D17A)
@@ -1562,14 +1564,12 @@ static void stripProhibitedOutput(QString *str, int from)
|| (uc >= 0xFFFFE && uc <= 0xFFFFF)
|| (uc >= 0x100000 && uc <= 0x10FFFD)
|| (uc >= 0x10FFFE && uc <= 0x10FFFF))) {
- *out++ = QChar::highSurrogate(uc);
- *out++ = QChar::lowSurrogate(uc);
+ continue;
}
}
- ++in;
+ return true;
}
- if (in != out)
- str->truncate(out - str->utf16());
+ return false;
}
static bool isBidirectionalRorAL(uint uc)
@@ -2084,7 +2084,10 @@ Q_AUTOTEST_EXPORT void qt_nameprep(QString *source, int from)
firstNonAscii > from ? firstNonAscii - 1 : from);
// Strip prohibited output
- stripProhibitedOutput(source, firstNonAscii);
+ if (containsProhibitedOuptut(source, firstNonAscii)) {
+ source->resize(from);
+ return;
+ }
// Check for valid bidirectional characters
bool containsLCat = false;