From 656376e789d48b07f545d7bbf8bcd6f980cc278d Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Tue, 22 Jan 2013 19:25:02 +0100 Subject: [PATCH] Fix remaining issues in the URI methods Change-Id: I0a402fb38f72d067b9bccae1b0c85cfca2cc2812 Reviewed-by: Simon Hausmann --- qv4globalobject.cpp | 39 ++++++++++++++++++++++++++++----------- tests/TestExpectations | 20 -------------------- 2 files changed, 28 insertions(+), 31 deletions(-) diff --git a/qv4globalobject.cpp b/qv4globalobject.cpp index 5d01d86..059dfe7 100644 --- a/qv4globalobject.cpp +++ b/qv4globalobject.cpp @@ -149,6 +149,13 @@ static QString unescape(const QString &input) static const char uriReserved[] = ";/?:@&=+$,"; static const char uriUnescaped[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.!~*'()"; +static void addEscapeSequence(QString &output, uchar ch) +{ + output.append(QLatin1Char('%')); + output.append(QLatin1Char(toHex(ch >> 4))); + output.append(QLatin1Char(toHex(ch & 0xf))); +} + static QString encode(const QString &input, const QString &unescapedSet, bool *ok) { *ok = true; @@ -158,7 +165,7 @@ static QString encode(const QString &input, const QString &unescapedSet, bool *o while (i < length) { const QChar c = input.at(i); if (!unescapedSet.contains(c)) { - ushort uc = c.unicode(); + uint uc = c.unicode(); if ((uc >= 0xDC00) && (uc <= 0xDFFF)) { *ok = false; break; @@ -169,19 +176,29 @@ static QString encode(const QString &input, const QString &unescapedSet, bool *o *ok = false; break; } - const ushort uc2 = input.at(i).unicode(); - if ((uc < 0xDC00) || (uc > 0xDFFF)) { + const uint uc2 = input.at(i).unicode(); + if ((uc2 < 0xDC00) || (uc2 > 0xDFFF)) { *ok = false; break; } uc = ((uc - 0xD800) * 0x400) + (uc2 - 0xDC00) + 0x10000; } - QString tmp(1, QChar(uc)); - QByteArray octets = tmp.toUtf8(); - for (int j = 0; j < octets.length(); ++j) { - output.append(QLatin1Char('%')); - output.append(QLatin1Char(toHex(octets.at(j) >> 4))); - output.append(QLatin1Char(toHex(octets.at(j)))); + if (uc < 0x80) { + addEscapeSequence(output, (uchar)uc); + } else { + if (uc < 0x0800) { + addEscapeSequence(output, 0xc0 | ((uchar) (uc >> 6))); + } else { + + if (QChar::requiresSurrogates(uc)) { + addEscapeSequence(output, 0xf0 | ((uchar) (uc >> 18))); + addEscapeSequence(output, 0x80 | (((uchar) (uc >> 12)) & 0x3f)); + } else { + addEscapeSequence(output, 0xe0 | (((uchar) (uc >> 12)) & 0x3f)); + } + addEscapeSequence(output, 0x80 | (((uchar) (uc >> 6)) & 0x3f)); + } + addEscapeSequence(output, 0x80 | ((uchar) (uc&0x3f))); } } else { output.append(c); @@ -252,7 +269,7 @@ static QString decode(const QString &input, const QString &reservedSet, bool *ok goto error; i += 2; - uc = (uc << 6) + b; + uc = (uc << 6) + (b & 0x3f); } if (uc < min_uc) goto error; @@ -601,7 +618,7 @@ Value GlobalFunctions::method_encodeURIComponent(ExecutionContext *context) QString uriString = context->argument(0).toString(context)->toQString(); bool ok; - QString out = encode(uriString, QString(), &ok); + QString out = encode(uriString, QString(uriUnescaped), &ok); if (!ok) context->throwURIError(Value::fromString(context, QStringLiteral("malformed URI sequence"))); diff --git a/tests/TestExpectations b/tests/TestExpectations index d719b5b..ab76a42 100644 --- a/tests/TestExpectations +++ b/tests/TestExpectations @@ -314,26 +314,6 @@ S15.12.2_A1 failing 15.12.3_2-3-a-2 failing 15.12.3_2-3-a-3 failing 15.12.3_4-1-2 failing -S15.1.3.3_A2.4_T1 failing -S15.1.3.3_A2.4_T2 failing -S15.1.3.3_A2.5_T1 failing -S15.1.3.4_A2.4_T1 failing -S15.1.3.4_A2.4_T2 failing -S15.1.3.4_A2.5_T1 failing -S15.1.3.4_A3.2_T1 failing -S15.1.3.4_A3.2_T2 failing -S15.1.3.4_A3.2_T3 failing -S15.1.3.4_A4_T1 failing -S15.1.3.4_A4_T2 failing -S15.1.3.4_A4_T3 failing -S15.1.3.4_A4_T4 failing -S15.1.3.4_A6_T1 failing -S15.1.3.1_A2.3_T1 failing -S15.1.3.1_A2.4_T1 failing -S15.1.3.1_A4_T2 failing -S15.1.3.2_A2.3_T1 failing -S15.1.3.2_A2.4_T1 failing -S15.1.3.2_A4_T2 failing 15.2.3.6-2-17-1 failing 15.2.3.6-4-291-1 failing 15.2.3.6-4-292-1 failing -- 2.7.4