From ebc134db484eee31491836b619aad1ee86e3070e Mon Sep 17 00:00:00 2001 From: Martin Petersson Date: Fri, 6 May 2011 13:00:53 +0200 Subject: Make QHostAddress.toString() follow RFC-5952 for IPv6 address format. Task-number: QTBUG-18426 Reviewed-by: Peter Hartmann --- src/network/kernel/qhostaddress.cpp | 31 ++++++++++++++++++--- tests/auto/qhostaddress/tst_qhostaddress.cpp | 40 ++++++++++++++++------------ 2 files changed, 51 insertions(+), 20 deletions(-) diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp index ae7d7a1..4e7c286 100644 --- a/src/network/kernel/qhostaddress.cpp +++ b/src/network/kernel/qhostaddress.cpp @@ -720,7 +720,8 @@ Q_IPV6ADDR QHostAddress::toIPv6Address() const Returns the address as a string. For example, if the address is the IPv4 address 127.0.0.1, the - returned string is "127.0.0.1". + returned string is "127.0.0.1". For IPv6 the string format will + follow the RFC5952 recommendation. \sa toIPv4Address() */ @@ -741,8 +742,32 @@ QString QHostAddress::toString() const ugle[i] = (quint16(d->a6[2*i]) << 8) | quint16(d->a6[2*i+1]); } QString s; - s.sprintf("%X:%X:%X:%X:%X:%X:%X:%X", - ugle[0], ugle[1], ugle[2], ugle[3], ugle[4], ugle[5], ugle[6], ugle[7]); + QString temp; + bool zeroDetected = false; + bool zeroShortened = false; + for (int i = 0; i < 8; i++) { + if ((ugle[i] != 0) || zeroShortened) { + temp.sprintf("%X", ugle[i]); + s.append(temp); + if (zeroDetected) + zeroShortened = true; + } else { + if (!zeroDetected) { + if (i<7 && (ugle[i+1] == 0)) { + s.append(QLatin1Char(':')); + zeroDetected = true; + } else { + temp.sprintf("%X", ugle[i]); + s.append(temp); + if (i<7) + s.append(QLatin1Char(':')); + } + } + } + if (i<7 && ((ugle[i] != 0) || zeroShortened || (i==0 && zeroDetected))) + s.append(QLatin1Char(':')); + } + if (!d->scopeId.isEmpty()) s.append(QLatin1Char('%') + d->scopeId); return s; diff --git a/tests/auto/qhostaddress/tst_qhostaddress.cpp b/tests/auto/qhostaddress/tst_qhostaddress.cpp index bd020aa..e2043a5 100644 --- a/tests/auto/qhostaddress/tst_qhostaddress.cpp +++ b/tests/auto/qhostaddress/tst_qhostaddress.cpp @@ -164,21 +164,27 @@ void tst_QHostAddress::setAddress_QString_data() QTest::newRow("ip4_04") << QString("255.3.2.1\r ") << (bool)TRUE << QString("255.3.2.1") << 4; QTest::newRow("ip4_05") << QString("0.0.0.0") << (bool)TRUE << QString("0.0.0.0") << 4; - // for the format of IPv6 addresses see also RFC 1884 + // for the format of IPv6 addresses see also RFC 5952 QTest::newRow("ip6_00") << QString("FEDC:BA98:7654:3210:FEDC:BA98:7654:3210") << (bool)TRUE << QString("FEDC:BA98:7654:3210:FEDC:BA98:7654:3210") << 6; - QTest::newRow("ip6_01") << QString("1080:0000:0000:0000:0008:0800:200C:417A") << (bool)TRUE << QString("1080:0:0:0:8:800:200C:417A") << 6; - QTest::newRow("ip6_02") << QString("1080:0:0:0:8:800:200C:417A") << (bool)TRUE << QString("1080:0:0:0:8:800:200C:417A") << 6; - QTest::newRow("ip6_03") << QString("1080::8:800:200C:417A") << (bool)TRUE << QString("1080:0:0:0:8:800:200C:417A") << 6; - QTest::newRow("ip6_04") << QString("FF01::43") << (bool)TRUE << QString("FF01:0:0:0:0:0:0:43") << 6; - QTest::newRow("ip6_05") << QString("::1") << (bool)TRUE << QString("0:0:0:0:0:0:0:1") << 6; - QTest::newRow("ip6_06") << QString("1::") << (bool)TRUE << QString("1:0:0:0:0:0:0:0") << 6; - QTest::newRow("ip6_07") << QString("::") << (bool)TRUE << QString("0:0:0:0:0:0:0:0") << 6; - QTest::newRow("ip6_08") << QString("0:0:0:0:0:0:13.1.68.3") << (bool)TRUE << QString("0:0:0:0:0:0:D01:4403") << 6; - QTest::newRow("ip6_09") << QString("::13.1.68.3") << (bool)TRUE << QString("0:0:0:0:0:0:D01:4403") << 6; - QTest::newRow("ip6_10") << QString("0:0:0:0:0:FFFF:129.144.52.38") << (bool)TRUE << QString("0:0:0:0:0:FFFF:8190:3426") << 6; - QTest::newRow("ip6_11") << QString("::FFFF:129.144.52.38") << (bool)TRUE << QString("0:0:0:0:0:FFFF:8190:3426") << 6; - QTest::newRow("ip6_12") << QString("1::FFFF:129.144.52.38") << (bool)TRUE << QString("1:0:0:0:0:FFFF:8190:3426") << 6; - QTest::newRow("ip6_13") << QString("A:B::D:E") << (bool)TRUE << QString("A:B:0:0:0:0:D:E") << 6; + QTest::newRow("ip6_01") << QString("1080:0000:0000:0000:0008:0800:200C:417A") << (bool)TRUE << QString("1080::8:800:200C:417A") << 6; + QTest::newRow("ip6_02") << QString("1080:0:0:0:8:800:200C:417A") << (bool)TRUE << QString("1080::8:800:200C:417A") << 6; + QTest::newRow("ip6_03") << QString("1080::8:800:200C:417A") << (bool)TRUE << QString("1080::8:800:200C:417A") << 6; + QTest::newRow("ip6_04") << QString("FF01::43") << (bool)TRUE << QString("FF01::43") << 6; + QTest::newRow("ip6_05") << QString("::1") << (bool)TRUE << QString("::1") << 6; + QTest::newRow("ip6_06") << QString("1::") << (bool)TRUE << QString("1::") << 6; + QTest::newRow("ip6_07") << QString("::") << (bool)TRUE << QString("::") << 6; + QTest::newRow("ip6_08") << QString("0:0:0:0:0:0:13.1.68.3") << (bool)TRUE << QString("::D01:4403") << 6; + QTest::newRow("ip6_09") << QString("::13.1.68.3") << (bool)TRUE << QString("::D01:4403") << 6; + QTest::newRow("ip6_10") << QString("0:0:0:0:0:FFFF:129.144.52.38") << (bool)TRUE << QString("::FFFF:8190:3426") << 6; + QTest::newRow("ip6_11") << QString("::FFFF:129.144.52.38") << (bool)TRUE << QString("::FFFF:8190:3426") << 6; + QTest::newRow("ip6_12") << QString("1::FFFF:129.144.52.38") << (bool)TRUE << QString("1::FFFF:8190:3426") << 6; + QTest::newRow("ip6_13") << QString("A:B::D:E") << (bool)TRUE << QString("A:B::D:E") << 6; + QTest::newRow("ip6_14") << QString("1080:0:1:0:8:800:200C:417A") << (bool)TRUE << QString("1080:0:1:0:8:800:200C:417A") << 6; + QTest::newRow("ip6_15") << QString("1080:0:1:0:8:800:200C:0") << (bool)TRUE << QString("1080:0:1:0:8:800:200C:0") << 6; + QTest::newRow("ip6_16") << QString("1080:0:1:0:8:800:0:0") << (bool)TRUE << QString("1080:0:1:0:8:800::") << 6; + QTest::newRow("ip6_17") << QString("1080:0:0:0:8:800:0:0") << (bool)TRUE << QString("1080::8:800:0:0") << 6; + QTest::newRow("ip6_18") << QString("0:1:1:1:8:800:0:0") << (bool)TRUE << QString("0:1:1:1:8:800::") << 6; + QTest::newRow("ip6_19") << QString("0:1:1:1:8:800:0:1") << (bool)TRUE << QString("0:1:1:1:8:800:0:1") << 6; QTest::newRow("error_00") << QString("foobarcom") << (bool)FALSE << QString() << 0; QTest::newRow("error_01") << QString("foo.bar.com") << (bool)FALSE << QString() << 0; @@ -329,16 +335,16 @@ void tst_QHostAddress::scopeId() { QHostAddress address("fe80::2e0:4cff:fefb:662a%eth0"); QCOMPARE(address.scopeId(), QString("eth0")); - QCOMPARE(address.toString().toLower(), QString("fe80:0:0:0:2e0:4cff:fefb:662a%eth0")); + QCOMPARE(address.toString().toLower(), QString("fe80::2e0:4cff:fefb:662a%eth0")); QHostAddress address2("fe80::2e0:4cff:fefb:662a"); QCOMPARE(address2.scopeId(), QString()); address2.setScopeId(QString("en0")); - QCOMPARE(address2.toString().toLower(), QString("fe80:0:0:0:2e0:4cff:fefb:662a%en0")); + QCOMPARE(address2.toString().toLower(), QString("fe80::2e0:4cff:fefb:662a%en0")); address2 = address; QCOMPARE(address2.scopeId(), QString("eth0")); - QCOMPARE(address2.toString().toLower(), QString("fe80:0:0:0:2e0:4cff:fefb:662a%eth0")); + QCOMPARE(address2.toString().toLower(), QString("fe80::2e0:4cff:fefb:662a%eth0")); } void tst_QHostAddress::hashKey() -- cgit v0.12 From 8447f5616be731d78081f326bb9cb3f5aa9087a4 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 6 May 2011 13:13:42 +0200 Subject: QT_USE_QSTRINGBUILDER to fix source compatibility In 4.8 we added support for using StringBuilder with QByteArray. But this is breaking source compatibility for people that used QT_USE_FAST_OPERATOR_PLUS in Qt 4.7. So we introduce a new macro Notice that QT_USE_FAST_CONCATENATION was not working without QT_USE_FAST_OPERATOR_PLUS, so we remove the checking of that macro. Reviewed-by: joao --- doc/src/snippets/qstring/stringbuilder.cpp | 7 +------ src/corelib/tools/qbytearray.h | 13 ++++++------- src/corelib/tools/qstring.cpp | 10 +++------- src/corelib/tools/qstring.h | 8 +++----- src/corelib/tools/qstringbuilder.h | 4 +++- src/qbase.pri | 2 +- tests/auto/qstringbuilder1/tst_qstringbuilder1.cpp | 3 +-- tests/auto/qstringbuilder2/tst_qstringbuilder2.cpp | 3 +-- tests/auto/qstringbuilder3/tst_qstringbuilder3.cpp | 3 +-- tests/auto/qstringbuilder4/tst_qstringbuilder4.cpp | 3 +-- 10 files changed, 21 insertions(+), 35 deletions(-) diff --git a/doc/src/snippets/qstring/stringbuilder.cpp b/doc/src/snippets/qstring/stringbuilder.cpp index 8ff1dd8..b8acbc1 100644 --- a/doc/src/snippets/qstring/stringbuilder.cpp +++ b/doc/src/snippets/qstring/stringbuilder.cpp @@ -49,14 +49,9 @@ //! [0] //! [3] - #define QT_USE_FAST_CONCATENATION + DEFINES *= QT_USE_QSTRINGBUILDER //! [3] -//! [4] - #define QT_USE_FAST_CONCATENATION - #define QT_USE_FAST_OPERATOR_PLUS -//! [4] - //! [5] #include diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h index 0627b4e..df58d95 100644 --- a/src/corelib/tools/qbytearray.h +++ b/src/corelib/tools/qbytearray.h @@ -57,9 +57,10 @@ # ifdef QT_USE_FAST_OPERATOR_PLUS # undef QT_USE_FAST_OPERATOR_PLUS # endif -# ifdef QT_USE_FAST_CONCATENATION -# undef QT_USE_FAST_CONCATENATION +# ifdef QT_USE_QSTRINGBUILDER +# undef QT_USE_QSTRINGBUILDER # endif + #endif @@ -559,8 +560,7 @@ inline bool operator>=(const QByteArray &a1, const char *a2) { return qstrcmp(a1, a2) >= 0; } inline bool operator>=(const char *a1, const QByteArray &a2) { return qstrcmp(a1, a2) >= 0; } -#ifndef QT_USE_FAST_OPERATOR_PLUS -# ifndef QT_USE_FAST_CONCATENATION +#if !defined(QT_USE_QSTRINGBUILDER) inline const QByteArray operator+(const QByteArray &a1, const QByteArray &a2) { return QByteArray(a1) += a2; } inline const QByteArray operator+(const QByteArray &a1, const char *a2) @@ -571,8 +571,7 @@ inline const QByteArray operator+(const char *a1, const QByteArray &a2) { return QByteArray(a1) += a2; } inline const QByteArray operator+(char a1, const QByteArray &a2) { return QByteArray(&a1, 1) += a2; } -# endif // QT_USE_FAST_CONCATENATION -#endif // QT_USE_FAST_OPERATOR_PLUS +#endif // QT_USE_QSTRINGBUILDER inline QBool QByteArray::contains(const char *c) const { return QBool(indexOf(c) != -1); } inline QByteArray &QByteArray::replace(char before, const char *c) @@ -615,7 +614,7 @@ QT_END_NAMESPACE QT_END_HEADER -#ifdef QT_USE_FAST_CONCATENATION +#ifdef QT_USE_QSTRINGBUILDER #include #endif diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 5493ba9..3b3f715 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -777,16 +777,12 @@ const QString::Null QString::null = { }; \snippet doc/src/snippets/qstring/stringbuilder.cpp 5 - A more global approach is to include this define: + A more global approach which is the most convenient but + not entirely source compatible, is to this define in your + .pro file: \snippet doc/src/snippets/qstring/stringbuilder.cpp 3 - and use \c{'%'} instead of \c{'+'} for string concatenation - everywhere. The third approach, which is the most convenient but - not entirely source compatible, is to include two defines: - - \snippet doc/src/snippets/qstring/stringbuilder.cpp 4 - and the \c{'+'} will automatically be performed as the \c{QStringBuilder} \c{'%'} everywhere. diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index 6418a8c..7c4367e 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -1016,8 +1016,7 @@ inline int QByteArray::findRev(const QString &s, int from) const # endif // QT3_SUPPORT #endif // QT_NO_CAST_TO_ASCII -#ifndef QT_USE_FAST_OPERATOR_PLUS -# ifndef QT_USE_FAST_CONCATENATION +#if !defined(QT_USE_FAST_OPERATOR_PLUS) && !defined(QT_USE_QSTRINGBUILDER) inline const QString operator+(const QString &s1, const QString &s2) { QString t(s1); t += s2; return t; } inline const QString operator+(const QString &s1, QChar s2) @@ -1038,8 +1037,7 @@ inline QT_ASCII_CAST_WARN const QString operator+(const QByteArray &ba, const QS inline QT_ASCII_CAST_WARN const QString operator+(const QString &s, const QByteArray &ba) { QString t(s); t += QString::fromAscii(ba.constData(), qstrnlen(ba.constData(), ba.size())); return t; } # endif // QT_NO_CAST_FROM_ASCII -# endif // QT_USE_FAST_CONCATENATION -#endif // QT_USE_FAST_OPERATOR_PLUS +#endif // QT_USE_QSTRINGBUILDER #ifndef QT_NO_STL inline std::string QString::toStdString() const @@ -1288,7 +1286,7 @@ QT_END_NAMESPACE QT_END_HEADER -#ifdef QT_USE_FAST_CONCATENATION +#if defined(QT_USE_FAST_OPERATOR_PLUS) || defined(QT_USE_QSTRINGBUILDER) #include #endif diff --git a/src/corelib/tools/qstringbuilder.h b/src/corelib/tools/qstringbuilder.h index 2d3475f..029aa0b 100644 --- a/src/corelib/tools/qstringbuilder.h +++ b/src/corelib/tools/qstringbuilder.h @@ -410,7 +410,9 @@ operator%(const A &a, const B &b) return QStringBuilder::type, typename QConcatenable::type>(a, b); } -#ifdef QT_USE_FAST_OPERATOR_PLUS +// QT_USE_FAST_OPERATOR_PLUS was introduced in 4.7, QT_USE_QSTRINGBUILDER is to be used from 4.8 onwards +// QT_USE_FAST_OPERATOR_PLUS does not remove the normal operator+ for QByteArray +#if defined(QT_USE_FAST_OPERATOR_PLUS) || defined(QT_USE_QSTRINGBUILDER) template QStringBuilder::type, typename QConcatenable::type> operator+(const A &a, const B &b) diff --git a/src/qbase.pri b/src/qbase.pri index ce69757..c4d081f 100644 --- a/src/qbase.pri +++ b/src/qbase.pri @@ -163,7 +163,7 @@ contains(QT_PRODUCT, OpenSource.*):DEFINES *= QT_OPENSOURCE DEFINES *= QT_NO_CAST_TO_ASCII QT_ASCII_CAST_WARNINGS contains(QT_CONFIG, qt3support):DEFINES *= QT3_SUPPORT DEFINES *= QT_MOC_COMPAT #we don't need warnings from calling moc code in our generated code -DEFINES *= QT_USE_FAST_OPERATOR_PLUS QT_USE_FAST_CONCATENATION +DEFINES *= QT_USE_QSTRINGBUILDER TARGET = $$qtLibraryTarget($$TARGET$$QT_LIBINFIX) #do this towards the end diff --git a/tests/auto/qstringbuilder1/tst_qstringbuilder1.cpp b/tests/auto/qstringbuilder1/tst_qstringbuilder1.cpp index 36b6b80..463f200 100644 --- a/tests/auto/qstringbuilder1/tst_qstringbuilder1.cpp +++ b/tests/auto/qstringbuilder1/tst_qstringbuilder1.cpp @@ -44,8 +44,7 @@ // this is the "no harm done" version. Only operator% is active, // with NO_CAST * defined #define P % -#undef QT_USE_FAST_OPERATOR_PLUS -#undef QT_USE_FAST_CONCATENATION +#undef QT_USE_QSTRINGBUILDER #define QT_NO_CAST_FROM_ASCII #define QT_NO_CAST_TO_ASCII diff --git a/tests/auto/qstringbuilder2/tst_qstringbuilder2.cpp b/tests/auto/qstringbuilder2/tst_qstringbuilder2.cpp index 88b1f73..bcf88cb 100644 --- a/tests/auto/qstringbuilder2/tst_qstringbuilder2.cpp +++ b/tests/auto/qstringbuilder2/tst_qstringbuilder2.cpp @@ -45,8 +45,7 @@ // based version // with NO_CAST * defined #define P + -#define QT_USE_FAST_OPERATOR_PLUS -#define QT_USE_FAST_CONCATENATION +#define QT_USE_QSTRINGBUILDER #define QT_NO_CAST_FROM_ASCII #define QT_NO_CAST_TO_ASCII diff --git a/tests/auto/qstringbuilder3/tst_qstringbuilder3.cpp b/tests/auto/qstringbuilder3/tst_qstringbuilder3.cpp index afc3333..338fbf4 100644 --- a/tests/auto/qstringbuilder3/tst_qstringbuilder3.cpp +++ b/tests/auto/qstringbuilder3/tst_qstringbuilder3.cpp @@ -44,8 +44,7 @@ // this is the "no harm done" version. Only operator% is active, // with NO_CAST * _not_ defined #define P % -#undef QT_USE_FAST_OPERATOR_PLUS -#undef QT_USE_FAST_CONCATENATION +#undef QT_USE_QSTRINGBUILDER #undef QT_NO_CAST_FROM_ASCII #undef QT_NO_CAST_TO_ASCII diff --git a/tests/auto/qstringbuilder4/tst_qstringbuilder4.cpp b/tests/auto/qstringbuilder4/tst_qstringbuilder4.cpp index ae4100a..d046e59 100644 --- a/tests/auto/qstringbuilder4/tst_qstringbuilder4.cpp +++ b/tests/auto/qstringbuilder4/tst_qstringbuilder4.cpp @@ -45,8 +45,7 @@ // based version // with NO_CAST * _not_ defined #define P + -#define QT_USE_FAST_OPERATOR_PLUS -#define QT_USE_FAST_CONCATENATION +#define QT_USE_QSTRINGBUILDER #undef QT_NO_CAST_FROM_ASCII #undef QT_NO_CAST_TO_ASCII -- cgit v0.12 From a363fad3f45335c6f03108a0ece5472901aa970f Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 4 Apr 2011 10:47:28 +0200 Subject: Doc: update platform notes on Mac to reflect WA_MacNoCocoaChildWindow (cherry picked from commit b240f8a2ee3b7ff82a389fbf5dfd076792f385e8) --- doc/src/platforms/platform-notes.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/platforms/platform-notes.qdoc b/doc/src/platforms/platform-notes.qdoc index 24b297f..aa39957 100644 --- a/doc/src/platforms/platform-notes.qdoc +++ b/doc/src/platforms/platform-notes.qdoc @@ -612,7 +612,7 @@ Qt::WA_MacNormalSize, Qt::WA_MacSmallSize, Qt::WA_MacMiniSize, Qt::WA_MacVariableSize, Qt::WA_MacBrushedMetal, Qt::WA_MacAlwaysShowToolWindow, Qt::WA_MacFrameworkScaled, Qt::WA_MacNoShadow, Qt::Sheet, Qt::Drawer, Qt::MacWindowToolBarButtonHint, - QMainWindow::unifiedTitleAndToolBarOnMac + QMainWindow::unifiedTitleAndToolBarOnMac, WA_MacNoCocoaChildWindow \section2 Mixing Qt with native code Two classes are awailable for either adding native Cocoa views/controls -- cgit v0.12 From f5acce7e11fa7c6abf5cf5352ec750c1ac65dd29 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 16 May 2011 13:47:09 +0200 Subject: Fix crashes with regular expressions QtScript on ARM traditional architectures Save and restore the r8 register properly. Backport of http://trac.webkit.org/changeset/65242 from WebKit trunk Reviewed-by: Jedrzej Nowacki --- src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexJIT.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexJIT.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexJIT.cpp index fcb8d86..1015923 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexJIT.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexJIT.cpp @@ -1312,6 +1312,9 @@ class RegexGenerator : private MacroAssembler { push(ARMRegisters::r4); push(ARMRegisters::r5); push(ARMRegisters::r6); +#if CPU(ARM_TRADITIONAL) + push(ARMRegisters::r8); // scratch register +#endif move(ARMRegisters::r3, output); #endif } @@ -1327,6 +1330,9 @@ class RegexGenerator : private MacroAssembler { pop(X86Registers::ebx); pop(X86Registers::ebp); #elif CPU(ARM) +#if CPU(ARM_TRADITIONAL) + pop(ARMRegisters::r8); // scratch register +#endif pop(ARMRegisters::r6); pop(ARMRegisters::r5); pop(ARMRegisters::r4); -- cgit v0.12 From 8e321cd869da7ff1cf0168da41aa0246b44867cc Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 16 May 2011 14:04:31 +0200 Subject: Fix inconsistency between Qt and ICU in Shift-JIS codec with regards to ASCII range Qt's Shift-JIS codec maps the characters 0x5c and 0x7e to unicode yen (0x5a) and unicode overline (0x203e). ICU and (as it turns out) Symbian's native Shift-JIS codec preserve 0x5c and 0x7e when converting to Unicode. Qt's behaviour creates a problem when loading japanese web sites that are encoded in Shift-JIS. When they reference external JavaScript files, those tend to inherit the current page encoding (unless the character set is explicitly specified). Consequently JavaScript tends to contain regular expressions (as a built-in feature of the language), which in turn uses backslashes for escape sequences. Therefore it is crucial that the encodings used to decode the script preserve the ASCII range, i.e. do not convert 0x5c (ascii backslash) to something else. This patch corrects the behaviour of Qt's Shift-JIS codec to leave all characters < 0x80 unaltered in the process of conversion to and from Unicode. Task: QTBUG-19335 Reviewed-by: Lars Knoll --- src/plugins/codecs/jp/qsjiscodec.cpp | 4 +++- tests/auto/qtextcodec/tst_qtextcodec.cpp | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/plugins/codecs/jp/qsjiscodec.cpp b/src/plugins/codecs/jp/qsjiscodec.cpp index 49190d3..3ea5300 100644 --- a/src/plugins/codecs/jp/qsjiscodec.cpp +++ b/src/plugins/codecs/jp/qsjiscodec.cpp @@ -155,7 +155,9 @@ QString QSjisCodec::convertToUnicode(const char* chars, int len, ConverterState uchar ch = chars[i]; switch (nbuf) { case 0: - if (ch < 0x80 || IsKana(ch)) { + if (ch < 0x80) { + result += QValidChar(ch); + } else if (IsKana(ch)) { // JIS X 0201 Latin or JIS X 0201 Kana u = conv->jisx0201ToUnicode(ch); result += QValidChar(u); diff --git a/tests/auto/qtextcodec/tst_qtextcodec.cpp b/tests/auto/qtextcodec/tst_qtextcodec.cpp index 43656c8..15ecc3b 100644 --- a/tests/auto/qtextcodec/tst_qtextcodec.cpp +++ b/tests/auto/qtextcodec/tst_qtextcodec.cpp @@ -106,6 +106,8 @@ private slots: void moreToFromUnicode_data(); void moreToFromUnicode(); + + void shiftJis(); }; void tst_QTextCodec::toUnicode_data() @@ -2236,6 +2238,19 @@ void tst_QTextCodec::moreToFromUnicode() QCOMPARE(testData, cStr); } +void tst_QTextCodec::shiftJis() +{ + QByteArray backslashTilde("\\~"); + QTextCodec* codec = QTextCodec::codecForName("shift_jis"); + QString string = codec->toUnicode(backslashTilde); + QCOMPARE(string.length(), 2); + QCOMPARE(string.at(0), QChar(QLatin1Char('\\'))); + QCOMPARE(string.at(1), QChar(QLatin1Char('~'))); + + QByteArray encoded = codec->fromUnicode(string); + QCOMPARE(encoded, backslashTilde); +} + struct DontCrashAtExit { ~DontCrashAtExit() { QTextCodec *c = QTextCodec::codecForName("utf8"); -- cgit v0.12 From 1485cb0ff66dba95015d4451d812124b9ab27170 Mon Sep 17 00:00:00 2001 From: Martin Petersson Date: Wed, 18 May 2011 10:29:25 +0200 Subject: tst_q3dns: update test to follow RFC-5952. QHostAddress::toString() was updated to follow RFC-5952. Reviewed-by: Markus Goetz --- tests/auto/q3dns/tst_q3dns.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/q3dns/tst_q3dns.cpp b/tests/auto/q3dns/tst_q3dns.cpp index b97a604..7d633ef 100644 --- a/tests/auto/q3dns/tst_q3dns.cpp +++ b/tests/auto/q3dns/tst_q3dns.cpp @@ -144,7 +144,7 @@ void tst_Q3Dns::literals() QCOMPARE((int) ip6literal1.addresses().count(), 0); Q3Dns ip6literal2("::1", Q3Dns::Aaaa); - QCOMPARE(ip6literal2.addresses().first().toString(), QString("0:0:0:0:0:0:0:1")); + QCOMPARE(ip6literal2.addresses().first().toString(), QString("::1")); QCOMPARE((int) ip6literal2.addresses().count(), 1); } -- cgit v0.12 From 1eff8e70fb9154c3ee96aefd8f6fd44429b117fa Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 17 May 2011 13:07:42 +0100 Subject: Symbian socket: Implement systemProxyForQuery for service networks When the specified (or active/default) network is a service network, try to determine the appropriate IAP network within it. This is the highest priority active network (if any) followed by the highest priority discovered network (if any) or the highest priority network as a last resort. As Symbian doesn't include proxy type in the comms database, proxies are assumed to be http type unless the port is 1080 (iana assigned port for SOCKS) in which case the proxy is set as SOCKS type. Also fixed unitialised member issue with SymbianIapId internal class Task-number: QTBUG-18618 Reviewed-by: Markus Goetz --- src/network/kernel/qnetworkproxy_symbian.cpp | 89 +++++++++++++--------- .../tst_qnetworkproxyfactory.cpp | 6 +- 2 files changed, 56 insertions(+), 39 deletions(-) diff --git a/src/network/kernel/qnetworkproxy_symbian.cpp b/src/network/kernel/qnetworkproxy_symbian.cpp index 4ba14c0..1fb31b5 100644 --- a/src/network/kernel/qnetworkproxy_symbian.cpp +++ b/src/network/kernel/qnetworkproxy_symbian.cpp @@ -68,74 +68,80 @@ QT_BEGIN_NAMESPACE class SymbianIapId { public: - enum State{ - NotValid, - Valid - }; - Q_DECLARE_FLAGS(States, State) - SymbianIapId() {} + SymbianIapId() : valid(false), id(0) {} ~SymbianIapId() {} - void setIapId(TUint32 iapId) { iapState |= Valid; id = iapId; } - bool isValid() { return iapState == Valid; } + void setIapId(TUint32 iapId) { valid = true; id = iapId; } + bool isValid() { return valid; } TUint32 iapId() { return id; } private: - QFlags iapState; + bool valid; TUint32 id; }; -Q_DECLARE_OPERATORS_FOR_FLAGS(SymbianIapId::States) - class SymbianProxyQuery { public: static QNetworkConfiguration findCurrentConfiguration(QNetworkConfigurationManager& configurationManager); + static QNetworkConfiguration findCurrentConfigurationFromServiceNetwork(const QNetworkConfiguration& serviceNetwork); static SymbianIapId getIapId(QNetworkConfigurationManager &configurationManager, const QNetworkProxyQuery &query); static CCDIAPRecord *getIapRecordLC(TUint32 aIAPId, CMDBSession &aDb); static CMDBRecordSet *prepareQueryLC(TUint32 serviceId, TDesC& serviceType); static QList proxyQueryL(TUint32 aIAPId, const QNetworkProxyQuery &query); }; +QNetworkConfiguration SymbianProxyQuery::findCurrentConfigurationFromServiceNetwork(const QNetworkConfiguration& serviceNetwork) +{ + // Note: This code assumes that the only unambigious way to + // find current proxy config is if there is only one access point + // or if the found access point is immediately usable. + QList childConfigurations = serviceNetwork.children(); + if (childConfigurations.isEmpty()) { + qWarning("QNetworkProxyFactory::systemProxyForQuery called with empty service network"); + return QNetworkConfiguration(); + } else if (childConfigurations.count() == 1) { + //if only one IAP in the service network, it's always going to be used. + return childConfigurations.at(0); + } else { + //use highest priority active config, if available + for (int index = 0; index < childConfigurations.count(); index++) { + QNetworkConfiguration childConfig = childConfigurations.at(index); + if (childConfig.isValid() && childConfig.state() == QNetworkConfiguration::Active) + return childConfig; + } + //otherwise use highest priority discovered config (that's the one which will be activated if start were called now) + for (int index = 0; index < childConfigurations.count(); index++) { + QNetworkConfiguration childConfig = childConfigurations.at(index); + if (childConfig.isValid() && childConfig.state() == QNetworkConfiguration::Discovered) + return childConfig; + } + //otherwise the highest priority defined (most likely to be activated if all were available when start is called) + qWarning("QNetworkProxyFactory::systemProxyForQuery called with service network, but none of its IAPs are available"); + return childConfigurations.at(0); + } +} + QNetworkConfiguration SymbianProxyQuery::findCurrentConfiguration(QNetworkConfigurationManager& configurationManager) { QList activeConfigurations = configurationManager.allConfigurations( QNetworkConfiguration::Active); - QNetworkConfiguration currentConfig; if (activeConfigurations.count() > 0) { - currentConfig = activeConfigurations.at(0); + return activeConfigurations.at(0); } else { // No active configurations, try default one QNetworkConfiguration defaultConfiguration = configurationManager.defaultConfiguration(); if (defaultConfiguration.isValid()) { switch (defaultConfiguration.type()) { case QNetworkConfiguration::InternetAccessPoint: - currentConfig = defaultConfiguration; - break; + return defaultConfiguration; case QNetworkConfiguration::ServiceNetwork: - { - // Note: This code assumes that the only unambigious way to - // find current proxy config is if there is only one access point - // or if the found access point is immediately usable. - QList childConfigurations = defaultConfiguration.children(); - if (childConfigurations.count() == 1) { - currentConfig = childConfigurations.at(0); - } else { - for (int index = 0; index < childConfigurations.count(); index++) { - QNetworkConfiguration childConfig = childConfigurations.at(index); - if (childConfig.isValid() && childConfig.state() == QNetworkConfiguration::Discovered) { - currentConfig = childConfig; - break; - } - } - } - } - break; + return findCurrentConfigurationFromServiceNetwork(defaultConfiguration); case QNetworkConfiguration::UserChoice: - // User choice is not a valid configuration for proxy discovery + qWarning("QNetworkProxyFactory::systemProxyForQuery called with user choice configuration, which is not valid"); break; } } } - return currentConfig; + return QNetworkConfiguration(); } SymbianIapId SymbianProxyQuery::getIapId(QNetworkConfigurationManager& configurationManager, const QNetworkProxyQuery &query) @@ -147,7 +153,11 @@ SymbianIapId SymbianProxyQuery::getIapId(QNetworkConfigurationManager& configura //If config is not specified, then try to find out an active or default one currentConfig = findCurrentConfiguration(configurationManager); } - if (currentConfig.isValid()) { + if (currentConfig.isValid() && currentConfig.type() == QNetworkConfiguration::ServiceNetwork) { + //convert service network to the real IAP. + currentConfig = findCurrentConfigurationFromServiceNetwork(currentConfig); + } + if (currentConfig.isValid() && currentConfig.type() == QNetworkConfiguration::InternetAccessPoint) { // Note: the following code assumes that the identifier is in format // I_xxxx where xxxx is the identifier of IAP. This is meant as a // temporary solution until there is a support for returning @@ -236,7 +246,12 @@ QList SymbianProxyQuery::proxyQueryL(TUint32 aIAPId, const QNetwo CleanupStack::Pop(); // serverName TUint32 port = proxyRecord->iPortNumber; - QNetworkProxy proxy(QNetworkProxy::HttpProxy, serverNameQt, port); + //Symbian config doesn't include proxy type, assume http unless the port matches assigned port of another type + //Mobile operators use a wide variety of port numbers for http proxies. + QNetworkProxy::ProxyType proxyType = QNetworkProxy::HttpProxy; + if (port == 1080) //IANA assigned port for SOCKS + proxyType = QNetworkProxy::Socks5Proxy; + QNetworkProxy proxy(proxyType, serverNameQt, port); foundProxies.append(proxy); } } diff --git a/tests/auto/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp b/tests/auto/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp index 82a4193..b04556c 100644 --- a/tests/auto/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp +++ b/tests/auto/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp @@ -146,6 +146,10 @@ void tst_QNetworkProxyFactory::systemProxyForQuery() const void tst_QNetworkProxyFactory::fromConfigurations() { QNetworkConfigurationManager manager; + //update is done to get the active / discovered states + manager.updateConfigurations(); + connect(&manager, SIGNAL(updateCompleted()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); QList proxies; QUrl url(QLatin1String("http://qt.nokia.com")); //get from known configurations @@ -233,8 +237,6 @@ void tst_QNetworkProxyFactory::inNetworkAccessManager() foreach (QNetworkProxy proxy, proxies) { qDebug() << formatProxyName(proxy); } - if (config.type() != QNetworkConfiguration::InternetAccessPoint) - QEXPECT_FAIL("","QNetworkProxyFactory::systemProxyForQuery doesn't work for service networks yet", Continue); QCOMPARE(factory->returnedList, proxies); } -- cgit v0.12