]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
pidl:Typelist: resolveType(): don't mistake a reference for a name
authorDouglas Bagnall <douglas.bagnall@catalyst.net.nz>
Wed, 29 May 2024 00:14:04 +0000 (12:14 +1200)
committerDouglas Bagnall <dbagnall@samba.org>
Fri, 31 May 2024 00:25:33 +0000 (00:25 +0000)
This function is only used by Python.pm, and was assuming any argument
unrecognised by hasType is a name. It sometimes isn't, resulting in
structures like this:

{
  'DATA' => {
      'TYPE' => 'STRUCT'
    },
  'NAME' => {
      'TYPE' => 'STRUCT',
      'ALIGN' => undef,
      'SURROUNDING_ELEMENT' => undef,
      'ORIGINAL' => {
      'TYPE' => 'STRUCT',
      'FILE' => 'source3/librpc/idl/smbXsrv.idl',
      'LINE' => 101,
      'NAME' => 'tevent_context'
    },
      'ELEMENTS' => undef,
      'NAME' => 'tevent_context',
      'PROPERTIES' => undef
    },
  'TYPE' => 'TYPEDEF'
      };

The problem with that is we end up with the HASH reference as a name
in Python bindings, like this

      PyErr_SetString(PyExc_TypeError, "Can not convert C Type struct HASH(0x5e2dfe5ee278) from Python");

which makes the build nondeterministic (as well as making the message
a little mysterious).

I think all the structures for which this happens are marked
'[ignore]' in IDL, meaning they are not transmitted on the wire. They
should perhaps also not have useless Python getsetters, but let's call
that a different problem.

Thanks to Freexian and the Debian LTS project for sponsoring this work.

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

Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
pidl/lib/Parse/Pidl/Typelist.pm

index 31ea19e357c56f04144de3b9193435cee0b4e234..2a98a16b2b5fcc53121b0459239d6e35852989dc 100644 (file)
@@ -138,8 +138,18 @@ sub resolveType($)
        my ($ctype) = @_;
 
        if (not hasType($ctype)) {
-               # assume struct typedef
-               return { TYPE => "TYPEDEF", NAME => $ctype, DATA => { TYPE => "STRUCT" } };
+               if (! ref $ctype) {
+                       # it looks like a name.
+                       # assume struct typedef
+                       return { TYPE => "TYPEDEF", NAME => $ctype, DATA => { TYPE => "STRUCT" } };
+               }
+               if ($ctype->{NAME} && ($ctype->{TYPE} eq "STRUCT")) {
+                       return {
+                               TYPE => "TYPEDEF",
+                               NAME => $ctype->{NAME},
+                               DATA => $ctype
+                       };
+               }
        } else {
                return getType($ctype);
        }