From f11d84640d73a11bac412995971b7f5718235fb4 Mon Sep 17 00:00:00 2001 From: Morten Sorvig Date: Wed, 26 Aug 2009 08:33:50 +0200 Subject: Only cast valid ids to QWidget pointers. Implement z-ordering on drag --- demos/mdiarea/main.cpp | 2 +- src/eventhandler.js | 15 ++++++++---- src/sessionserver.cpp | 2 +- src/widgeteventhandler.cpp | 58 +++++++++++++++++++++++++++++++++++----------- src/widgeteventhandler.h | 7 ++++++ 5 files changed, 64 insertions(+), 20 deletions(-) diff --git a/demos/mdiarea/main.cpp b/demos/mdiarea/main.cpp index 949d16c..0e30da0 100755 --- a/demos/mdiarea/main.cpp +++ b/demos/mdiarea/main.cpp @@ -31,7 +31,7 @@ int main(int argc, char **argv) // area->addSubWindow(new QWidget); WebClient server; server.setRootWidget(area); - area->show(); + // area->show(); return app.exec(); } diff --git a/src/eventhandler.js b/src/eventhandler.js index 49ab031..bd3d5fe 100644 --- a/src/eventhandler.js +++ b/src/eventhandler.js @@ -139,9 +139,9 @@ function createElement(widgetType, id) element = this.createWidgetElement(id); } - element.zIndex = 1; + element.style.zIndex = 1; var structureElement = this.createStructureElement(); - structureElement.zIndex = 0; + structureElement.style.zIndex = 0; element["structureElement"] = structureElement; structureElement.appendChild(element); return element; @@ -271,7 +271,7 @@ function eventHandler(text) if (!element) element = this.createElement(widgetType, widget); - + // alert("key" + key + "type" + type); if (type == "update") { // alert("update" + widget); @@ -310,7 +310,7 @@ function eventHandler(text) this.setTopLevel(element.structureElement, parentPointer == 0); if (parent && parent.structureElement && element.structureElement) { parent.structureElement.appendChild(element.structureElement); - element.structureElement.zIndex = 2; + element.structureElement.style.zIndex = 2; } } else if (type == "textUpdate") { updateText(element, event.text); @@ -414,6 +414,11 @@ var webclientObjectCounter = 0; if (isNaN(parseInt(element.style.left))) { element.style.left = '0px'; } if (isNaN(parseInt(element.style.top))) { element.style.top = '0px'; } + console.log(element.parentNode); + + ++this.globalZIndex; + element.style.zIndex = this.globalZIndex; // Special case adapted to the QMdiArea hiearchy. + var x = parseInt(element.style.left); var y = parseInt(element.style.top); @@ -496,7 +501,7 @@ function setUpWebClientObject(webclientObject) webclientObject.dragBegin = dragBegin; webclientObject.drag = drag; webclientObject.dragEnd = dragEnd; - + webclientObject.globalZIndex = 1; // console.log(webclientObject); // console.log(webclientObject.baseUrl); } diff --git a/src/sessionserver.cpp b/src/sessionserver.cpp index 922638b..9efe3c5 100644 --- a/src/sessionserver.cpp +++ b/src/sessionserver.cpp @@ -17,7 +17,7 @@ SessionServer::SessionServer(QWidget *widget, Session *session, Server *server) widget->setParent(fakeRoot); widget->move(0, 0); - widgetEventHandler = new WidgetEventHandler(rootWidget, server); + widgetEventHandler = new WidgetEventHandler(widget, server); rootWidget->setAttribute(Qt::WA_DontShowOnScreen); diff --git a/src/widgeteventhandler.cpp b/src/widgeteventhandler.cpp index e610a41..bdcd20c 100644 --- a/src/widgeteventhandler.cpp +++ b/src/widgeteventhandler.cpp @@ -116,13 +116,13 @@ bool WidgetEventHandler::eventFilter(QObject *object, QEvent *event) } if (QLabel *label = qobject_cast(widget)) { - events.addEvent((int)widget, EventEntry::TextUpdate); + events.addEvent(idForWidget(widget), EventEntry::TextUpdate); return true; } else if (QTextEdit *textEdit = qobject_cast(widget)) { - events.addEvent((int)widget, EventEntry::TextUpdate); + events.addEvent(idForWidget(widget), EventEntry::TextUpdate); return true; } else if (QPushButton *textEdit = qobject_cast(widget)) { - events.addEvent((int)widget, EventEntry::TextUpdate); + events.addEvent(idForWidget(widget), EventEntry::TextUpdate); return true; } else if (!grabbing) { @@ -134,7 +134,7 @@ bool WidgetEventHandler::eventFilter(QObject *object, QEvent *event) if (event->type() == QEvent::Show) { DEBUG << "show" << object; // Add immediate show update if we have an image to serve. - if (events.images.contains((int)widget)) { + if (events.images.contains(idForWidget(widget))) { addShowEvent(widget); } @@ -146,7 +146,7 @@ bool WidgetEventHandler::eventFilter(QObject *object, QEvent *event) if (event->type() == QEvent::Hide) { DEBUG << "hide" << object; - events.addEvent((int)widget, EventEntry::Hide); + events.addEvent(idForWidget(widget), EventEntry::Hide); recursivelyAddHide(widget); } @@ -154,19 +154,19 @@ bool WidgetEventHandler::eventFilter(QObject *object, QEvent *event) QRect geometry = globalGeometry(widget); DEBUG << "move geometry" << object->metaObject()->className() << geometry; if (disableUpdates.contains(sender()) == false) - events.addGeometryEvent((int)widget, geometry); + events.addGeometryEvent(idForWidget(widget), geometry); } if (event->type() == QEvent::Resize) { QRect geometry = globalGeometry(widget); DEBUG << "resize geometry" << geometry; - events.addGeometryEvent((int)widget, geometry); + events.addGeometryEvent(idForWidget(widget), geometry); } if (event->type() == QEvent::ParentChange) { DEBUG << "parentChange" << "parent"<< widget->parentWidget() << "child" << widget; - events.addParentChangeEvent((int)widget); + events.addParentChangeEvent(idForWidget(widget)); } return false; @@ -208,6 +208,32 @@ void WidgetEventHandler::handleRequest(HttpRequest *request, HttpResponse *respo } } +// Keep track of the current live widgets, to avoid dereferencing +// stale widget pointers when clients sends updated for a certain +// widget id. This also protects against malicious clients that +// sends fake ids. +quintptr WidgetEventHandler::idForWidget(QWidget *widget) +{ + quintptr id = reinterpret_cast(widget); + if (liveWidgets.contains(id) == false) { + liveWidgets.insert(id); + connect(widget, SIGNAL(destroyed()), SLOT(widgetDeleted())); + } + return id; +} + +QWidget *WidgetEventHandler::widgetForId(quintptr id) +{ + if (liveWidgets.contains(id)) + return reinterpret_cast(id); + return 0; +} + +void WidgetEventHandler::widgetDeleted() +{ + liveWidgets.remove(reinterpret_cast(sender())); +} + bool WidgetEventHandler::handleJsonMessage(const QByteArray &message) { QByteArray jsonText = QUrl::fromPercentEncoding(message.mid(5)).toUtf8(); // remove "/json", decode. @@ -238,11 +264,12 @@ void WidgetEventHandler::handleMousePress(const QByteArray &message) QPoint p(tokens.at(1).toInt(), tokens.at(2).toInt()); // ### assumes well-formed string QWidget *target = findEventTarget(rootWidget, p); -// DEBUG << "target" << target; + qDebug() << "target" << target << target->metaObject()->className(); QPoint local = target->mapFrom(rootWidget, p); if (message.startsWith("/mousepress")) { + qDebug() << "press" << local; QMouseEvent press(QEvent::MouseButtonPress, local , Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); QApplication::sendEvent(target, &press); } else if (message.startsWith("/mouserelease")) { @@ -288,7 +315,9 @@ void WidgetEventHandler::handleTextUpdate(json_object* request) json_object* tmp = json_object_object_get(request, "text"); QByteArray text = json_object_get_string(tmp); - QWidget *widget = reinterpret_cast(id); + QWidget *widget = widgetForId(id); + if (!widget) + return; disableUpdates.insert(widget); if (text == "\n") { @@ -306,7 +335,10 @@ void WidgetEventHandler::handlePositionUpdate(json_object *request) const int x = json_object_get_int(json_object_object_get(request, "x")); const int y = json_object_get_int(json_object_object_get(request, "y")); - QWidget *widget = ((QWidget *)(id)); + QWidget *widget = widgetForId(id); + if (!widget) + return; + disableUpdates.insert(widget); widget->move(x, y); disableUpdates.remove(widget); @@ -332,10 +364,10 @@ void WidgetEventHandler::widgetPaint(QWidget *widget, const QRect &updateRect) // DEBUG << "update" << widget << (int)widget; - events.addUpdateEvent((int)widget, image, updateRect); + events.addUpdateEvent(idForWidget(widget), image, updateRect); // DEBUG << "geometry" << widget << (int)widget << globalGeometry(widget); - events.addGeometryEvent((int)widget, globalGeometry(widget)); + events.addGeometryEvent(idForWidget(widget), globalGeometry(widget)); } QRect WidgetEventHandler::globalGeometry(QWidget *widget) diff --git a/src/widgeteventhandler.h b/src/widgeteventhandler.h index 2df5e8c..3327541 100644 --- a/src/widgeteventhandler.h +++ b/src/widgeteventhandler.h @@ -21,8 +21,13 @@ public: protected slots: void updatePendingWidgets(); void textChange(); + void widgetDeleted(); protected: + quintptr idForWidget(QWidget *widget); + QWidget *widgetForId(quintptr id); + QSet liveWidgets; + bool handleJsonMessage(const QByteArray &message); void handleMousePress(const QByteArray &message); void handleKeyPress(const QByteArray &message); @@ -35,6 +40,8 @@ protected: void recursivelyAddHide(QWidget *root); void addShowEvent(QWidget *widget); + + public: //private: EventQueue events; QHash pendingUpdates; -- cgit v1.2.3