From 40e409bf9e89a163c771b2a58493d2c1b496fae7 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Wed, 3 May 2017 16:57:07 +0200 Subject: [PATCH] python3: Use "y#" instead of "s#" for binary data in PyArg_ParseTuple 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 Reviewed-by: Andreas Schneider Reviewed-by: Andrew Bartlett --- auth/credentials/pycredentials.c | 6 ++++-- pidl/lib/Parse/Pidl/Samba4/Python.pm | 6 +++--- python/py3compat.h | 8 ++++++++ 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/auth/credentials/pycredentials.c b/auth/credentials/pycredentials.c index 7f03f1f3496..283a73fcd72 100644 --- a/auth/credentials/pycredentials.c +++ b/auth/credentials/pycredentials.c @@ -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, diff --git a/pidl/lib/Parse/Pidl/Samba4/Python.pm b/pidl/lib/Parse/Pidl/Samba4/Python.pm index e40f4f17a57..79beb2e75ed 100644 --- a/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -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,"); diff --git a/python/py3compat.h b/python/py3compat.h index c7724c95748..f54b3912f17 100644 --- a/python/py3compat.h +++ b/python/py3compat.h @@ -98,6 +98,10 @@ PyMODINIT_FUNC PyInit_ ## name(void); \ PyMODINIT_FUNC PyInit_ ## name(void) +/* PyArg_ParseTuple/Py_BuildValue argument */ + +#define PYARG_BYTES_LEN "y#" + #else /***** Python 2 *****/ @@ -140,6 +144,10 @@ #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