summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMorten Sorvig <msorvig@trolltech.com>2009-08-26 08:33:50 +0200
committerMorten Sorvig <msorvig@trolltech.com>2009-08-26 08:33:50 +0200
commitf11d84640d73a11bac412995971b7f5718235fb4 (patch)
tree847f439bba757a4d1665915ff62e0f7edaf230a3
parentad4f2f7a9c7049aa07bb4e150ca391059a0b0af7 (diff)
Only cast valid ids to QWidget pointers. Implement z-ordering on drag
-rwxr-xr-xdemos/mdiarea/main.cpp2
-rw-r--r--src/eventhandler.js15
-rw-r--r--src/sessionserver.cpp2
-rw-r--r--src/widgeteventhandler.cpp58
-rw-r--r--src/widgeteventhandler.h7
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<QLabel *>(widget)) {
- events.addEvent((int)widget, EventEntry::TextUpdate);
+ events.addEvent(idForWidget(widget), EventEntry::TextUpdate);
return true;
} else if (QTextEdit *textEdit = qobject_cast<QTextEdit *>(widget)) {
- events.addEvent((int)widget, EventEntry::TextUpdate);
+ events.addEvent(idForWidget(widget), EventEntry::TextUpdate);
return true;
} else if (QPushButton *textEdit = qobject_cast<QPushButton *>(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<quintptr>(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<QWidget *>(id);
+ return 0;
+}
+
+void WidgetEventHandler::widgetDeleted()
+{
+ liveWidgets.remove(reinterpret_cast<quintptr>(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<QWidget *>(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<quintptr> 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<QWidget *, QRect> pendingUpdates;