diff python/pydc/pydcext.c @ 34:2682a627168c

- breaking changes: * restrict 'Z' conversions to immutable types * restrict 'p' to mutable types (and handles)
author Tassilo Philipp
date Sun, 12 Apr 2020 19:37:37 +0200
parents ba47a3d709d7
children 75fe1dec0eb4
line wrap: on
line diff
--- a/python/pydc/pydcext.c	Sat Apr 11 20:00:25 2020 +0200
+++ b/python/pydc/pydcext.c	Sun Apr 12 19:37:37 2020 +0200
@@ -325,15 +325,11 @@
 				dcArgDouble(gpCall, PyFloat_AsDouble(po));
 				break;
 
-			case DC_SIGCHAR_POINTER:
+			case DC_SIGCHAR_POINTER: // this will only accept integers or mutable array types (meaning only bytearray)
 			{
-				PyObject* bo = NULL;
 				DCpointer p;
-				if ( PyUnicode_Check(po) ) {
-					if((bo = PyUnicode_AsEncodedString(po, "utf-8", "strict")))  // !new ref!
-						p = PyBytes_AS_STRING(bo); // Borrowed pointer
-				} else if ( DcPyString_Check(po) )
-					p = (DCpointer) DcPyString_AsString(po);
+				if ( PyByteArray_Check(po) )
+					p = (DCpointer) PyByteArray_AsString(po); // adds an extra '\0', but that's ok
 #if PY_MAJOR_VERSION < 3
 				else if ( PyInt_Check(po) )
 					p = (DCpointer) PyInt_AS_LONG(po);
@@ -341,25 +337,34 @@
 				else if ( PyLong_Check(po) )
 					p = (DCpointer) PyLong_AsVoidPtr(po);
 				else
-					return PyErr_Format( PyExc_RuntimeError, "arg %d - expecting a promoting pointer-type (int,str)", pos );
+					return PyErr_Format( PyExc_RuntimeError, "arg %d - expecting a promoting pointer-type (int, bytearray)", pos );
 				dcArgPointer(gpCall, p);
-				Py_XDECREF(bo);
 			}
 			break;
 
-			case DC_SIGCHAR_STRING:
+			case DC_SIGCHAR_STRING: // strings are considered to be immutable objects
 			{
 				PyObject* bo = NULL;
 				const char* p;
+				char* p_;
+				size_t s;
 				if ( PyUnicode_Check(po) ) {
 					if((bo = PyUnicode_AsEncodedString(po, "utf-8", "strict")))  // !new ref!
 						p = PyBytes_AS_STRING(bo); // Borrowed pointer
-				} else if ( DcPyString_Check(po) ) {
-					p = DcPyString_AsString(po);
-				} else
+				} else if ( DcPyString_Check(po) )
+					p = DcPyString_AsString(po); //@@@ must not be modified in any way
+				else if ( PyByteArray_Check(po) )
+					p = (DCpointer) PyByteArray_AsString(po); // adds an extra '\0', but that's ok //@@@ not sure if allowed to modify
+				else
 					return PyErr_Format( PyExc_RuntimeError, "arg %d - expecting a str", pos );
-				dcArgPointer(gpCall, (DCpointer) p);
+
+				// pointer points in any case to a buffer that shouldn't be modified, so pass a copy of the string to dyncall
+				s = strlen(p)+1;
+				p_ = malloc(s);
+				strncpy(p_, p, s);
 				Py_XDECREF(bo);
+				dcArgPointer(gpCall, (DCpointer)p_);
+				free(p_);
 			}
 			break;