From: Stefan Metzmacher Date: Tue, 28 Jan 2025 13:56:54 +0000 (+0100) Subject: pidl:Python: prepare code to avoid NTSTATUS/WERROR exceptions X-Git-Tag: samba-4.20.8~44 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3e1b15aa6f18d1ba02ba0297005df85efd5d76d9;p=thirdparty%2Fsamba.git pidl:Python: prepare code to avoid NTSTATUS/WERROR exceptions They are returned as additional result. It means callers can look at all out params, even if the status is an error. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14213 Signed-off-by: Stefan Metzmacher Reviewed-by: Douglas Bagnall (cherry picked from commit 7ecaf1a779370ef3ecf189e51a5e668329fa24c7) --- diff --git a/pidl/lib/Parse/Pidl/Samba4/Python.pm b/pidl/lib/Parse/Pidl/Samba4/Python.pm index 6db26cc04dc..7a415c99c3a 100644 --- a/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -970,6 +970,7 @@ sub PythonFunctionUnpackOut($$$) $self->pidl("static PyObject *$outfnname(struct $fn->{NAME} *r)"); $self->pidl("{"); $self->indent; + $self->pidl("_UNUSED_ bool raise_result_exception = true;"); foreach my $e (@{$fn->{ELEMENTS}}) { next unless (grep(/out/,@{$e->{DIRECTION}})); next if (($metadata_args->{in}->{$e->{NAME}} and grep(/in/, @{$e->{DIRECTION}})) or @@ -987,7 +988,16 @@ sub PythonFunctionUnpackOut($$$) $result_size++; } + my $max_result_size = $result_size; + my $alloc_size = "$result_size"; + if ($fn->{RETURN_TYPE} and $is_raisable_return) { + $max_result_size++; + } $self->pidl("PyObject *result = NULL;"); + if ($max_result_size != $result_size) { + $self->pidl("size_t result_size = $result_size;"); + $alloc_size = "result_size"; + } $self->pidl(""); if ($result_size > 1) { @@ -997,24 +1007,39 @@ sub PythonFunctionUnpackOut($$$) } if ($fn->{RETURN_TYPE} and $is_raisable_return) { + $self->pidl("if (raise_result_exception) {"); + $self->indent; if (defined($fn->{RETURN_TYPE}) and $fn->{RETURN_TYPE} eq "NTSTATUS") { $self->handle_ntstatus("r->out.result", "NULL", undef); } elsif (defined($fn->{RETURN_TYPE}) and $fn->{RETURN_TYPE} eq "WERROR") { $self->handle_werror("r->out.result", "NULL", undef); } + $self->deindent; + $self->pidl("} else {"); + $self->indent; + $self->pidl("/* $fn->{RETURN_TYPE} will be part of the results */"); + $self->pidl("result_size += 1;"); + $self->deindent; + $self->pidl("}"); + $self->pidl(""); } - if ($result_size > 1) { - $self->pidl("result = PyTuple_New($result_size);"); + if ($max_result_size > 1) { + if ($max_result_size != $result_size) { + $self->pidl("if (result_size > 1) {"); + $self->indent; + } + $self->pidl("result = PyTuple_New($alloc_size);"); $self->pidl("if (result == NULL) {"); $self->indent; $self->pidl("return NULL;"); $self->deindent; $self->pidl("}"); + if ($max_result_size != $result_size) { + $self->deindent; + $self->pidl("}"); + } $self->pidl(""); - } elsif ($result_size == 0) { - $self->pidl("result = Py_None;"); - $self->pidl("Py_INCREF(result);"); } my $i = 0; @@ -1030,23 +1055,59 @@ sub PythonFunctionUnpackOut($$$) $signature .= $e->{NAME}; } - if ($result_size > 1) { + if ($max_result_size > 1) { + if ($max_result_size != $result_size and $result_size == 1) { + $self->pidl("if (result_size > 1) {"); + $self->indent; + } $self->pidl("PyTuple_SetItem(result, $i, $py_name);"); - $i++; - } else { + if ($max_result_size != $result_size and $result_size == 1) { + $self->deindent; + $self->pidl("}"); + } + } + if ($result_size == 1) { + if ($max_result_size != $result_size) { + $self->pidl("if (result_size == 1) {"); + $self->indent; + } $self->pidl("result = $py_name;"); + if ($max_result_size != $result_size) { + $self->deindent; + $self->pidl("}"); + } } + $self->pidl(""); + $i++; } } - if ($fn->{RETURN_TYPE} and not $is_raisable_return) { + if ($fn->{RETURN_TYPE} and $is_raisable_return) { + $self->pidl("if (!raise_result_exception) {"); + $self->indent; + } + + if ($fn->{RETURN_TYPE}) { my $conv = $self->ConvertObjectToPythonData("r", $fn->{RETURN_TYPE}, "r->out.result", $fn); - if ($result_size > 1) { + if ($max_result_size > 1) { $self->pidl("PyTuple_SetItem(result, $i, $conv);"); - } else { + } elsif ($max_result_size == 1) { $self->pidl("result = $conv;"); + } else { + fatal($fn->{ORIGINAL}, "Internal error max_result_size=$max_result_size"); } - $signature .= "result"; + + if (not $is_raisable_return) { + $signature .= "result"; + } + } + + if ($fn->{RETURN_TYPE} and $is_raisable_return) { + $self->deindent; + $self->pidl("}"); + $self->pidl(""); + } elsif ($fn->{RETURN_TYPE}) { + $self->pidl(""); } if (substr($signature, -2) eq ", ") { @@ -1056,6 +1117,20 @@ sub PythonFunctionUnpackOut($$$) $signature .= ")"; } + if ($result_size == 0) { + if ($max_result_size != $result_size) { + $self->pidl("if (result_size == 0) {"); + $self->indent; + } + $self->pidl("result = Py_None;"); + $self->pidl("Py_INCREF(result);"); + if ($max_result_size != $result_size) { + $self->deindent; + $self->pidl("}"); + } + $self->pidl(""); + } + $self->pidl("return result;"); $self->deindent; $self->pidl("}");