python3: Use "y#" instead of "s#" for binary data in PyArg_ParseTuple
authorPetr Viktorin <pviktori@redhat.com>
Wed, 3 May 2017 14:57:07 +0000 (16:57 +0200)
committerAndrew Bartlett <abartlet@samba.org>
Fri, 19 May 2017 20:20:15 +0000 (22:20 +0200)
The "s#" format code for PyArg_ParseTupleAndKeywords and Py_BuildValue
converts a char* and size to/from Python str (with utf-8 encoding under
Python 3).
In some cases, we want bytes (str on Python 2, bytes on 3) instead. The
code for this is "y#" in Python 3, but that is not available in 2.

Introduce a PYARG_BYTES_LEN macro that expands to "s#" or "y#", and use
that in:
- credentials.get_ntlm_response (for input and output)
- ndr_unpack argument in PIDL generated code

Signed-off-by: Petr Viktorin <pviktori@redhat.com>
Reviewed-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
auth/credentials/pycredentials.c
pidl/lib/Parse/Pidl/Samba4/Python.pm
python/py3compat.h

index 7f03f1f3496308343954db72d14917ac75b0dd26..283a73fcd721237cb6a70ef96cc86912ac036a30 100644 (file)
@@ -96,7 +96,8 @@ static PyObject *py_creds_get_ntlm_response(PyObject *self, PyObject *args, PyOb
        tv_now = timeval_current();
        server_timestamp = timeval_to_nttime(&tv_now);
 
-       if (!PyArg_ParseTupleAndKeywords(args, kwargs, "is#|s#K",
+       if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+                                        "i" PYARG_BYTES_LEN "|" PYARG_BYTES_LEN "K",
                                         discard_const_p(char *, kwnames),
                                         &flags, &challenge, &target_info.data, &target_info.length)) {
                return NULL;
@@ -116,7 +117,8 @@ static PyObject *py_creds_get_ntlm_response(PyObject *self, PyObject *args, PyOb
                return NULL;
        }
 
-       ret = Py_BuildValue("{siss#ss#ss#ss#}",
+       ret = Py_BuildValue("{sis" PYARG_BYTES_LEN "s" PYARG_BYTES_LEN
+                                   "s" PYARG_BYTES_LEN "s" PYARG_BYTES_LEN "}",
                            "flags", flags,
                            "lm_reponse",
                            (const char *)lm_response.data, lm_response.length,
index e40f4f17a5749ae3f3b72545181e9658b47f83c0..79beb2e75ed36d7825eb9be1b634abf9ba165e79 100644 (file)
@@ -320,7 +320,7 @@ sub PythonStruct($$$$$$)
                $self->pidl("PyObject *allow_remaining_obj = NULL;");
                $self->pidl("bool allow_remaining = false;");
                $self->pidl("");
-               $self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, \"s#|O:__ndr_unpack__\",");
+               $self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, PYARG_BYTES_LEN \"|O:__ndr_unpack__\",");
                $self->indent;
                $self->pidl("discard_const_p(char *, kwnames),");
                $self->pidl("&blob.data, &blob_length,");
@@ -705,7 +705,7 @@ sub PythonFunctionStruct($$$$)
        $self->pidl("PyObject *allow_remaining_obj = NULL;");
        $self->pidl("bool allow_remaining = false;");
        $self->pidl("");
-       $self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, \"s#|OOO:__ndr_unpack_in__\",");
+       $self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, PYARG_BYTES_LEN \"|OOO:__ndr_unpack_in__\",");
        $self->indent;
        $self->pidl("discard_const_p(char *, kwnames),");
        $self->pidl("&blob.data, &blob_length,");
@@ -753,7 +753,7 @@ sub PythonFunctionStruct($$$$)
        $self->pidl("PyObject *allow_remaining_obj = NULL;");
        $self->pidl("bool allow_remaining = false;");
        $self->pidl("");
-       $self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, \"s#|OOO:__ndr_unpack_out__\",");
+       $self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, PYARG_BYTES_LEN \"|OOO:__ndr_unpack_out__\",");
        $self->indent;
        $self->pidl("discard_const_p(char *, kwnames),");
        $self->pidl("&blob.data, &blob_length,");
index c7724c957489bab6f8b7309a6a325926e44be7b8..f54b3912f175f518fed3c7fb94a0521321736570 100644 (file)
     PyMODINIT_FUNC PyInit_ ## name(void); \
     PyMODINIT_FUNC PyInit_ ## name(void)
 
+/* PyArg_ParseTuple/Py_BuildValue argument */
+
+#define PYARG_BYTES_LEN "y#"
+
 #else
 
 /***** Python 2 *****/
 #define PyBytes_ConcatAndDel PyString_ConcatAndDel
 #define _PyBytes_Resize _PyString_Resize
 
+/* PyArg_ParseTuple/Py_BuildValue argument */
+
+#define PYARG_BYTES_LEN "s#"
+
 /* Module init */
 
 #define PyModuleDef_HEAD_INIT 0