From c463b98c583714ccd02b878f9f968bcf2b5685de Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 17 Aug 2005 01:20:22 +0000 Subject: r9337: defer the checking of array sizes until the end of the function/structure, as the checks might involve variables that have not yet been unmarshalled. This is needed to cope with the correct IDL for the winreg pipe. Jelmer, can you look at this when you get a chance and see if you think this is a reasonable approach? Sorry its wrecks the nice indentation in the generated code. (This used to be commit 127ed0cfe2d210f5e927d3768d5372042d1c070c) --- source4/build/pidl/Parse/Pidl/Samba/NDR/Parser.pm | 57 +++++++++++++++++++++-- 1 file changed, 53 insertions(+), 4 deletions(-) (limited to 'source4/build/pidl') diff --git a/source4/build/pidl/Parse/Pidl/Samba/NDR/Parser.pm b/source4/build/pidl/Parse/Pidl/Samba/NDR/Parser.pm index 4cc0dd9184..87b99c5ef8 100644 --- a/source4/build/pidl/Parse/Pidl/Samba/NDR/Parser.pm +++ b/source4/build/pidl/Parse/Pidl/Samba/NDR/Parser.pm @@ -86,7 +86,11 @@ sub get_value_of($) } my $res = ""; +my $deferred = ""; my $tabs = ""; + +#################################### +# pidl() is our basic output routine sub pidl($) { my $d = shift; @@ -97,6 +101,31 @@ sub pidl($) $res .="\n"; } +#################################### +# defer() is like pidl(), but adds to +# a deferred buffer which is then added to the +# output buffer at the end of the structure/union/function +# This is needed to cope with code that must be pushed back +# to the end of a block of elements +sub defer($) +{ + my $d = shift; + if ($d) { + $deferred .= $tabs; + $deferred .= $d; + } + $deferred .="\n"; +} + +######################################## +# add the deferred content to the current +# output +sub add_deferred() +{ + $res .= $deferred; + $deferred = ""; +} + sub indent() { $tabs .= "\t"; @@ -118,6 +147,18 @@ sub check_null_pointer($) } } +##################################################################### +# check that a variable we get from ParseExpr isn't a null pointer, +# putting the check at the end of the structure/function +sub check_null_pointer_deferred($) +{ + my $size = shift; + if ($size =~ /^\*/) { + my $size2 = substr($size, 1); + defer "if ($size2 == NULL) return NT_STATUS_INVALID_PARAMETER_MIX;"; + } +} + ##################################################################### # check that a variable we get from ParseExpr isn't a null pointer # void return varient @@ -278,14 +319,14 @@ sub ParseArrayPullHeader($$$$$) if ($l->{IS_CONFORMANT} and not $l->{IS_ZERO_TERMINATED}) { my $size = ParseExpr($l->{SIZE_IS}, $env); - check_null_pointer($size); - pidl "NDR_CHECK(ndr_check_array_size(ndr, (void*)" . get_pointer_to($var_name) . ", $size));"; + check_null_pointer_deferred($size); + defer "NDR_CHECK(ndr_check_array_size(ndr, (void*)" . get_pointer_to($var_name) . ", $size));"; } if ($l->{IS_VARYING} and not $l->{IS_ZERO_TERMINATED}) { my $length = ParseExpr($l->{LENGTH_IS}, $env); - check_null_pointer($length); - pidl "NDR_CHECK(ndr_check_array_length(ndr, (void*)" . get_pointer_to($var_name) . ", $length));"; + check_null_pointer_deferred($length); + defer "NDR_CHECK(ndr_check_array_length(ndr, (void*)" . get_pointer_to($var_name) . ", $length));"; } if (!$l->{IS_FIXED}) { @@ -1305,6 +1346,8 @@ sub ParseStructPull($$) deindent; pidl "}"; + add_deferred(); + end_flags($struct); # restore the old relative_base_offset pidl "ndr_pull_restore_relative_base_offset(ndr, _save_relative_base_offset);" if defined($struct->{PROPERTIES}{relative_base}); @@ -1577,6 +1620,9 @@ sub ParseUnionPull($$) deindent; pidl "}"; + + add_deferred(); + end_flags($e); # restore the old relative_base_offset pidl "ndr_pull_restore_relative_base_offset(ndr, _save_relative_base_offset);" if defined($e->{PROPERTIES}{relative_base}); @@ -1892,6 +1938,7 @@ sub ParseFunctionPull($) } } + add_deferred(); deindent; pidl "}"; @@ -1908,8 +1955,10 @@ sub ParseFunctionPull($) pidl "NDR_CHECK(ndr_pull_$fn->{RETURN_TYPE}(ndr, NDR_SCALARS, &r->out.result));"; } + add_deferred(); deindent; pidl "}"; + pidl "return NT_STATUS_OK;"; deindent; pidl "}"; -- cgit