[Kde-bindings] KDE/kdebindings/csharp

Arno Rehn kde at arnorehn.de
Tue May 11 10:52:33 UTC 2010


SVN commit 1125426 by arnorehn:

Fix some grave bugs in marshalling C++ stack variables to C# objects:

First, When calling a C# method from C++ (i.e. a virtual method or a slot), create copies of the stack arguments,
which are then later used in C#. Before, if a signal linkClicked(QUrl) was connected to a slot, the wrapper
C# class Qyoto.QUrl was created with the pointer to the temporary value QUrl. This lead to a double-free crash.

Second, if a C++ value is converted to a C# native type (e.g. QLists), always delete the original QList if it was
passed on stack because it's not needed anymore.

Third, never ever delete pointers (even if cleanup() is set), when we later use them in C# (was the case with the char* and uchar* marshaller).

CCMAIL: kde-bindings at kde.org



 M  +1 -1      kimono/src/kdehandlers.cpp  
 M  +4 -0      plasma/src/plasmahandlers.cpp  
 M  +1 -1      qyoto/src/delegateinvocation.h  
 M  +30 -13    qyoto/src/handlers.cpp  
 M  +1 -1      qyoto/src/invokeslot.h  
 M  +3 -3      qyoto/src/marshall_macros.h  
 M  +1 -1      qyoto/src/virtualmethodcall.h  


--- trunk/KDE/kdebindings/csharp/kimono/src/kdehandlers.cpp #1125425:1125426
@@ -84,7 +84,7 @@
 
 		m->var().s_voidp = av;
 	    
-		if (m->cleanup())
+		if (m->type().isStack())
 			delete offerList;
 	}
 	break;
--- trunk/KDE/kdebindings/csharp/plasma/src/plasmahandlers.cpp #1125425:1125426
@@ -104,6 +104,10 @@
 			m->var().s_voidp = dict;
 			m->next();
 			
+			if (m->type().isStack()) {
+				delete map;
+			}
+
 			break;
 		}
 	
--- trunk/KDE/kdebindings/csharp/qyoto/src/delegateinvocation.h #1125425:1125426
@@ -88,7 +88,7 @@
 	inline Smoke::StackItem &var() { return _sp[_cur]; }
 	inline Smoke *smoke() { return type().smoke(); }
 
-	inline bool cleanup() { return false; }
+	inline bool cleanup() { return true; }
 	inline void unsupported() { qFatal("Cannot handle '%s' as slot argument\n", type().name()); }
 
 	void next() {
--- trunk/KDE/kdebindings/csharp/qyoto/src/handlers.cpp #1125425:1125426
@@ -1051,7 +1051,7 @@
 		smokeqyoto_object  * o = alloc_smokeqyoto_object(false, m->smoke(), m->type().classId(), p);
 		const char * classname = qyoto_resolve_classname(o);
 
-		if(m->type().isConst() && m->type().isRef()) {
+		if((m->type().isConst() && m->type().isRef()) || (m->type().isStack() && m->cleanup())) {
 			p = construct_copy( o );
 			if (p != 0) {
 				o->ptr = p;
@@ -1120,11 +1120,7 @@
 	    } else {
 			m->var().s_class = 0;
 		}
-
-	    if (m->cleanup()) {
-			delete[] p;
 		}
-	}
 	break;
 
 	default:
@@ -1146,10 +1142,7 @@
 	{
 		uchar *p = (uchar*) m->item().s_voidp;
 		m->var().s_class = (*CreateGenericPointer)("System.Byte", p);
-	    if (m->cleanup()) {
-			delete[] p;
 		}
-	}
 	break;
 
 	default:
@@ -1197,7 +1190,7 @@
 				m->var().s_class = (*IntPtrFromQString)(s);
 			}
 
-			if (m->cleanup() || m->type().isStack())
+			if (m->type().isStack())
 				delete s;
 			} else {
 				m->var().s_voidp = 0;
@@ -1470,6 +1463,15 @@
 		Smoke::ModuleIndex id = m->smoke()->findClass("QVariant");
 		smokeqyoto_object  * o = alloc_smokeqyoto_object(false, id.smoke, id.index, p);
 		
+		if((m->type().isConst() && m->type().isRef()) || (m->type().isStack() && m->cleanup())) {
+			p = construct_copy( o );
+			if (p != 0) {
+				o->ptr = p;
+				o->allocated = true;
+		    }
+		}
+
+		
 		obj = (*CreateInstance)("Qyoto.QDBusVariant", o);
 		if (do_debug & qtdb_calls) {
 			printf("allocating %s %p -> %p\n", "QDBusVariant", o->ptr, (void*)obj);
@@ -1527,6 +1529,10 @@
 			m->var().s_voidp = dict;
 			m->next();
 			
+			if (m->type().isStack()) {
+				delete map;
+			}
+			
 			break;
 		}
 	
@@ -1573,6 +1579,11 @@
 			m->var().s_voidp = dict;
 			m->next();
 			
+			if (m->type().isStack()) {
+				delete map;
+			}
+
+			
 			break;
 		}
 	
@@ -1623,6 +1634,11 @@
 			m->var().s_voidp = dict;
 			m->next();
 			
+			if (m->type().isStack()) {
+				delete map;
+			}
+
+			
 			break;
 		}
 	
@@ -1668,7 +1684,7 @@
 		m->var().s_voidp = al;
 		m->next();
 
-		if (m->cleanup()) {
+		if (m->type().isStack()) {
 			delete stringlist;
 		}
 
@@ -1752,7 +1768,7 @@
 	    m->var().s_voidp = av;
 		m->next();
 
-		if (m->cleanup()) {
+		if (m->type().isStack()) {
 			delete valuelist;
 		}
 	}
@@ -1779,9 +1795,10 @@
 		}
 		m->var().s_voidp = al;
 		m->next();
-		if (m->cleanup())
+		if (m->type().isStack()) {
 			delete list;
 	}
+	}
 	break;
 	default:
 		m->unsupported();
@@ -1849,7 +1866,7 @@
 			m->var().s_voidp = al;
 			m->next();
 
-			if (m->cleanup()) {
+			if (m->type().isStack()) {
 				delete valuelist;
 			}
 			
--- trunk/KDE/kdebindings/csharp/qyoto/src/invokeslot.h #1125425:1125426
@@ -45,7 +45,7 @@
 	inline Smoke::StackItem &var() { return _sp[_cur]; }
 	inline Smoke *smoke() { return type().smoke(); }
 
-	inline bool cleanup() { return false; }
+	inline bool cleanup() { return true; }
 	void unsupported();
 	void copyArguments();
 	void invokeSlot();
--- trunk/KDE/kdebindings/csharp/qyoto/src/marshall_macros.h #1125425:1125426
@@ -81,7 +81,7 @@
 			m->var().s_voidp = al;
 			m->next();
 
-			if (m->cleanup()) {
+			if (m->type().isStack()) {
 				delete list;
 			}
 			
@@ -166,7 +166,7 @@
 			m->var().s_voidp = al;
 			m->next();
 
-			if (m->cleanup()) {
+			if (m->type().isStack()) {
 				delete valuelist;
 			}
 			
@@ -268,7 +268,7 @@
 			m->var().s_voidp = pair;
 			m->next();
 
-			if (m->cleanup() || m->type().isStack()) {
+			if (m->type().isStack()) {
 				delete qpair;
 			}
 		}
--- trunk/KDE/kdebindings/csharp/qyoto/src/virtualmethodcall.h #1125425:1125426
@@ -44,7 +44,7 @@
 	inline Smoke::StackItem &var() { return _sp[_cur + 1]; }
 	inline const Smoke::Method &method() { return _smoke->methods[_method]; }
 	inline Smoke *smoke() { return _smoke; }
-	inline bool cleanup() { return false; }   // is this right?
+	inline bool cleanup() { return true; }
 
 	void unsupported();
 	void callMethod();



More information about the Kde-bindings mailing list