From 147df10403ba280b3f04c1e3d6c4b1cf386abe5d Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Thu, 3 Feb 2011 12:28:27 +0100 Subject: Don't crash when creating backtrace for built-in JS function When the JIT is enabled, NativeFunctionWrapper (used for built-in functions such as Array.prototype.forEach) inherits JSFunction, so we must check whether the function is actually a JS (script) function before we start accessing script-specific properties. Task-number: QTBUG-17137 Reviewed-by: Olivier Goffart --- src/script/api/qscriptcontextinfo.cpp | 3 ++- tests/auto/qscriptcontext/tst_qscriptcontext.cpp | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/script/api/qscriptcontextinfo.cpp b/src/script/api/qscriptcontextinfo.cpp index db6b2d7..d39abe6 100644 --- a/src/script/api/qscriptcontextinfo.cpp +++ b/src/script/api/qscriptcontextinfo.cpp @@ -181,7 +181,8 @@ QScriptContextInfoPrivate::QScriptContextInfoPrivate(const QScriptContext *conte JSC::JSObject *callee = frame->callee(); if (callee && callee->inherits(&JSC::InternalFunction::info)) functionName = JSC::asInternalFunction(callee)->name(frame); - if (callee && callee->inherits(&JSC::JSFunction::info)) { + if (callee && callee->inherits(&JSC::JSFunction::info) + && !JSC::asFunction(callee)->isHostFunction()) { functionType = QScriptContextInfo::ScriptFunction; JSC::FunctionExecutable *body = JSC::asFunction(callee)->jsExecutable(); functionStartLineNumber = body->lineNo(); diff --git a/tests/auto/qscriptcontext/tst_qscriptcontext.cpp b/tests/auto/qscriptcontext/tst_qscriptcontext.cpp index 1a1576b..dd21555 100644 --- a/tests/auto/qscriptcontext/tst_qscriptcontext.cpp +++ b/tests/auto/qscriptcontext/tst_qscriptcontext.cpp @@ -860,6 +860,21 @@ void tst_QScriptContext::backtrace_data() QTest::newRow("js recursive") << source << expected; } + + { + QString source = QString::fromLatin1( + "[0].forEach(\n" + " function() {\n" + " result = bt();\n" + "}); result"); + + QStringList expected; + expected << "() at -1" + << "(0, 0, 0) at testfile:3" + << "forEach(0) at -1" + << "() at testfile:4"; + QTest::newRow("js callback from built-in") << source << expected; + } } -- cgit v0.12 From 71eb2bd23604d9c809f143496f781c1d5c065473 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 28 Jan 2011 17:46:30 +0100 Subject: move multiple inclusion check for feature files to correct location previously, features specified with an absolute path would not be covered by the multiple inclusion guard, unlike the one specified just by a name. this is of theoretical value only, as nobody specifies features via absolute path anyway ... Reviewed-by: mariusSO --- qmake/project.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qmake/project.cpp b/qmake/project.cpp index 8d8d9e0..4e2d743 100644 --- a/qmake/project.cpp +++ b/qmake/project.cpp @@ -1681,10 +1681,10 @@ QMakeProject::doProjectInclude(QString file, uchar flags, QMap Date: Fri, 28 Jan 2011 17:51:22 +0100 Subject: use const ref Reviewed-by: mariusSO --- qmake/project.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/project.cpp b/qmake/project.cpp index 4e2d743..1a13639 100644 --- a/qmake/project.cpp +++ b/qmake/project.cpp @@ -228,7 +228,7 @@ static QString varMap(const QString &x) return ret; } -static QStringList split_arg_list(QString params) +static QStringList split_arg_list(const QString ¶ms) { int quote = 0; QStringList args; -- cgit v0.12 From dbfca8da2807921069c0e53da33f6e7bd3e73479 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 28 Jan 2011 18:03:16 +0100 Subject: complain about unmatched quotes/parens using WarnDeprecated instead of WarnParser is a bit backwards, but we need something which is on by default and i don't feel like introducing a second parser warning mode for that. Reviewed-by: mariusSO --- qmake/project.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/qmake/project.cpp b/qmake/project.cpp index 1a13639..9c99c44 100644 --- a/qmake/project.cpp +++ b/qmake/project.cpp @@ -280,6 +280,8 @@ static QStringList split_arg_list(const QString ¶ms) ++last; } } + // Could do a check for unmatched parens here, but split_value_list() + // is called on all our output, so mistakes will be caught anyway. return args; } @@ -288,6 +290,7 @@ static QStringList split_value_list(const QString &vals) QString build; QStringList ret; QStack quote; + int parens = 0; const ushort LPAREN = '('; const ushort RPAREN = ')'; @@ -298,7 +301,7 @@ static QStringList split_value_list(const QString &vals) ushort unicode; const QChar *vals_data = vals.data(); const int vals_len = vals.length(); - for(int x = 0, parens = 0; x < vals_len; x++) { + for(int x = 0; x < vals_len; x++) { unicode = vals_data[x].unicode(); if(x != (int)vals_len-1 && unicode == BACKSLASH && (vals_data[x+1].unicode() == SINGLEQUOTE || vals_data[x+1].unicode() == DOUBLEQUOTE)) { @@ -322,6 +325,11 @@ static QStringList split_value_list(const QString &vals) } if(!build.isEmpty()) ret << build; + if (parens) + warn_msg(WarnDeprecated, "%s:%d: Unmatched parentheses are deprecated.", + parser.file.toLatin1().constData(), parser.line_no); + // Could do a check for unmatched quotes here, but doVariableReplaceExpand() + // is called on all our output, so mistakes will be caught anyway. return ret; } @@ -2966,6 +2974,9 @@ QMakeProject::doVariableReplaceExpand(const QString &str, QMap Date: Fri, 4 Feb 2011 09:28:58 +0100 Subject: Designer: Fix a crash in the Signal-Slot-Editor. Object search found deleted widgets by name when searching on the form window. Search main container instead, do not assert. Reviewed-by: Jarek Kobus Task-number: QTBUG-17179 --- .../signalsloteditor/signalslot_utils.cpp | 22 ++++++++++------------ .../signalsloteditor/signalsloteditorwindow.cpp | 2 +- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/tools/designer/src/components/signalsloteditor/signalslot_utils.cpp b/tools/designer/src/components/signalsloteditor/signalslot_utils.cpp index aecd1e5..d0af770 100644 --- a/tools/designer/src/components/signalsloteditor/signalslot_utils.cpp +++ b/tools/designer/src/components/signalsloteditor/signalslot_utils.cpp @@ -72,7 +72,6 @@ static void memberList(QDesignerFormEditorInterface *core, { if (!object) return; - // 1) member sheet const QDesignerMemberSheetExtension *members = qt_extension(core->extensionManager(), object); Q_ASSERT(members != 0); @@ -118,15 +117,15 @@ static void memberList(QDesignerFormEditorInterface *core, if (!metaDataBase) return; - const qdesigner_internal::MetaDataBaseItem *mdbItem = metaDataBase->metaDataBaseItem(object); - Q_ASSERT(mdbItem); - const QStringList mdbFakeMethods = member_type == qdesigner_internal::SlotMember ? mdbItem->fakeSlots() : mdbItem->fakeSignals(); - if (!mdbFakeMethods.empty()) - foreach (const QString &fakeMethod, mdbFakeMethods) - if (predicate(fakeMethod)) { - *it = ClassNameSignaturePair(className, fakeMethod); - ++it; - } + if (const qdesigner_internal::MetaDataBaseItem *mdbItem = metaDataBase->metaDataBaseItem(object)) { + const QStringList mdbFakeMethods = member_type == qdesigner_internal::SlotMember ? mdbItem->fakeSlots() : mdbItem->fakeSignals(); + if (!mdbFakeMethods.empty()) + foreach (const QString &fakeMethod, mdbFakeMethods) + if (predicate(fakeMethod)) { + *it = ClassNameSignaturePair(className, fakeMethod); + ++it; + } + } } namespace { @@ -245,10 +244,9 @@ namespace qdesigner_internal { ClassesMemberFunctions reverseClassesMemberFunctions(const QString &obj_name, MemberType member_type, const QString &peer, QDesignerFormWindowInterface *form) { - QObject *object = qFindChild(form, obj_name); + QObject *object = qFindChild(form->mainContainer(), obj_name); if (!object) return ClassesMemberFunctions(); - QDesignerFormEditorInterface *core = form->core(); ClassesMemberFunctions rc; diff --git a/tools/designer/src/components/signalsloteditor/signalsloteditorwindow.cpp b/tools/designer/src/components/signalsloteditor/signalsloteditorwindow.cpp index ecee08e..831649f 100644 --- a/tools/designer/src/components/signalsloteditor/signalsloteditorwindow.cpp +++ b/tools/designer/src/components/signalsloteditor/signalsloteditorwindow.cpp @@ -658,7 +658,7 @@ QWidget *ConnectionDelegate::createEditor(QWidget *parent, const qdesigner_internal::ClassesMemberFunctions class_list = qdesigner_internal::reverseClassesMemberFunctions(obj_name, type, peer, m_form); - QObject *object = qFindChild(m_form, obj_name); + QObject *object = qFindChild(m_form->mainContainer(), obj_name); inline_editor->addText(type == qdesigner_internal::SignalMember ? tr("") : tr("")); foreach (const qdesigner_internal::ClassMemberFunctions &class_info, class_list) { -- cgit v0.12 From de1cfc13c66fcb35d0a211bb5136ebc25279041a Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Fri, 4 Feb 2011 13:36:27 +0100 Subject: Don't crash when BMP color table is broken If the BMP's number of color table entries is out of bounds, we would resize our color table vector to a silly value, leading to crashes later on. If the number of color table entries is larger than 256, just stop processing the BMP since it's most probably corrupt. Task-number: QT-4534 Reviewed-by: Robert Griebl --- src/gui/image/qbmphandler.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp index 09c086a..6dea9d9 100644 --- a/src/gui/image/qbmphandler.cpp +++ b/src/gui/image/qbmphandler.cpp @@ -246,6 +246,8 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int if (depth != 32) { ncols = bi.biClrUsed ? bi.biClrUsed : 1 << nbits; + if (ncols > 256) // sanity check - don't run out of mem if color table is broken + return false; image.setColorCount(ncols); } -- cgit v0.12 From aa8d84efdc8e7dd26f36a3586050458d7be0c279 Mon Sep 17 00:00:00 2001 From: Denis Oliver Kropp Date: Fri, 4 Feb 2011 14:50:00 +0100 Subject: directfb: Pixmap creation always premultiplied the alpha even when it is already premultiplied in the image. This also avoids the temporary surface and blitting. Merge-request: 990 Reviewed-by: Marcel Schuette --- .../gfxdrivers/directfb/qdirectfbpixmap.cpp | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp index 6639983..50e0f5f 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp @@ -300,40 +300,26 @@ void QDirectFBPixmapData::fromImage(const QImage &img, Qt::ImageConversionFlags { alpha = QDirectFBPixmapData::hasAlphaChannel(img, flags); imageFormat = alpha ? screen->alphaPixmapFormat() : screen->pixelFormat(); + QImage image; if ((flags & ~Qt::NoOpaqueDetection) != Qt::AutoColor) { image = img.convertToFormat(imageFormat, flags); flags = Qt::AutoColor; } else if (img.format() == QImage::Format_RGB32 || img.depth() == 1) { image = img.convertToFormat(imageFormat, flags); + } else if (img.format() != imageFormat) { + image = img.convertToFormat(imageFormat, flags); } else { image = img; } - IDirectFBSurface *imageSurface = screen->createDFBSurface(image, image.format(), QDirectFBScreen::DontTrackSurface); - if (!imageSurface) { - qWarning("QDirectFBPixmapData::fromImage()"); - invalidate(); - return; - } - - dfbSurface = screen->createDFBSurface(image.size(), imageFormat, QDirectFBScreen::TrackSurface); + dfbSurface = screen->createDFBSurface(image, image.format(), QDirectFBScreen::NoPreallocated | QDirectFBScreen::TrackSurface); if (!dfbSurface) { qWarning("QDirectFBPixmapData::fromImage()"); invalidate(); return; } - if (image.hasAlphaChannel()) { - dfbSurface->Clear(dfbSurface, 0, 0, 0, 0); - dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_BLEND_ALPHACHANNEL); - } else { - dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX); - } - - dfbSurface->Blit(dfbSurface, imageSurface, 0, 0, 0); - imageSurface->Release(imageSurface); - w = image.width(); h = image.height(); is_null = (w <= 0 || h <= 0); -- cgit v0.12 From c696b4fe5a0acd85bc739fb148b8f76965f12d20 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 3 Feb 2011 19:26:36 +0100 Subject: Autotest: Use QElapsedTimer for timings --- tests/auto/qdbusperformance/tst_qdbusperformance.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/qdbusperformance/tst_qdbusperformance.cpp b/tests/auto/qdbusperformance/tst_qdbusperformance.cpp index 42db697..a5b4b98 100644 --- a/tests/auto/qdbusperformance/tst_qdbusperformance.cpp +++ b/tests/auto/qdbusperformance/tst_qdbusperformance.cpp @@ -125,7 +125,7 @@ void tst_QDBusPerformance::init() void tst_QDBusPerformance::callSpeed() { - QTime timer; + QElapsedTimer timer; int callCount = 0; timer.start(); @@ -141,7 +141,7 @@ void tst_QDBusPerformance::callSpeed() bool tst_QDBusPerformance::executeTest(const char *funcname, int size, const QVariant &data) { - QTime timer; + QElapsedTimer timer; int callCount = 0; qint64 transferred = 0; -- cgit v0.12 From fa9b8b6420b0805000435a0b312f47f990dab9a5 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 4 Feb 2011 15:32:35 +0100 Subject: Autotest: simple improvements --- tests/auto/qprocess/tst_qprocess.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/auto/qprocess/tst_qprocess.cpp b/tests/auto/qprocess/tst_qprocess.cpp index 4ee8957..b0f7a9f 100644 --- a/tests/auto/qprocess/tst_qprocess.cpp +++ b/tests/auto/qprocess/tst_qprocess.cpp @@ -249,6 +249,8 @@ void tst_QProcess::constructing() char c; QCOMPARE(process.read(&c, 1), qlonglong(-1)); QCOMPARE(process.write(&c, 1), qlonglong(-1)); + + QProcess proc2; } void tst_QProcess::simpleStart() @@ -265,7 +267,7 @@ void tst_QProcess::simpleStart() process->start("testProcessNormal/testProcessNormal"); if (process->state() != QProcess::Starting) QCOMPARE(process->state(), QProcess::Running); - QVERIFY(process->waitForStarted(5000)); + QVERIFY2(process->waitForStarted(5000), qPrintable(process->errorString())); QCOMPARE(process->state(), QProcess::Running); #if defined(Q_OS_WINCE) // Note: This actually seems incorrect, it will only exit the while loop when finishing fails @@ -277,7 +279,7 @@ void tst_QProcess::simpleStart() while (process->waitForReadyRead(5000)) { } #endif - QCOMPARE(process->state(), QProcess::NotRunning); + QCOMPARE(int(process->state()), int(QProcess::NotRunning)); delete process; process = 0; -- cgit v0.12 From 4f29c5d5381a76f24e13628da3edc5b19c6b1cd2 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 2 Feb 2011 13:23:40 +0100 Subject: Doc: Fix the docs saying what the locale codec is used for --- src/corelib/tools/qstring.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index b96edb9..c1b8740 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -3868,8 +3868,7 @@ const char *QString::latin1_helper() const If \a size is -1 (default), it is taken to be qstrlen(\a str). - QTextCodec::codecForLocale() is used to perform the conversion - from Unicode. + QTextCodec::codecForLocale() is used to perform the conversion. \sa toLocal8Bit(), fromAscii(), fromLatin1(), fromUtf8() */ -- cgit v0.12 From fd2e832657a38d4dba9b86ce190f7736a837d53d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 28 Jan 2011 16:40:51 +0100 Subject: Make qdbus show all types, even those that it doesn't know about --- src/dbus/qdbusmetaobject.cpp | 18 +++++++++++++++++- tools/qdbus/qdbus/qdbus.cpp | 11 +++++++++-- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/dbus/qdbusmetaobject.cpp b/src/dbus/qdbusmetaobject.cpp index 5fe0589..6683505 100644 --- a/src/dbus/qdbusmetaobject.cpp +++ b/src/dbus/qdbusmetaobject.cpp @@ -169,6 +169,8 @@ QDBusMetaObjectGenerator::QDBusMetaObjectGenerator(const QString &interfaceName, } } +Q_DBUS_EXPORT bool qt_dbus_metaobject_skip_annotations = false; + QDBusMetaObjectGenerator::Type QDBusMetaObjectGenerator::findType(const QByteArray &signature, const QDBusIntrospection::Annotations &annotations, @@ -178,7 +180,7 @@ QDBusMetaObjectGenerator::findType(const QByteArray &signature, result.id = QVariant::Invalid; int type = QDBusMetaType::signatureToType(signature); - if (type == QVariant::Invalid) { + if (type == QVariant::Invalid && !qt_dbus_metaobject_skip_annotations) { // it's not a type normally handled by our meta type system // it must contain an annotation QString annotationName = QString::fromLatin1("com.trolltech.QtDBus.QtTypeName"); @@ -201,6 +203,20 @@ QDBusMetaObjectGenerator::findType(const QByteArray &signature, return result; // unknown type is invalid too result.name = typeName; + } else if (type == QVariant::Invalid) { + // this case is used only by the qdbus command-line tool + // invalid, let's create an impossible type that contains the signature + + if (signature == "av") { + result.name = "QVariantList"; + type = QVariant::List; + } else if (signature == "a{sv}") { + result.name = "QVariantMap"; + type = QVariant::Map; + } else { + result.name = "QDBusRawType::" + signature; + type = -1; + } } else { result.name = QVariant::typeToName( QVariant::Type(type) ); } diff --git a/tools/qdbus/qdbus/qdbus.cpp b/tools/qdbus/qdbus/qdbus.cpp index 6ec8224..4e5cf9a 100644 --- a/tools/qdbus/qdbus/qdbus.cpp +++ b/tools/qdbus/qdbus/qdbus.cpp @@ -50,6 +50,8 @@ #include #include +Q_DBUS_EXPORT extern bool qt_dbus_metaobject_skip_annotations; + static QDBusConnection connection(QLatin1String("")); static bool printArgumentsLiterally = false; @@ -99,7 +101,7 @@ static void printArg(const QVariant &v) else if (arg.currentSignature() == QLatin1String("a{sv}")) printArg(qdbus_cast(arg)); else - printf("qdbus: I don't know how to display an argument of type '%s'\n", + printf("qdbus: I don't know how to display an argument of type '%s', run with --literal.\n", qPrintable(arg.currentSignature())); } else { printf("%s\n", qPrintable(v.toString())); @@ -311,7 +313,11 @@ static int placeCall(const QString &service, const QString &path, const QString int id = QVariant::nameToType(types.at(i)); if (id == QVariant::UserType) id = QMetaType::type(types.at(i)); - Q_ASSERT(id); + if (!id) { + fprintf(stderr, "Cannot call method '%s' because type '%s' is unknown to this tool\n", + qPrintable(member), types.at(i).constData()); + return 1; + } QVariant p; QString argument; @@ -435,6 +441,7 @@ static void printAllServices(QDBusConnectionInterface *bus) int main(int argc, char **argv) { + qt_dbus_metaobject_skip_annotations = true; QCoreApplication app(argc, argv); QStringList args = app.arguments(); args.takeFirst(); -- cgit v0.12 From 2b72330127cf045d324bc20dfbc9fac2d12c6cdb Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 28 Jan 2011 16:43:56 +0100 Subject: QtDBus: do not wait for reply for AddMatch and RemoveMatch We can't recover from these functions failing anyway, so don't ask for an error condition. The D-Bus library will set the no-reply flag under these conditions. Reviewed-by: Will Thompson --- src/dbus/qdbusintegrator.cpp | 38 ++++++++++++++------------------------ 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 2e7b052..bc03896 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -2074,30 +2074,20 @@ void QDBusConnectionPrivate::connectSignal(const QString &key, const SignalHook if (connection) { qDBusDebug("Adding rule: %s", hook.matchRule.constData()); - QDBusErrorInternal error; - q_dbus_bus_add_match(connection, hook.matchRule, error); - if (!!error) { - QDBusError qerror = error; - qWarning("QDBusConnectionPrivate::connectSignal: received error from D-Bus server " - "while connecting signal to %s::%s: %s (%s)", - hook.obj->metaObject()->className(), - hook.obj->metaObject()->method(hook.midx).signature(), - qPrintable(qerror.name()), qPrintable(qerror.message())); - Q_ASSERT(false); - } else { - // Successfully connected the signal - // Do we need to watch for this name? - if (shouldWatchService(hook.service)) { - WatchedServicesHash::mapped_type &data = watchedServices[hook.service]; - if (++data.refcount == 1) { - // we need to watch for this service changing - connectSignal(dbusServiceString(), QString(), dbusInterfaceString(), - QLatin1String("NameOwnerChanged"), QStringList() << hook.service, QString(), - this, SLOT(serviceOwnerChangedNoLock(QString,QString,QString))); - data.owner = getNameOwnerNoCache(hook.service); - qDBusDebug() << this << "Watching service" << hook.service << "for owner changes (current owner:" - << data.owner << ")"; - } + q_dbus_bus_add_match(connection, hook.matchRule, NULL); + + // Successfully connected the signal + // Do we need to watch for this name? + if (shouldWatchService(hook.service)) { + WatchedServicesHash::mapped_type &data = watchedServices[hook.service]; + if (++data.refcount == 1) { + // we need to watch for this service changing + connectSignal(dbusServiceString(), QString(), dbusInterfaceString(), + QLatin1String("NameOwnerChanged"), QStringList() << hook.service, QString(), + this, SLOT(serviceOwnerChangedNoLock(QString,QString,QString))); + data.owner = getNameOwnerNoCache(hook.service); + qDBusDebug() << this << "Watching service" << hook.service << "for owner changes (current owner:" + << data.owner << ")"; } } } -- cgit v0.12 From 4cc2c1d87a90279cd024768c905da013f037cea1 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Mon, 7 Feb 2011 17:56:43 +0100 Subject: Revert "Improved performance of mapFromGlobal/mapToGlobal on X11" This change introduced regressions with some window managers (for example with metacity when you maximize the window) This reverts commit cdd776a91e65bf5c30cea1bab9823134a3f797d0. --- src/gui/kernel/qwidget_x11.cpp | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp index 28eb3f0..b0375ef 100644 --- a/src/gui/kernel/qwidget_x11.cpp +++ b/src/gui/kernel/qwidget_x11.cpp @@ -1318,40 +1318,12 @@ QPoint QWidgetPrivate::mapFromGlobal(const QPoint &pos) const QPoint QWidget::mapToGlobal(const QPoint &pos) const { Q_D(const QWidget); - QPoint offset = data->crect.topLeft(); - const QWidget *w = this; - const QWidget *p = w->parentWidget(); - while (!w->isWindow() && p) { - w = p; - p = p->parentWidget(); - offset += w->data->crect.topLeft(); - } - - const QWidgetPrivate *wd = w->d_func(); - QTLWExtra *tlw = wd->topData(); - if (!tlw->embedded) - return pos + offset; - return d->mapToGlobal(pos); } QPoint QWidget::mapFromGlobal(const QPoint &pos) const { Q_D(const QWidget); - QPoint offset = data->crect.topLeft(); - const QWidget *w = this; - const QWidget *p = w->parentWidget(); - while (!w->isWindow() && p) { - w = p; - p = p->parentWidget(); - offset += w->data->crect.topLeft(); - } - - const QWidgetPrivate *wd = w->d_func(); - QTLWExtra *tlw = wd->topData(); - if (!tlw->embedded) - return pos - offset; - return d->mapFromGlobal(pos); } -- cgit v0.12 From 640436345645b6cf6ff3334399f33c9d1c089492 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Mon, 7 Feb 2011 14:53:59 +0100 Subject: Don't crash when creating backtrace for built-in JS function (2nd try) Commit 147df10403ba280b3f04c1e3d6c4b1cf386abe5d did not quite fix the issue; other places need the same checks. When the JIT is enabled, frames for built-in JS host calls (such as Array.prototype.forEach) are not fully initialized. In particular, the CodeBlock register of such frames is not set (see comment in JITCall.cpp). We need to check if the codeBlock is actually valid before we start using it. This fixes the crash(es) but not the problem of actually getting the arguments for such frames through the API. There's also a related problem when a QtScript function (newFunction()) is called as a callback of a built-in JS host function (QTBUG-17287). These problems will go away once JavaScriptCore is updated to a more recent version (4.8 at the earliest), since the native-vs-script frame handling has been unified. Task-number: QTBUG-17137 Reviewed-by: Olivier Goffart --- src/script/api/qscriptcontext.cpp | 9 ++++++- src/script/api/qscriptcontextinfo.cpp | 4 +-- src/script/api/qscriptengine.cpp | 3 ++- src/script/api/qscriptengine_p.h | 18 ++++++++++++++ tests/auto/qscriptcontext/tst_qscriptcontext.cpp | 31 +++++++++++++++++++++++- tests/auto/qscriptengine/tst_qscriptengine.cpp | 16 ++++++++++++ 6 files changed, 76 insertions(+), 5 deletions(-) diff --git a/src/script/api/qscriptcontext.cpp b/src/script/api/qscriptcontext.cpp index 59ea52d..2468a46 100644 --- a/src/script/api/qscriptcontext.cpp +++ b/src/script/api/qscriptcontext.cpp @@ -299,6 +299,12 @@ QScriptValue QScriptContext::argumentsObject() const //for a js function if (frame->codeBlock() && frame->callee()) { + if (!QScriptEnginePrivate::hasValidCodeBlockRegister(frame)) { + // We have a built-in JS host call. + // codeBlock is needed by retrieveArguments(), but since it + // contains junk, we would crash. Return an invalid value for now. + return QScriptValue(); + } JSC::JSValue result = frame->interpreter()->retrieveArguments(frame, JSC::asFunction(frame->callee())); return QScript::scriptEngineFromExec(frame)->scriptValueFromJSCValue(result); } @@ -309,7 +315,8 @@ QScriptValue QScriptContext::argumentsObject() const } //for a native function - if (!frame->optionalCalleeArguments()) { + if (!frame->optionalCalleeArguments() + && QScriptEnginePrivate::hasValidCodeBlockRegister(frame)) { // Make sure we don't go here for host JSFunctions Q_ASSERT(frame->argumentCount() > 0); //we need at least 'this' otherwise we'll crash later JSC::Arguments* arguments = new (&frame->globalData())JSC::Arguments(frame, JSC::Arguments::NoParameters); frame->setCalleeArguments(arguments); diff --git a/src/script/api/qscriptcontextinfo.cpp b/src/script/api/qscriptcontextinfo.cpp index d39abe6..0f9de1d 100644 --- a/src/script/api/qscriptcontextinfo.cpp +++ b/src/script/api/qscriptcontextinfo.cpp @@ -157,7 +157,7 @@ QScriptContextInfoPrivate::QScriptContextInfoPrivate(const QScriptContext *conte JSC::Instruction *returnPC = rewindContext->returnPC(); JSC::CodeBlock *codeBlock = frame->codeBlock(); - if (returnPC && codeBlock) { + if (returnPC && codeBlock && QScriptEnginePrivate::hasValidCodeBlockRegister(frame)) { #if ENABLE(JIT) unsigned bytecodeOffset = codeBlock->getBytecodeIndex(frame, JSC::ReturnAddressPtr(returnPC)); #else @@ -171,7 +171,7 @@ QScriptContextInfoPrivate::QScriptContextInfoPrivate(const QScriptContext *conte // Get the filename and the scriptId: JSC::CodeBlock *codeBlock = frame->codeBlock(); - if (codeBlock) { + if (codeBlock && QScriptEnginePrivate::hasValidCodeBlockRegister(frame)) { JSC::SourceProvider *source = codeBlock->source(); scriptId = source->asID(); fileName = source->url(); diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index 54039c0..478fdaa 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -858,7 +858,8 @@ JSC::JSValue JSC_HOST_CALL functionQsTr(JSC::ExecState *exec, JSC::JSObject*, JS { JSC::ExecState *frame = exec->callerFrame()->removeHostCallFrameFlag(); while (frame) { - if (frame->codeBlock() && frame->codeBlock()->source() + if (frame->codeBlock() && QScriptEnginePrivate::hasValidCodeBlockRegister(frame) + && frame->codeBlock()->source() && !frame->codeBlock()->source()->url().isEmpty()) { context = engine->translationContextFromUrl(frame->codeBlock()->source()->url()); break; diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h index f8144e9..94d195e 100644 --- a/src/script/api/qscriptengine_p.h +++ b/src/script/api/qscriptengine_p.h @@ -56,6 +56,7 @@ #include "Debugger.h" #include "ErrorInstance.h" #include "JSArray.h" +#include "Executable.h" #include "Lexer.h" #include "RefPtr.h" #include "RegExpConstructor.h" @@ -231,6 +232,8 @@ public: static inline JSC::ExecState *frameForContext(QScriptContext *context); static inline const JSC::ExecState *frameForContext(const QScriptContext *context); + static inline bool hasValidCodeBlockRegister(JSC::ExecState *frame); + JSC::JSGlobalObject *originalGlobalObject() const; JSC::JSObject *getOriginalGlobalObjectProxy(); JSC::JSObject *customGlobalObject() const; @@ -862,6 +865,21 @@ inline const JSC::ExecState *QScriptEnginePrivate::frameForContext(const QScript return reinterpret_cast(context); } +inline bool QScriptEnginePrivate::hasValidCodeBlockRegister(JSC::ExecState *frame) +{ +#if ENABLE(JIT) + // Frames created by the VM don't have their CodeBlock register + // initialized. We can detect such frames by checking if the + // callee is a host JSFunction. + JSC::JSObject *callee = frame->callee(); + return !(callee && callee->inherits(&JSC::JSFunction::info) + && JSC::asFunction(callee)->isHostFunction()); +#else + Q_UNUSED(frame); + return true; +#endif +} + inline JSC::ExecState *QScriptEnginePrivate::globalExec() const { return originalGlobalObject()->globalExec(); diff --git a/tests/auto/qscriptcontext/tst_qscriptcontext.cpp b/tests/auto/qscriptcontext/tst_qscriptcontext.cpp index dd21555..7915eb0 100644 --- a/tests/auto/qscriptcontext/tst_qscriptcontext.cpp +++ b/tests/auto/qscriptcontext/tst_qscriptcontext.cpp @@ -871,7 +871,36 @@ void tst_QScriptContext::backtrace_data() QStringList expected; expected << "() at -1" << "(0, 0, 0) at testfile:3" - << "forEach(0) at -1" + << QString::fromLatin1("forEach(%0) at -1") + // Because the JIT doesn't store the arguments in the frame + // for built-in functions, arguments are not available. + // Will work when the copy of JavaScriptCore is updated + // (QTBUG-16568). + .arg(qt_script_isJITEnabled() + ? "" + : "function () {\n result = bt();\n}") + << "() at testfile:4"; + QTest::newRow("js callback from built-in") << source << expected; + } + + { + QString source = QString::fromLatin1( + "[10,20].forEach(\n" + " function() {\n" + " result = bt();\n" + "}); result"); + + QStringList expected; + expected << "() at -1" + << "(20, 1, 10,20) at testfile:3" + << QString::fromLatin1("forEach(%0) at -1") + // Because the JIT doesn't store the arguments in the frame + // for built-in functions, arguments are not available. + // Will work when the copy of JavaScriptCore is updated + // (QTBUG-16568). + .arg(qt_script_isJITEnabled() + ? "" + : "function () {\n result = bt();\n}") << "() at testfile:4"; QTest::newRow("js callback from built-in") << source << expected; } diff --git a/tests/auto/qscriptengine/tst_qscriptengine.cpp b/tests/auto/qscriptengine/tst_qscriptengine.cpp index c3a0ba1..8de6fbc 100644 --- a/tests/auto/qscriptengine/tst_qscriptengine.cpp +++ b/tests/auto/qscriptengine/tst_qscriptengine.cpp @@ -164,6 +164,7 @@ private slots: void translationContext_data(); void translationContext(); void translateScriptIdBased(); + void translateFromBuiltinCallback(); void functionScopes(); void nativeFunctionScopes(); void evaluateProgram(); @@ -4725,6 +4726,21 @@ void tst_QScriptEngine::translateScriptIdBased() QString::fromLatin1("qtn_foo_bar")); // Doesn't have plural } +void tst_QScriptEngine::translateFromBuiltinCallback() +{ + QScriptEngine eng; + eng.installTranslatorFunctions(); + + // Callback has no translation context. + eng.evaluate("function foo() { qsTr('foo'); }"); + + // Stack at translation time will be: + // qsTr, foo, forEach, global + // qsTr() needs to walk to the outer-most (global) frame before it finds + // a translation context, and this should not crash. + eng.evaluate("[10,20].forEach(foo)", "script.js"); +} + void tst_QScriptEngine::functionScopes() { QScriptEngine eng; -- cgit v0.12 From c718d992865de7015df0173c816b257d72e13f24 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 8 Feb 2011 11:08:37 +0100 Subject: Fix compilation error: symbol is namespaced. Reviewed-by: Rohan McGovern --- tools/qdbus/qdbus/qdbus.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/qdbus/qdbus/qdbus.cpp b/tools/qdbus/qdbus/qdbus.cpp index 4e5cf9a..d8433fc 100644 --- a/tools/qdbus/qdbus/qdbus.cpp +++ b/tools/qdbus/qdbus/qdbus.cpp @@ -50,7 +50,9 @@ #include #include +QT_BEGIN_NAMESPACE Q_DBUS_EXPORT extern bool qt_dbus_metaobject_skip_annotations; +QT_END_NAMESPACE static QDBusConnection connection(QLatin1String("")); static bool printArgumentsLiterally = false; -- cgit v0.12 From 8d6ad569495d389b111ab8879117cc7832287fa8 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 6 Feb 2011 18:51:34 +0100 Subject: Make sure we use at least 1024 bytes when calling getpwuid_r. On some systems, sysconf may return -1 to indicate that there's no such limit (limitless), so don't create a buffer of size -1. Reviewed-by: Bradley T. Hughes --- src/gui/kernel/qapplication_x11.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp index f28868c..8fef6fb 100644 --- a/src/gui/kernel/qapplication_x11.cpp +++ b/src/gui/kernel/qapplication_x11.cpp @@ -5657,7 +5657,7 @@ static void sm_performSaveYourself(QSessionManagerPrivate* smd) // tell the session manager about our user as well. struct passwd *entryPtr = 0; #if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) - QVarLengthArray buf(sysconf(_SC_GETPW_R_SIZE_MAX)); + QVarLengthArray buf(qMax(sysconf(_SC_GETPW_R_SIZE_MAX), 1024L)); struct passwd entry; getpwuid_r(geteuid(), &entry, buf.data(), buf.size(), &entryPtr); #else -- cgit v0.12 From 609bcb4f9ab3f8fecd037e9c401891ca4d6f2172 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 6 Feb 2011 18:58:00 +0100 Subject: Use an increasing size for the getpwuid_r buffer. Reviewed-by: Bradley T. Hughes --- src/gui/kernel/qapplication_x11.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp index 8fef6fb..4cdb82f 100644 --- a/src/gui/kernel/qapplication_x11.cpp +++ b/src/gui/kernel/qapplication_x11.cpp @@ -5659,7 +5659,18 @@ static void sm_performSaveYourself(QSessionManagerPrivate* smd) #if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) QVarLengthArray buf(qMax(sysconf(_SC_GETPW_R_SIZE_MAX), 1024L)); struct passwd entry; - getpwuid_r(geteuid(), &entry, buf.data(), buf.size(), &entryPtr); + while (getpwuid_r(geteuid(), &entry, buf.data(), buf.size(), &entryPtr) == ERANGE) { + if (buf.size() >= 32768) { + // too big already, fail + static char badusername[] = ""; + entryPtr = &entry; + entry.pw_name = badusername; + break; + } + + // retry with a bigger buffer + buf.resize(buf.size() * 2); + } #else entryPtr = getpwuid(geteuid()); #endif -- cgit v0.12 From 6b6b13130a95b896202ad09fa349e3f69c2807de Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 6 Feb 2011 19:43:50 +0100 Subject: Check that _POSIX_THREAD_SAFE_FUNCTIONS is larger than zero. POSIX allows this symbol to be defined to -1 to indicate that the interfaces aren't present. On FreeBSD 8, it's defined to -1, but the functions are present (supposedly, they don't work -- just stubs). Guessing that OpenBSD is the same. Also removing the QT_NO_THREAD, since Qt can't be built without threading support. It's only used by our bootstrapped tools, which in turn use QCoreApplication only (no QApplication). Reviewed-By: Bradley T. Hughes --- src/gui/kernel/qapplication_x11.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp index 4cdb82f..e0447cc 100644 --- a/src/gui/kernel/qapplication_x11.cpp +++ b/src/gui/kernel/qapplication_x11.cpp @@ -5656,7 +5656,7 @@ static void sm_performSaveYourself(QSessionManagerPrivate* smd) sm_setProperty(QString::fromLatin1(SmProgram), argument0); // tell the session manager about our user as well. struct passwd *entryPtr = 0; -#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) +#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && (_POSIX_THREAD_SAFE_FUNCTIONS - 0 > 0) QVarLengthArray buf(qMax(sysconf(_SC_GETPW_R_SIZE_MAX), 1024L)); struct passwd entry; while (getpwuid_r(geteuid(), &entry, buf.data(), buf.size(), &entryPtr) == ERANGE) { -- cgit v0.12 From e5fbadc54b8e25c94c50f0d0a49bc1a44674dac7 Mon Sep 17 00:00:00 2001 From: Jocelyn Turcotte Date: Thu, 3 Feb 2011 21:10:59 +0100 Subject: Use the thread-default glib context for the DBus connection in the ICD bearer manager. This allows the bearer management plugin to be ran on a thread different than the main one. Task-number: QTBUG-17199 Reviewed-by: Kranthi --- src/plugins/bearer/icd/dbusdispatcher.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/bearer/icd/dbusdispatcher.cpp b/src/plugins/bearer/icd/dbusdispatcher.cpp index 5fc2a38..f100a48 100644 --- a/src/plugins/bearer/icd/dbusdispatcher.cpp +++ b/src/plugins/bearer/icd/dbusdispatcher.cpp @@ -468,7 +468,7 @@ void DBusDispatcher::setupDBus() d_ptr->signal_vtable.message_function = signalHandler; dbus_connection_set_exit_on_disconnect(d_ptr->connection, FALSE); - dbus_connection_setup_with_g_main(d_ptr->connection, NULL); + dbus_connection_setup_with_g_main(d_ptr->connection, g_main_context_get_thread_default()); dbus_connection_register_object_path(d_ptr->connection, d_ptr->signalPath.toLatin1(), &d_ptr->signal_vtable, -- cgit v0.12 From 97c07046f9031f19005e7f57fc0dee09437f378b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 8 Feb 2011 16:21:47 +0100 Subject: Fix the compilation error that the previous fix didn't fix --- tools/qdbus/qdbus/qdbus.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/qdbus/qdbus/qdbus.cpp b/tools/qdbus/qdbus/qdbus.cpp index d8433fc..8e1c384 100644 --- a/tools/qdbus/qdbus/qdbus.cpp +++ b/tools/qdbus/qdbus/qdbus.cpp @@ -443,7 +443,7 @@ static void printAllServices(QDBusConnectionInterface *bus) int main(int argc, char **argv) { - qt_dbus_metaobject_skip_annotations = true; + QT_PREPEND_NAMESPACE(qt_dbus_metaobject_skip_annotations) = true; QCoreApplication app(argc, argv); QStringList args = app.arguments(); args.takeFirst(); -- cgit v0.12 From a6ccb1a72173cec6381d519a720dc08cfdc03720 Mon Sep 17 00:00:00 2001 From: David Faure Date: Tue, 8 Feb 2011 16:33:42 +0100 Subject: Fix compilation of QMutableSetIterator::value() with QT_STRICT_ITERATORS Merge-request: 1078 Reviewed-by: Thiago Macieira --- src/corelib/tools/qset.h | 2 +- tests/auto/qset/tst_qset.cpp | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/corelib/tools/qset.h b/src/corelib/tools/qset.h index 8075fbd..1074f99 100644 --- a/src/corelib/tools/qset.h +++ b/src/corelib/tools/qset.h @@ -330,7 +330,7 @@ class QMutableSetIterator typedef typename QSet::iterator iterator; QSet *c; iterator i, n; - inline bool item_exists() const { return n != c->constEnd(); } + inline bool item_exists() const { return c->constEnd() != n; } public: inline QMutableSetIterator(QSet &container) diff --git a/tests/auto/qset/tst_qset.cpp b/tests/auto/qset/tst_qset.cpp index 204ca55..164bf1e 100644 --- a/tests/auto/qset/tst_qset.cpp +++ b/tests/auto/qset/tst_qset.cpp @@ -39,6 +39,7 @@ ** ****************************************************************************/ +//#define QT_STRICT_ITERATORS #include #include @@ -815,6 +816,16 @@ void tst_QSet::javaMutableIterator() int sum = 0; QMutableSetIterator i(set1); while (i.hasNext()) { + i.next(); + sum += toNumber(i.value()); + } + QVERIFY(sum == 24999 * 25000 / 2); + } + + { + int sum = 0; + QMutableSetIterator i(set1); + while (i.hasNext()) { sum += toNumber(i.peekNext()); i.next(); } -- cgit v0.12