diff options
author | Paul Pazderski | 2019-08-11 20:03:22 +0000 |
---|---|---|
committer | Paul Pazderski | 2019-08-14 16:10:29 +0000 |
commit | fb29bcbf1cf8004cbc97a1d4db4621c00a0fe7cf (patch) | |
tree | ebe27dfc05de68fd47e405f7f547f0982a971ca2 | |
parent | 38b275f345755c035b4f13d23a5116c23494a311 (diff) | |
download | eclipse.platform.swt-fb29bcbf1cf8004cbc97a1d4db4621c00a0fe7cf.tar.gz eclipse.platform.swt-fb29bcbf1cf8004cbc97a1d4db4621c00a0fe7cf.tar.xz eclipse.platform.swt-fb29bcbf1cf8004cbc97a1d4db4621c00a0fe7cf.zip |
Bug 549643 - [Win32][DND] dragSetData occurs after dragEnd
For DropTarget this change fix the flaw that an implementation must
release the IDataObject when drop occurs (like the target must do in
DropLeave).
For DragSource it create a new IDataObject for each drag&drop operation.
That way a faulty or malicious drop target cannot query data (produce
DND.DragSetData events) after drag&drop operation finished.
Change-Id: I1679f5d3726bb318ec037bb1715fc4091129c730
Signed-off-by: Paul Pazderski <paul-eclipse@ppazderski.de>
2 files changed, 81 insertions, 69 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/DragSource.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/DragSource.java index 8d509da04a..c4c4e09894 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/DragSource.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/DragSource.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2017 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -161,8 +161,6 @@ public DragSource(Control control, int style) { DND.error(DND.ERROR_CANNOT_INIT_DRAG); } control.setData(DND.DRAG_SOURCE_KEY, this); - createCOMInterfaces(); - this.AddRef(); controlListener = event -> { if (event.type == SWT.Dispose) { @@ -241,6 +239,7 @@ private int AddRef() { } private void createCOMInterfaces() { + disposeCOMInterfaces(); // register each of the interfaces that this object implements iDropSource = new COMObject(new int[]{2, 0, 0, 2, 1}){ @Override @@ -276,6 +275,7 @@ private void createCOMInterfaces() { // method10 DUnadvise - not implemented // method11 EnumDAdvise - not implemented }; + refCount = 1; } @Override @@ -307,6 +307,7 @@ private void drag(Event dragEvent) { notifyListeners(DND.DragStart,event); if (!event.doit || transferAgents == null || transferAgents.length == 0 ) return; + createCOMInterfaces(); int[] pdwEffect = new int[1]; int operations = opToOs(getStyle()); Display display = control.getDisplay(); @@ -379,6 +380,7 @@ private void drag(Event dragEvent) { topControl = null; } display.setData(key, oldValue); + Release(); } int operation = osToOp(pdwEffect[0]); if (dataEffect == DND.DROP_MOVE) { @@ -388,6 +390,9 @@ private void drag(Event dragEvent) { operation = dataEffect; } } + + disposeCOMInterfaces(); + event = new DNDEvent(); event.widget = this; event.time = OS.GetMessageTime(); diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/DropTarget.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/DropTarget.java index 177e3827bc..844cc84434 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/DropTarget.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/DropTarget.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2017 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -402,80 +402,87 @@ int Drop_64(long pDataObject, int grfKeyState, long pt, long pdwEffect) { } int Drop(long pDataObject, int grfKeyState, int pt_x, int pt_y, long pdwEffect) { - pt_x = DPIUtil.autoScaleDown(pt_x);// To Points - pt_y = DPIUtil.autoScaleDown(pt_y);// To Points - DNDEvent event = new DNDEvent(); - event.widget = this; - event.time = OS.GetMessageTime(); - if (dropEffect != null) { - event.item = dropEffect.getItem(pt_x, pt_y); - } - event.detail = DND.DROP_NONE; - notifyListeners(DND.DragLeave, event); - refresh(); - - event = new DNDEvent(); - if (!setEventData(event, pDataObject, grfKeyState, pt_x, pt_y, pdwEffect)) { + try { + pt_x = DPIUtil.autoScaleDown(pt_x);// To Points + pt_y = DPIUtil.autoScaleDown(pt_y);// To Points + DNDEvent event = new DNDEvent(); + event.widget = this; + event.time = OS.GetMessageTime(); + if (dropEffect != null) { + event.item = dropEffect.getItem(pt_x, pt_y); + } + event.detail = DND.DROP_NONE; + notifyListeners(DND.DragLeave, event); + refresh(); + + event = new DNDEvent(); + if (!setEventData(event, pDataObject, grfKeyState, pt_x, pt_y, pdwEffect)) { + keyOperation = -1; + OS.MoveMemory(pdwEffect, new int[] {COM.DROPEFFECT_NONE}, 4); + return COM.S_FALSE; + } keyOperation = -1; - OS.MoveMemory(pdwEffect, new int[] {COM.DROPEFFECT_NONE}, 4); - return COM.S_FALSE; - } - keyOperation = -1; - int allowedOperations = event.operations; - TransferData[] allowedDataTypes = new TransferData[event.dataTypes.length]; - System.arraycopy(event.dataTypes, 0, allowedDataTypes, 0, allowedDataTypes.length); - event.dataType = selectedDataType; - event.detail = selectedOperation; - notifyListeners(DND.DropAccept,event); - refresh(); + int allowedOperations = event.operations; + TransferData[] allowedDataTypes = new TransferData[event.dataTypes.length]; + System.arraycopy(event.dataTypes, 0, allowedDataTypes, 0, allowedDataTypes.length); + event.dataType = selectedDataType; + event.detail = selectedOperation; + notifyListeners(DND.DropAccept,event); + refresh(); + + selectedDataType = null; + for (int i = 0; i < allowedDataTypes.length; i++) { + if (TransferData.sameType(allowedDataTypes[i], event.dataType)){ + selectedDataType = allowedDataTypes[i]; + break; + } + } + selectedOperation = DND.DROP_NONE; + if (selectedDataType != null && (allowedOperations & event.detail) == event.detail) { + selectedOperation = event.detail; + } - selectedDataType = null; - for (int i = 0; i < allowedDataTypes.length; i++) { - if (TransferData.sameType(allowedDataTypes[i], event.dataType)){ - selectedDataType = allowedDataTypes[i]; - break; + if (selectedOperation == DND.DROP_NONE){ + OS.MoveMemory(pdwEffect, new int[] {COM.DROPEFFECT_NONE}, 4); + return COM.S_OK; } - } - selectedOperation = DND.DROP_NONE; - if (selectedDataType != null && (allowedOperations & event.detail) == event.detail) { - selectedOperation = event.detail; - } - if (selectedOperation == DND.DROP_NONE){ - OS.MoveMemory(pdwEffect, new int[] {COM.DROPEFFECT_NONE}, 4); - return COM.S_OK; - } + // Get Data in a Java format + Object object = null; + for (int i = 0; i < transferAgents.length; i++){ + Transfer transfer = transferAgents[i]; + if (transfer != null && transfer.isSupportedType(selectedDataType)){ + object = transfer.nativeToJava(selectedDataType); + break; + } + } + if (object == null){ + selectedOperation = DND.DROP_NONE; + } - // Get Data in a Java format - Object object = null; - for (int i = 0; i < transferAgents.length; i++){ - Transfer transfer = transferAgents[i]; - if (transfer != null && transfer.isSupportedType(selectedDataType)){ - object = transfer.nativeToJava(selectedDataType); - break; + event.detail = selectedOperation; + event.dataType = selectedDataType; + event.data = object; + OS.ImageList_DragShowNolock(false); + try { + notifyListeners(DND.Drop,event); + } finally { + OS.ImageList_DragShowNolock(true); } - } - if (object == null){ + refresh(); selectedOperation = DND.DROP_NONE; - } - - event.detail = selectedOperation; - event.dataType = selectedDataType; - event.data = object; - OS.ImageList_DragShowNolock(false); - try { - notifyListeners(DND.Drop,event); + if ((allowedOperations & event.detail) == event.detail) { + selectedOperation = event.detail; + } + //notify source of action taken + OS.MoveMemory(pdwEffect, new int[] {opToOs(selectedOperation)}, 4); + return COM.S_OK; } finally { - OS.ImageList_DragShowNolock(true); - } - refresh(); - selectedOperation = DND.DROP_NONE; - if ((allowedOperations & event.detail) == event.detail) { - selectedOperation = event.detail; + if (iDataObject != null) { + iDataObject.Release(); + iDataObject = null; + } } - //notify source of action taken - OS.MoveMemory(pdwEffect, new int[] {opToOs(selectedOperation)}, 4); - return COM.S_OK; } /** |