summaryrefslogtreecommitdiff
path: root/source4/pidl/lib/Parse/Pidl/Samba4/NDR
diff options
context:
space:
mode:
Diffstat (limited to 'source4/pidl/lib/Parse/Pidl/Samba4/NDR')
-rw-r--r--source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm96
1 files changed, 71 insertions, 25 deletions
diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm b/source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
index a1bd3e1f96..1e199ba62b 100644
--- a/source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
+++ b/source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
@@ -304,6 +304,51 @@ sub ParseArrayPushHeader($$$$$)
return $length;
}
+sub check_fully_dereferenced($$)
+{
+ my ($element, $env) = @_;
+
+ return sub ($) {
+ my $origvar = shift;
+ my $check = 0;
+
+ # Figure out the number of pointers in $ptr
+ my $expandedvar = $origvar;
+ $expandedvar =~ s/^(\**)//;
+ my $ptr = $1;
+
+ my $var = undef;
+ foreach (keys %$env) {
+ if ($env->{$_} eq $expandedvar) {
+ $var = $_;
+ last;
+ }
+ }
+
+ return($origvar) unless (defined($var));
+ my $e;
+ foreach (@{$element->{PARENT}->{ELEMENTS}}) {
+ if ($_->{NAME} eq $var) {
+ $e = $_;
+ last;
+ }
+ }
+
+ $e or die("Environment doesn't match siblings");
+
+ # See if pointer at pointer level $level
+ # needs to be checked.
+ my $nump = 0;
+ foreach (@{$e->{LEVELS}}) {
+ if ($_->{TYPE} eq "POINTER") {
+ $nump = $_->{POINTER_INDEX}+1;
+ }
+ }
+ warning($element->{ORIGINAL}, "Got pointer for `$e->{NAME}', expected fully derefenced variable") if ($nump > length($ptr));
+ return ($origvar);
+ }
+}
+
sub check_null_pointer($$$$)
{
my ($element, $env, $print_fn, $return) = @_;
@@ -373,8 +418,8 @@ sub ParseArrayPullHeader($$$$$)
} elsif ($l->{IS_ZERO_TERMINATED}) { # Noheader arrays
$length = $size = "ndr_get_string_size($ndr, sizeof(*$var_name))";
} else {
- $length = $size = ParseExprExt($l->{SIZE_IS}, $env, $e,
- check_null_pointer($e, $env, \&pidl, "return NT_STATUS_INVALID_PARAMETER_MIX;"));
+ $length = $size = ParseExprExt($l->{SIZE_IS}, $env, $e->{ORIGINAL},
+ check_null_pointer($e, $env, \&pidl, "return NT_STATUS_INVALID_PARAMETER_MIX;"), check_fully_dereferenced($e, $env));
}
if ((!$l->{IS_SURROUNDING}) and $l->{IS_CONFORMANT}) {
@@ -397,7 +442,7 @@ sub ParseArrayPullHeader($$$$$)
if ($l->{IS_CONFORMANT} and not $l->{IS_ZERO_TERMINATED}) {
defer "if ($var_name) {";
defer_indent;
- my $size = ParseExprExt($l->{SIZE_IS}, $env, $e, check_null_pointer($e, $env, \&defer, "return NT_STATUS_INVALID_PARAMETER_MIX;"));
+ my $size = ParseExprExt($l->{SIZE_IS}, $env, $e->{ORIGINAL}, check_null_pointer($e, $env, \&defer, "return NT_STATUS_INVALID_PARAMETER_MIX;"), check_fully_dereferenced($e, $env));
defer "NDR_CHECK(ndr_check_array_size(ndr, (void*)" . get_pointer_to($var_name) . ", $size));";
defer_deindent;
defer "}";
@@ -406,7 +451,7 @@ sub ParseArrayPullHeader($$$$$)
if ($l->{IS_VARYING} and not $l->{IS_ZERO_TERMINATED}) {
defer "if ($var_name) {";
defer_indent;
- my $length = ParseExprExt($l->{LENGTH_IS}, $env, $e, check_null_pointer($e, $env, \&defer, "return NT_STATUS_INVALID_PARAMETER_MIX;"));
+ my $length = ParseExprExt($l->{LENGTH_IS}, $env, $e->{ORIGINAL}, check_null_pointer($e, $env, \&defer, "return NT_STATUS_INVALID_PARAMETER_MIX;"), check_fully_dereferenced($e, $env));
defer "NDR_CHECK(ndr_check_array_length(ndr, (void*)" . get_pointer_to($var_name) . ", $length));";
defer_deindent;
defer "}"
@@ -432,7 +477,7 @@ sub compression_clen($$$)
my ($e, $l, $env) = @_;
my ($alg, $clen, $dlen) = split(/ /, $l->{COMPRESSION});
- return ParseExpr($clen, $env, $e);
+ return ParseExpr($clen, $env, $e->{ORIGINAL});
}
sub compression_dlen($$$)
@@ -440,7 +485,7 @@ sub compression_dlen($$$)
my ($e,$l,$env) = @_;
my ($alg, $clen, $dlen) = split(/ /, $l->{COMPRESSION});
- return ParseExpr($dlen, $env, $e);
+ return ParseExpr($dlen, $env, $e->{ORIGINAL});
}
sub ParseCompressionPushStart($$$$)
@@ -501,7 +546,7 @@ sub ParseSubcontextPushStart($$$$)
{
my ($e,$l,$ndr,$env) = @_;
my $subndr = "_ndr_$e->{NAME}";
- my $subcontext_size = ParseExpr($l->{SUBCONTEXT_SIZE}, $env, $e);
+ my $subcontext_size = ParseExpr($l->{SUBCONTEXT_SIZE}, $env, $e->{ORIGINAL});
pidl "{";
indent;
@@ -519,7 +564,7 @@ sub ParseSubcontextPushEnd($$$$)
{
my ($e,$l,$ndr,$env) = @_;
my $subndr = "_ndr_$e->{NAME}";
- my $subcontext_size = ParseExpr($l->{SUBCONTEXT_SIZE}, $env, $e);
+ my $subcontext_size = ParseExpr($l->{SUBCONTEXT_SIZE}, $env, $e->{ORIGINAL});
if (defined $l->{COMPRESSION}) {
ParseCompressionPushEnd($e, $l, $subndr, $env);
@@ -534,7 +579,7 @@ sub ParseSubcontextPullStart($$$$)
{
my ($e,$l,$ndr,$env) = @_;
my $subndr = "_ndr_$e->{NAME}";
- my $subcontext_size = ParseExpr($l->{SUBCONTEXT_SIZE}, $env, $e);
+ my $subcontext_size = ParseExpr($l->{SUBCONTEXT_SIZE}, $env, $e->{ORIGINAL});
pidl "{";
indent;
@@ -552,7 +597,7 @@ sub ParseSubcontextPullEnd($$$$)
{
my ($e,$l,$ndr,$env) = @_;
my $subndr = "_ndr_$e->{NAME}";
- my $subcontext_size = ParseExpr($l->{SUBCONTEXT_SIZE}, $env, $e);
+ my $subcontext_size = ParseExpr($l->{SUBCONTEXT_SIZE}, $env, $e->{ORIGINAL});
if (defined $l->{COMPRESSION}) {
ParseCompressionPullEnd($e, $l, $subndr, $env);
@@ -617,7 +662,7 @@ sub ParseElementPushLevel
}
} elsif ($l->{TYPE} eq "ARRAY" and not has_fast_array($e,$l) and
not is_charset_array($e, $l)) {
- my $length = ParseExpr($l->{LENGTH_IS}, $env, $e);
+ my $length = ParseExpr($l->{LENGTH_IS}, $env, $e->{ORIGINAL});
my $counter = "cntr_$e->{NAME}_$l->{LEVEL_INDEX}";
$var_name = $var_name . "[$counter]";
@@ -668,7 +713,7 @@ sub ParseElementPush($$$$$$)
start_flags($e);
if (my $value = has_property($e, "value")) {
- $var_name = ParseExpr($value, $env, $e);
+ $var_name = ParseExpr($value, $env, $e->{ORIGINAL});
}
ParseElementPushLevel($e, $e->{LEVELS}[0], $ndr, $var_name, $env, $primitives, $deferred);
@@ -719,7 +764,7 @@ sub ParseElementPrint($$$)
$var_name = append_prefix($e, $var_name);
if (my $value = has_property($e, "value")) {
- $var_name = "(ndr->flags & LIBNDR_PRINT_SET_VALUES)?" . ParseExpr($value,$env, $e) . ":$var_name";
+ $var_name = "(ndr->flags & LIBNDR_PRINT_SET_VALUES)?" . ParseExpr($value,$env, $e->{ORIGINAL}) . ":$var_name";
}
foreach my $l (@{$e->{LEVELS}}) {
@@ -741,8 +786,8 @@ sub ParseElementPrint($$$)
if ($l->{IS_ZERO_TERMINATED}) {
$length = "ndr_string_length($var_name, sizeof(*$var_name))";
} else {
- $length = ParseExprExt($l->{LENGTH_IS}, $env, $e,
- check_null_pointer($e, $env, \&pidl, "return;"));
+ $length = ParseExprExt($l->{LENGTH_IS}, $env, $e->{ORIGINAL},
+ check_null_pointer($e, $env, \&pidl, "return;"), check_fully_dereferenced($e, $env));
}
if (is_charset_array($e,$l)) {
@@ -772,8 +817,8 @@ sub ParseElementPrint($$$)
}
pidl "ndr_print_$l->{DATA_TYPE}(ndr, \"$e->{NAME}\", $var_name);";
} elsif ($l->{TYPE} eq "SWITCH") {
- my $switch_var = ParseExprExt($l->{SWITCH_IS}, $env, $e,
- check_null_pointer($e, $env, \&pidl, "return;"));
+ my $switch_var = ParseExprExt($l->{SWITCH_IS}, $env, $e->{ORIGINAL},
+ check_null_pointer($e, $env, \&pidl, "return;"), check_fully_dereferenced($e, $env));
pidl "ndr_print_set_switch_value(ndr, " . get_pointer_to($var_name) . ", $switch_var);";
}
}
@@ -803,8 +848,8 @@ sub ParseElementPrint($$$)
sub ParseSwitchPull($$$$$$)
{
my($e,$l,$ndr,$var_name,$ndr_flags,$env) = @_;
- my $switch_var = ParseExprExt($l->{SWITCH_IS}, $env, $e,
- check_null_pointer($e, $env, \&pidl, "return NT_STATUS_INVALID_PARAMETER_MIX;"));
+ my $switch_var = ParseExprExt($l->{SWITCH_IS}, $env, $e->{ORIGINAL},
+ check_null_pointer($e, $env, \&pidl, "return NT_STATUS_INVALID_PARAMETER_MIX;"), check_fully_dereferenced($e, $env));
$var_name = get_pointer_to($var_name);
pidl "NDR_CHECK(ndr_pull_set_switch_value($ndr, $var_name, $switch_var));";
@@ -815,8 +860,8 @@ sub ParseSwitchPull($$$$$$)
sub ParseSwitchPush($$$$$$)
{
my($e,$l,$ndr,$var_name,$ndr_flags,$env) = @_;
- my $switch_var = ParseExprExt($l->{SWITCH_IS}, $env, $e,
- check_null_pointer($e, $env, \&pidl, "return NT_STATUS_INVALID_PARAMETER_MIX;"));
+ my $switch_var = ParseExprExt($l->{SWITCH_IS}, $env, $e->{ORIGINAL},
+ check_null_pointer($e, $env, \&pidl, "return NT_STATUS_INVALID_PARAMETER_MIX;"), check_fully_dereferenced($e, $env));
$var_name = get_pointer_to($var_name);
pidl "NDR_CHECK(ndr_push_set_switch_value($ndr, $var_name, $switch_var));";
@@ -1012,7 +1057,7 @@ sub ParseElementPullLevel
}
} elsif ($l->{TYPE} eq "ARRAY" and
not has_fast_array($e,$l) and not is_charset_array($e, $l)) {
- my $length = ParseExpr($l->{LENGTH_IS}, $env, $e);
+ my $length = ParseExpr($l->{LENGTH_IS}, $env, $e->{ORIGINAL});
my $counter = "cntr_$e->{NAME}_$l->{LEVEL_INDEX}";
my $array_name = $var_name;
@@ -1181,7 +1226,7 @@ sub ParseStructPush($$)
$size = "ndr_string_length(r->$e->{NAME}, sizeof(*r->$e->{NAME}))";
}
} else {
- $size = ParseExpr($e->{LEVELS}[0]->{SIZE_IS}, $env, $e);
+ $size = ParseExpr($e->{LEVELS}[0]->{SIZE_IS}, $env, $e->{ORIGINAL});
}
pidl "NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, $size));";
@@ -2038,7 +2083,7 @@ sub AllocateArrayLevel($$$$$)
{
my ($e,$l,$ndr,$env,$size) = @_;
- my $var = ParseExpr($e->{NAME}, $env, $e);
+ my $var = ParseExpr($e->{NAME}, $env, $e->{ORIGINAL});
my $pl = GetPrevLevel($e, $l);
if (defined($pl) and
@@ -2118,7 +2163,8 @@ sub ParseFunctionPull($)
and $e->{LEVELS}[1]->{IS_ZERO_TERMINATED});
if ($e->{LEVELS}[1]->{TYPE} eq "ARRAY") {
- my $size = ParseExprExt($e->{LEVELS}[1]->{SIZE_IS}, $env, $e, check_null_pointer($e, $env, \&pidl, "return NT_STATUS_INVALID_PARAMETER_MIX;"));
+ my $size = ParseExprExt($e->{LEVELS}[1]->{SIZE_IS}, $env, $e->{ORIGINAL}, check_null_pointer($e, $env, \&pidl, "return NT_STATUS_INVALID_PARAMETER_MIX;"),
+ check_fully_dereferenced($e, $env));
pidl "NDR_PULL_ALLOC_N(ndr, r->out.$e->{NAME}, $size);";