r21455: Fix a bug in our handling of conformant arrays. The conformant array was
authorJelmer Vernooij <jelmer@samba.org>
Mon, 19 Feb 2007 19:42:51 +0000 (19:42 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 19:48:37 +0000 (14:48 -0500)
always pushed, even if just the buffers part of a struct had to be pushed.

Pull was not affected.

source/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
source/pidl/tests/samba-ndr.pl

index a4957fc7d9493aa4a2174935431e925ab0da5d4f..8393d6f3c006c127174d5cdded0bfbd00ddd58a1 100644 (file)
@@ -12,7 +12,7 @@ require Exporter;
 @EXPORT = qw(is_charset_array);
 @EXPORT_OK = qw(check_null_pointer GenerateFunctionInEnv 
    GenerateFunctionOutEnv EnvSubstituteValue GenerateStructEnv NeededFunction
-   NeededElement NeededType);
+   NeededElement NeededType $res);
 
 use strict;
 use Parse::Pidl::Typelist qw(hasType getType mapTypeName);
@@ -110,7 +110,7 @@ sub get_value_of($)
        }
 }
 
-my $res;
+our $res;
 my $deferred = [];
 my $tabs = "";
 
@@ -1194,6 +1194,34 @@ sub ParseStructPushPrimitives($$$$)
 {
        my ($struct, $name, $varname, $env) = @_;
 
+       # see if the structure contains a conformant array. If it
+       # does, then it must be the last element of the structure, and
+       # we need to push the conformant length early, as it fits on
+       # the wire before the structure (and even before the structure
+       # alignment)
+       if (defined($struct->{SURROUNDING_ELEMENT})) {
+               my $e = $struct->{SURROUNDING_ELEMENT};
+
+               if (defined($e->{LEVELS}[0]) and 
+                       $e->{LEVELS}[0]->{TYPE} eq "ARRAY") {
+                       my $size;
+                       
+                       if ($e->{LEVELS}[0]->{IS_ZERO_TERMINATED}) {
+                               if (has_property($e, "charset")) {
+                                       $size = "ndr_charset_length($varname->$e->{NAME}, CH_$e->{PROPERTIES}->{charset})";
+                               } else {
+                                       $size = "ndr_string_length($varname->$e->{NAME}, sizeof(*$varname->$e->{NAME}))";
+                               }
+                       } else {
+                               $size = ParseExpr($e->{LEVELS}[0]->{SIZE_IS}, $env, $e->{ORIGINAL});
+                       }
+
+                       pidl "NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, $size));";
+               } else {
+                       pidl "NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_string_array_size(ndr, $varname->$e->{NAME})));";
+               }
+       }
+
        pidl "NDR_CHECK(ndr_push_align(ndr, $struct->{ALIGN}));";
 
        if (defined($struct->{PROPERTIES}{relative_base})) {
@@ -1232,34 +1260,6 @@ sub ParseStructPush($$$)
 
        start_flags($struct);
 
-       # see if the structure contains a conformant array. If it
-       # does, then it must be the last element of the structure, and
-       # we need to push the conformant length early, as it fits on
-       # the wire before the structure (and even before the structure
-       # alignment)
-       if (defined($struct->{SURROUNDING_ELEMENT})) {
-               my $e = $struct->{SURROUNDING_ELEMENT};
-
-               if (defined($e->{LEVELS}[0]) and 
-                       $e->{LEVELS}[0]->{TYPE} eq "ARRAY") {
-                       my $size;
-                       
-                       if ($e->{LEVELS}[0]->{IS_ZERO_TERMINATED}) {
-                               if (has_property($e, "charset")) {
-                                       $size = "ndr_charset_length($varname->$e->{NAME}, CH_$e->{PROPERTIES}->{charset})";
-                               } else {
-                                       $size = "ndr_string_length($varname->$e->{NAME}, sizeof(*$varname->$e->{NAME}))";
-                               }
-                       } else {
-                               $size = ParseExpr($e->{LEVELS}[0]->{SIZE_IS}, $env, $e->{ORIGINAL});
-                       }
-
-                       pidl "NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, $size));";
-               } else {
-                       pidl "NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_string_array_size(ndr, $varname->$e->{NAME})));";
-               }
-       }
-
        pidl "if (ndr_flags & NDR_SCALARS) {";
        indent;
        ParseStructPushPrimitives($struct, $name, $varname, $env);
index 28b41e4486f0c60dae8c19374809032e99173f25..a528265e64040cc71f6e36446c3ee46a0c61f687 100755 (executable)
@@ -4,14 +4,14 @@
 use strict;
 use warnings;
 
-use Test::More tests => 32;
+use Test::More tests => 34;
 use FindBin qw($RealBin);
 use lib "$RealBin";
 use Util;
 use Parse::Pidl::Util qw(MyDumper);
 use Parse::Pidl::Samba4::NDR::Parser qw(check_null_pointer 
        GenerateFunctionInEnv GenerateFunctionOutEnv GenerateStructEnv 
-       EnvSubstituteValue NeededFunction NeededElement NeededType); 
+       EnvSubstituteValue NeededFunction NeededElement NeededType $res); 
 
 my $output;
 sub print_fn($) { my $x = shift; $output.=$x; }
@@ -253,3 +253,41 @@ is_deeply($needed, { pull_bla => 1, push_bla => 1, print_bla => 1, print_rep =>
                         pull_bar => 1, push_bar => 1, 
                                     ndr_bar_to_rep => 1, ndr_rep_to_bar => 1});
        
+$res = "";
+Parse::Pidl::Samba4::NDR::Parser::ParseStructPush({
+                       NAME => "mystruct",
+                       TYPE => "STRUCT",
+                       PROPERTIES => {},
+                       ALIGN => 4,
+                       ELEMENTS => [ ]}, "mystruct", "x");
+is($res, "if (ndr_flags & NDR_SCALARS) {
+       NDR_CHECK(ndr_push_align(ndr, 4));
+}
+if (ndr_flags & NDR_BUFFERS) {
+}
+");
+
+$res = "";
+my $e = { 
+       NAME => "el1", 
+       TYPE => "mytype",
+       REPRESENTATION_TYPE => "mytype",
+       PROPERTIES => {},
+       LEVELS => [ 
+               { LEVEL_INDEX => 0, TYPE => "DATA", DATA_TYPE => "mytype" } 
+] };
+Parse::Pidl::Samba4::NDR::Parser::ParseStructPush({
+                       NAME => "mystruct",
+                       TYPE => "STRUCT",
+                       PROPERTIES => {},
+                       ALIGN => 4,
+                       SURROUNDING_ELEMENT => $e,
+                       ELEMENTS => [ $e ]}, "mystruct", "x");
+is($res, "if (ndr_flags & NDR_SCALARS) {
+       NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_string_array_size(ndr, x->el1)));
+       NDR_CHECK(ndr_push_align(ndr, 4));
+       NDR_CHECK(ndr_push_mytype(ndr, NDR_SCALARS, &x->el1));
+}
+if (ndr_flags & NDR_BUFFERS) {
+}
+");