From: Stefan Metzmacher Date: Tue, 9 May 2017 07:59:39 +0000 (+0200) Subject: pidl/Python: generate a ndr_PyLong_AsCheckedUnsignedLongLong() helper function X-Git-Url: http://git.samba.org/?p=metze%2Fsamba%2Fwip.git;a=commitdiff_plain;h=d7f3d3cf35269867c03e3c14baa1d62a55dcc387 pidl/Python: generate a ndr_PyLong_AsCheckedUnsignedLongLong() helper function This reduces the size of the generated C code a lot. Signed-off-by: Stefan Metzmacher --- diff --git a/pidl/lib/Parse/Pidl/Samba4/Python.pm b/pidl/lib/Parse/Pidl/Samba4/Python.pm index 570e8675eda3..20830f809f08 100644 --- a/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -1750,45 +1750,14 @@ sub ConvertObjectFromPythonData($$$$$$;$$) |uid_t|gid_t)$/x) { $self->pidl("{"); $self->indent; - $self->pidl("const unsigned long long uint_max = ndr_sizeof2uintmax(sizeof($target));"); - $self->pidl("if (PyLong_Check($cvar)) {"); - $self->indent; - $self->pidl("unsigned long long test_var;"); - $self->pidl("test_var = PyLong_AsUnsignedLongLong($cvar);"); + $self->pidl("unsigned long long ull_value;"); + $self->pidl("ull_value = ndr_PyLong_AsCheckedUnsignedLongLong($cvar, sizeof($target));"); $self->pidl("if (PyErr_Occurred() != NULL) {"); $self->indent; $self->pidl($fail); $self->deindent; $self->pidl("}"); - $self->pidl("if (test_var > uint_max) {"); - $self->indent; - $self->pidl("PyErr_Format(PyExc_OverflowError, \"Expected type %s or %s within range 0 - %llu, got %llu\",\\"); - $self->pidl(" PyInt_Type.tp_name, PyLong_Type.tp_name, uint_max, test_var);"); - $self->pidl($fail); - $self->deindent; - $self->pidl("}"); - $self->pidl("$target = test_var;"); - $self->deindent; - $self->pidl("} else if (PyInt_Check($cvar)) {"); - $self->indent; - $self->pidl("long test_var;"); - $self->pidl("test_var = PyInt_AsLong($cvar);"); - $self->pidl("if (test_var < 0 || (unsigned long long)test_var > uint_max) {"); - $self->indent; - $self->pidl("PyErr_Format(PyExc_OverflowError, \"Expected type %s or %s within range 0 - %llu, got %ld\",\\"); - $self->pidl(" PyInt_Type.tp_name, PyLong_Type.tp_name, uint_max, test_var);"); - $self->pidl($fail); - $self->deindent; - $self->pidl("}"); - $self->pidl("$target = test_var;"); - $self->deindent; - $self->pidl("} else {"); - $self->indent; - $self->pidl("PyErr_Format(PyExc_TypeError, \"Expected type %s or %s\",\\"); - $self->pidl(" PyInt_Type.tp_name, PyLong_Type.tp_name);"); - $self->pidl($fail); - $self->deindent; - $self->pidl("}"); + $self->pidl("$target = (" . mapTypeName($ctype_alias) . ")ull_value;"); $self->deindent; $self->pidl("}"); return; @@ -2391,6 +2360,62 @@ static inline PyObject *ndr_PyLong_FromUnsignedLongLong(unsigned long long v) } } +/* + * This is the unsigned Python Integer -> C integer validation + * case. The signed case is below. + */ +static inline unsigned long long ndr_PyLong_AsCheckedUnsignedLongLong(PyObject *py_value, + size_t target_size) +{ + const unsigned long long uint_max = ndr_sizeof2uintmax(target_size); + unsigned long long ret_value = 0; + + if (PyLong_Check(py_value)) { + unsigned long long test_var; + + test_var = PyLong_AsUnsignedLongLong(py_value); + if (PyErr_Occurred() != NULL) { + return 0; + } + + if (test_var > uint_max) { + PyErr_Format(PyExc_OverflowError, + \"Expected type %s or %s within range 0 - %llu, got %llu\", + PyInt_Type.tp_name, PyLong_Type.tp_name, uint_max, test_var); + return 0; + } + + ret_value = test_var; + + return ret_value; + } + + if (PyInt_Check(py_value)) { + long test_var; + + test_var = PyInt_AsLong(py_value); + if (PyErr_Occurred() != NULL) { + return 0; + } + + if (test_var < 0 || (unsigned long long)test_var > uint_max) { + PyErr_Format(PyExc_OverflowError, + \"Expected type %s or %s within range 0 - %llu, got %ld\", + PyInt_Type.tp_name, PyLong_Type.tp_name, uint_max, test_var); + return 0; + } + + ret_value = test_var; + + return ret_value; + } + + PyErr_Format(PyExc_TypeError, + \"Expected type %s or %s within range 0 - %llu\", + PyInt_Type.tp_name, PyLong_Type.tp_name, uint_max); + return 0; +} + "); foreach my $x (@$ndr) {