pidl/Python: use py_dcerpc_ndr_pointer_wrap/deref if multiple pointer levels are...
authorStefan Metzmacher <metze@samba.org>
Thu, 29 Nov 2018 12:25:21 +0000 (13:25 +0100)
committerJeremy Allison <jra@samba.org>
Sat, 12 Jan 2019 02:13:41 +0000 (03:13 +0100)
This will help the raw_protocol test to explore lsa_GetUserName.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
pidl/lib/Parse/Pidl/Samba4/Python.pm

index 1ef64db..5697b52 100644 (file)
@@ -1902,6 +1902,9 @@ sub ConvertObjectFromPythonLevel($$$$$$$$$)
        $recurse = $recurse + 1;
 
        if ($l->{TYPE} eq "POINTER") {
+               my $need_deindent = 0;
+               my $need_deref = 0;
+
                if ($l->{POINTER_TYPE} ne "ref") {
                        $self->pidl("if ($py_var == Py_None) {");
                        $self->indent;
@@ -1909,10 +1912,13 @@ sub ConvertObjectFromPythonLevel($$$$$$$$$)
                        $self->deindent;
                        $self->pidl("} else {");
                        $self->indent;
+                       $need_deindent = 1;
+                       if ($nl->{TYPE} eq "POINTER") {
+                               $need_deref = 1;
+                       }
                }
-               # if we want to handle more than one level of pointer in python interfaces
-               # then this is where we would need to allocate it
-               if ($l->{POINTER_TYPE} eq "ref") {
+
+               if ($l->{POINTER_TYPE} eq "ref" or $need_deref == 1) {
                        $self->pidl("$var_name = talloc_ptrtype($mem_ctx, $var_name);");
                        $self->pidl("if ($var_name == NULL) {");
                        $self->indent;
@@ -1932,11 +1938,15 @@ sub ConvertObjectFromPythonLevel($$$$$$$$$)
                } else {
                        $self->pidl("$var_name = NULL;");
                }
+               if ($need_deref == 1) {
+                       my $ndr_pointer_typename = $self->import_type_variable("samba.dcerpc.base", "ndr_pointer");
+                       $self->pidl("$py_var = py_dcerpc_ndr_pointer_deref($ndr_pointer_typename, $py_var);");
+               }
                unless ($nl->{TYPE} eq "DATA" and Parse::Pidl::Typelist::scalar_is_reference($nl->{DATA_TYPE})) {
                        $var_name = get_value_of($var_name);
                }
                $self->ConvertObjectFromPythonLevel($env, $mem_ctx, $py_var, $e, $nl, $var_name, $fail, $recurse);
-               if ($l->{POINTER_TYPE} ne "ref") {
+               if ($need_deindent == 1) {
                        $self->deindent;
                        $self->pidl("}");
                }
@@ -2138,6 +2148,10 @@ sub ConvertObjectToPythonLevel($$$$$$$)
        }
 
        if ($l->{TYPE} eq "POINTER") {
+               my $need_wrap = 0;
+               if ($l->{POINTER_TYPE} ne "ref" and $nl->{TYPE} eq "POINTER") {
+                       $need_wrap = 1;
+               }
                if ($l->{POINTER_TYPE} ne "ref") {
                        if ($recurse == 0) {
                                $self->pidl("if ($var_name == NULL) {");
@@ -2164,6 +2178,19 @@ sub ConvertObjectToPythonLevel($$$$$$$)
                        $self->deindent;
                        $self->pidl("}");
                }
+               if ($need_wrap) {
+                       my $py_var_wrap = undef;
+                       $need_wrap = 1;
+                       $self->pidl("{");
+                       $self->indent;
+                       $py_var_wrap = "py_$e->{NAME}_level_$l->{LEVEL_INDEX}";
+                       $self->pidl("PyObject *$py_var_wrap = $py_var;");
+                       my $ndr_pointer_typename = $self->import_type_variable("samba.dcerpc.base", "ndr_pointer");
+                       $self->pidl("$py_var = py_dcerpc_ndr_pointer_wrap($ndr_pointer_typename, $py_var_wrap);");
+                       $self->pidl("Py_XDECREF($py_var_wrap);");
+                       $self->deindent;
+                       $self->pidl("}");
+               }
        } elsif ($l->{TYPE} eq "ARRAY") {
                if ($pl && $pl->{TYPE} eq "POINTER") {
                        $var_name = get_pointer_to($var_name);