mirror of
https://github.com/samba-team/samba.git
synced 2024-12-28 07:21:54 +03:00
r21455: Fix a bug in our handling of conformant arrays. The conformant array was
always pushed, even if just the buffers part of a struct had to be pushed. Pull was not affected.
This commit is contained in:
parent
426238eb45
commit
ffe3879204
@ -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);
|
||||
|
@ -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) {
|
||||
}
|
||||
");
|
||||
|
Loading…
Reference in New Issue
Block a user