summaryrefslogtreecommitdiff
path: root/source4/build
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2004-12-09 07:05:00 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:06:27 -0500
commit74eb0017be0e89df7c0ce0a18a7042dc7d06bfdb (patch)
treef92ef13e0f4712f77852d2ba768e3b8b7d94a0a1 /source4/build
parent22f141166ad8f54282210699921a5de0b8436742 (diff)
downloadsamba-74eb0017be0e89df7c0ce0a18a7042dc7d06bfdb.tar.gz
samba-74eb0017be0e89df7c0ce0a18a7042dc7d06bfdb.tar.bz2
samba-74eb0017be0e89df7c0ce0a18a7042dc7d06bfdb.zip
r4110: fixed pidl to allow arrays to have size_is() and length_is() elements
that depend on variables that come after the array in the structure or function. This has been something that has been problematic for a while, but the winreg QueryValue problem finally prompted me to fix it properly. We should now go back and fix up all the ugly workarounds we have used to avoid this problem in other calls. Unfortunately the solution is fairly complex, and involves the use of the internal ndr token lists (similar to the solution for relative pointers). I wonder if anyone else will be able to follow the logic if I get run over by a bus :-) (This used to be commit e839b19ec5581f669f2a7705b1fb80845313251c)
Diffstat (limited to 'source4/build')
-rw-r--r--source4/build/pidl/parser.pm72
1 files changed, 42 insertions, 30 deletions
diff --git a/source4/build/pidl/parser.pm b/source4/build/pidl/parser.pm
index cec983724d..4461bb77af 100644
--- a/source4/build/pidl/parser.pm
+++ b/source4/build/pidl/parser.pm
@@ -269,6 +269,25 @@ sub ParseArrayPrint($$)
}
#####################################################################
+# check the size_is and length_is constraints
+sub CheckArraySizes($$)
+{
+ my $e = shift;
+ my $var_prefix = shift;
+
+ if (util::has_property($e, "size_is")) {
+ my $size = find_size_var($e, util::array_size($e), $var_prefix);
+ pidl "\tNDR_CHECK(ndr_check_array_size(ndr, (void*)&$var_prefix$e->{NAME}, $size));\n";
+ }
+
+ if (my $length = util::has_property($e, "length_is")) {
+ $length = find_size_var($e, $length, $var_prefix);
+ pidl "\tNDR_CHECK(ndr_check_array_length(ndr, (void*)&$var_prefix$e->{NAME}, $length));\n";
+ }
+}
+
+
+#####################################################################
# parse an array - pull side
sub ParseArrayPull($$$)
{
@@ -294,47 +313,28 @@ sub ParseArrayPull($$$)
}
# non fixed arrays encode the size just before the array
- pidl "\t{\n";
- pidl "\t\tuint32_t _array_size;\n";
- pidl "\t\tNDR_CHECK(ndr_pull_uint32(ndr, &_array_size));\n";
- if ($size =~ /r->in/) {
- pidl "\t\tif (!(ndr->flags & LIBNDR_FLAG_REF_ALLOC) && _array_size != $size) {\n";
- } else {
- pidl "\t\tif ($size != _array_size) {\n";
- }
- pidl "\t\t\treturn ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, \"Bad array size %u should be %u\", _array_size, $size);\n";
- pidl "\t\t}\n";
- if ($size =~ /r->in/) {
- pidl "else { $size = _array_size; }\n";
- }
- pidl "\t}\n";
+ pidl "\t\tNDR_CHECK(ndr_pull_array_size(ndr, &$var_prefix$e->{NAME}));\n";
+ $alloc_size = "ndr_get_array_size(ndr, &$var_prefix$e->{NAME})";
}
if ((util::need_alloc($e) && !util::is_fixed_array($e)) ||
($var_prefix eq "r->in." && util::has_property($e, "ref"))) {
if (!util::is_inline_array($e) || $ndr_flags eq "NDR_SCALARS") {
- pidl "\t\tNDR_ALLOC_N(ndr, $var_prefix$e->{NAME}, MAX(1, $alloc_size));\n";
+ pidl "\t\tNDR_ALLOC_N(ndr, $var_prefix$e->{NAME}, $alloc_size);\n";
}
}
if (($var_prefix eq "r->out." && util::has_property($e, "ref"))) {
if (!util::is_inline_array($e) || $ndr_flags eq "NDR_SCALARS") {
pidl "\tif (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {";
- pidl "\t\tNDR_ALLOC_N(ndr, $var_prefix$e->{NAME}, MAX(1, $alloc_size));\n";
+ pidl "\t\tNDR_ALLOC_N(ndr, $var_prefix$e->{NAME}, $alloc_size);\n";
pidl "\t}\n";
}
}
- pidl "\t{\n";
-
if (my $length = util::has_property($e, "length_is")) {
- $length = find_size_var($e, $length, $var_prefix);
- pidl "\t\tuint32_t _offset, _length;\n";
- pidl "\t\tNDR_CHECK(ndr_pull_uint32(ndr, &_offset));\n";
- pidl "\t\tNDR_CHECK(ndr_pull_uint32(ndr, &_length));\n";
- pidl "\t\tif (_offset != 0) return ndr_pull_error(ndr, NDR_ERR_OFFSET, \"Bad array offset 0x%08x\", _offset);\n";
- pidl "\t\tif (_length > $size || _length != $length) return ndr_pull_error(ndr, NDR_ERR_LENGTH, \"Bad array length 0x%08x > size 0x%08x\", _offset, $size);\n\n";
- $size = "_length";
+ pidl "\t\tNDR_CHECK(ndr_pull_array_length(ndr, &$var_prefix$e->{NAME}));\n";
+ $size = "ndr_get_array_length(ndr, &$var_prefix$e->{NAME})";
}
if (util::is_scalar_type($e->{TYPE})) {
@@ -342,8 +342,6 @@ sub ParseArrayPull($$$)
} else {
pidl "\t\tNDR_CHECK(ndr_pull_array(ndr, $ndr_flags, (void **)$var_prefix$e->{NAME}, sizeof($var_prefix$e->{NAME}\[0]), $size, (ndr_pull_flags_fn_t)ndr_pull_$e->{TYPE}));\n";
}
-
- pidl "\t}\n";
}
@@ -835,6 +833,10 @@ sub ParseStructPull($)
ParseElementPullBuffer($e, "r->", "NDR_BUFFERS");
}
+ foreach my $e (@{$struct->{ELEMENTS}}) {
+ CheckArraySizes($e, "r->");
+ }
+
pidl "\tndr_pull_struct_end(ndr);\n";
pidl "done:\n";
@@ -844,7 +846,6 @@ sub ParseStructPull($)
#####################################################################
# calculate size of ndr struct
-
sub ParseStructNdrSize($)
{
my $t = shift;
@@ -855,7 +856,6 @@ sub ParseStructNdrSize($)
pidl "{\n";
if (util::has_property($t->{DATA}, "flag")) {
-
pidl "\tflags = flags | " . $t->{DATA}->{PROPERTIES}->{flag} . ";\n";
}
@@ -1398,7 +1398,7 @@ sub AllocateRefVars($)
# 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";
+ pidl "\tNDR_ALLOC_N(ndr, r->out.$e->{NAME}, $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 {
@@ -1448,6 +1448,12 @@ sub ParseFunctionPull($)
}
}
+ foreach my $e (@{$fn->{DATA}}) {
+ if (util::has_property($e, "in")) {
+ CheckArraySizes($e, "r->in.");
+ }
+ }
+
pidl "\nndr_out:\n";
pidl "\tif (!(flags & NDR_OUT)) goto done;\n\n";
@@ -1457,6 +1463,12 @@ sub ParseFunctionPull($)
}
}
+ foreach my $e (@{$fn->{DATA}}) {
+ if (util::has_property($e, "out")) {
+ CheckArraySizes($e, "r->out.");
+ }
+ }
+
if ($fn->{RETURN_TYPE} && $fn->{RETURN_TYPE} ne "void") {
pidl "\tNDR_CHECK(ndr_pull_$fn->{RETURN_TYPE}(ndr, &r->out.result));\n";
}