From f532c207f5a70e24c0c83359084dc17658b7f956 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 9 May 2017 15:02:02 +0200 Subject: [PATCH] pidl/Python: improve error handling in PythonFunctionUnpackOut() results Signed-off-by: Stefan Metzmacher --- pidl/lib/Parse/Pidl/Samba4/Python.pm | 43 +++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/pidl/lib/Parse/Pidl/Samba4/Python.pm b/pidl/lib/Parse/Pidl/Samba4/Python.pm index efb3265a5da1..a46bebe51d08 100644 --- a/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -938,57 +938,86 @@ sub PythonFunctionUnpackOut($$$) $self->pidl("static PyObject *$outfnname(struct $fn->{NAME} *r)"); $self->pidl("{"); $self->indent; - $self->pidl("PyObject *result;"); + $self->pidl("PyObject *result = NULL;"); foreach my $e (@{$fn->{ELEMENTS}}) { next unless (grep(/out/,@{$e->{DIRECTION}})); next if (($metadata_args->{in}->{$e->{NAME}} and grep(/in/, @{$e->{DIRECTION}})) or ($metadata_args->{out}->{$e->{NAME}}) and grep(/out/, @{$e->{DIRECTION}})); - $self->pidl("PyObject *py_$e->{NAME};"); + $self->pidl("PyObject *py_$e->{NAME} = NULL;"); $result_size++; } if ($fn->{RETURN_TYPE}) { - $result_size++ unless ($fn->{RETURN_TYPE} eq "WERROR" or $fn->{RETURN_TYPE} eq "NTSTATUS"); + if ($fn->{RETURN_TYPE} ne "WERROR" and $fn->{RETURN_TYPE} ne "NTSTATUS") { + $self->pidl("PyObject *py_result = NULL;"); + $result_size++; + } } my $i = 0; + my $fail = "return NULL;"; + if ($result_size > 1) { + $self->pidl("int ret;"); + $self->pidl(""); $self->pidl("result = PyTuple_New($result_size);"); + $self->fail_on_null("result", $fail); + $fail = "Py_DECREF(result); " . $fail; + $signature .= "("; } elsif ($result_size == 0) { + $self->pidl(""); $self->pidl("result = Py_None;"); $self->pidl("Py_INCREF(result);"); $signature .= "None"; } + $self->pidl(""); + foreach my $e (@{$fn->{ELEMENTS}}) { next if ($metadata_args->{out}->{$e->{NAME}}); my $py_name = "py_$e->{NAME}"; if (grep(/out/,@{$e->{DIRECTION}})) { - $self->ConvertObjectToPython("r", $env, $e, "r->out.$e->{NAME}", $py_name, "return NULL;"); + $self->ConvertObjectToPython("r", $env, $e, "r->out.$e->{NAME}", $py_name, $fail); if ($result_size > 1) { - $self->pidl("PyTuple_SetItem(result, $i, $py_name);"); + $self->pidl("ret = PyTuple_SetItem(result, $i, $py_name);"); + $self->pidl("if (ret != 0) {"); + $self->indent; + $self->pidl($fail); + $self->deindent; + $self->pidl("}"); $i++; $signature .= "$e->{NAME}, "; } else { $self->pidl("result = $py_name;"); $signature .= $e->{NAME}; } + $self->pidl(""); } } if (defined($fn->{RETURN_TYPE}) and $fn->{RETURN_TYPE} eq "NTSTATUS") { $self->handle_ntstatus("r->out.result", "NULL", undef); + $self->pidl(""); } elsif (defined($fn->{RETURN_TYPE}) and $fn->{RETURN_TYPE} eq "WERROR") { $self->handle_werror("r->out.result", "NULL", undef); + $self->pidl(""); } elsif (defined($fn->{RETURN_TYPE})) { my $conv = $self->ConvertObjectToPythonData("r", $fn->{RETURN_TYPE}, "r->out.result", $fn); + $self->pidl("py_result = $conv;"); + $self->fail_on_null("py_result", $fail); if ($result_size > 1) { - $self->pidl("PyTuple_SetItem(result, $i, $conv);"); + $self->pidl("ret = PyTuple_SetItem(result, $i, py_result);"); + $self->pidl("if (ret != 0) {"); + $self->indent; + $self->pidl($fail); + $self->deindent; + $self->pidl("}"); } else { - $self->pidl("result = $conv;"); + $self->pidl("result = py_result;"); } + $self->pidl(""); $signature .= "result"; } -- 2.34.1