summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/build/pidl/parser.pm54
1 files changed, 47 insertions, 7 deletions
diff --git a/source4/build/pidl/parser.pm b/source4/build/pidl/parser.pm
index b616a85f05..69b878e46e 100644
--- a/source4/build/pidl/parser.pm
+++ b/source4/build/pidl/parser.pm
@@ -1235,6 +1235,40 @@ sub ParseFunctionElementPull($$)
}
}
+
+############################################################
+# allocate ref variables
+sub AllocateRefVars($)
+{
+ my $e = shift;
+ my $asize = util::array_size($e);
+
+ # note that if the variable is also an "in"
+ # variable then we copy the initial value from
+ # the in side
+
+ if (!defined $asize) {
+ # its a simple variable
+ pidl "\tNDR_ALLOC(ndr, r->out.$e->{NAME});\n";
+ if (util::has_property($e, "in")) {
+ pidl "\t*r->out.$e->{NAME} = *r->in.$e->{NAME};\n";
+ } else {
+ pidl "\tZERO_STRUCTP(r->out.$e->{NAME});\n";
+ }
+ return;
+ }
+
+ # its an array
+ my $size = find_size_var($e, $asize, "r->out.");
+ pidl "\tNDR_ALLOC_N(ndr, r->out.$e->{NAME}, MAX(1, $size));\n";
+ if (util::has_property($e, "in")) {
+ pidl "\tmemcpy(r->out.$e->{NAME},r->in.$e->{NAME},$size * sizeof(*r->in.$e->{NAME}));\n";
+ } else {
+ pidl "\tmemset(r->out.$e->{NAME}, 0, $size * sizeof(*r->out.$e->{NAME}));\n";
+ }
+}
+
+
#####################################################################
# parse a function
sub ParseFunctionPull($)
@@ -1253,6 +1287,18 @@ sub ParseFunctionPull($)
}
pidl "\n\tif (!(flags & NDR_IN)) goto ndr_out;\n\n";
+
+ # auto-init the out section of a structure. I originally argued that
+ # this was a bad idea as it hides bugs, but coping correctly
+ # with initialisation and not wiping ref vars is turning
+ # out to be too tricky (tridge)
+ foreach my $e (@{$fn->{DATA}}) {
+ if (util::has_property($e, "out")) {
+ pidl "\tZERO_STRUCT(r->out);\n\n";
+ last;
+ }
+ }
+
foreach my $e (@{$fn->{DATA}}) {
if (util::has_property($e, "in")) {
ParseFunctionElementPull($e, "in");
@@ -1260,13 +1306,7 @@ sub ParseFunctionPull($)
# we need to allocate any reference output variables, so that
# a dcerpc backend can be sure they are non-null
if (util::has_property($e, "out") && util::has_property($e, "ref")) {
- my $asize = util::array_size($e);
- if (defined $asize) {
- my $size = find_size_var($e, $asize, "r->out.");
- pidl "\tNDR_ALLOC_N(ndr, r->out.$e->{NAME}, MAX(1, $size));\n";
- } else {
- pidl "\tNDR_ALLOC(ndr, r->out.$e->{NAME});\n";
- }
+ AllocateRefVars($e);
}
}