diff options
-rw-r--r-- | source4/librpc/ndr/ndr_string.c | 15 | ||||
-rw-r--r-- | source4/pidl/lib/Parse/Pidl/Samba/NDR/Parser.pm | 30 |
2 files changed, 30 insertions, 15 deletions
diff --git a/source4/librpc/ndr/ndr_string.c b/source4/librpc/ndr/ndr_string.c index 1a922e2880..96f48edda9 100644 --- a/source4/librpc/ndr/ndr_string.c +++ b/source4/librpc/ndr/ndr_string.c @@ -612,21 +612,24 @@ uint32_t ndr_string_length(const void *_var, uint32_t element_size) return i+1; } -NTSTATUS ndr_check_string_terminator(struct ndr_pull *ndr, const void *_var, uint32_t count, uint32_t element_size) +NTSTATUS ndr_check_string_terminator(struct ndr_pull *ndr, uint32_t count, uint32_t element_size) { - const char *var = _var; uint32_t i; + struct ndr_pull_save save_offset; - var += element_size*(count-1); + ndr_pull_save(ndr, &save_offset); + ndr_pull_advance(ndr, (count - 1) * element_size); + NDR_PULL_NEED_BYTES(ndr, element_size); for (i = 0; i < element_size; i++) { - if (var[i] != 0) { - return NT_STATUS_UNSUCCESSFUL; + if (ndr->data[ndr->offset+i] != 0) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "String terminator not present or outside string boundaries"); } } - return NT_STATUS_OK; + ndr_pull_restore(ndr, &save_offset); + return NT_STATUS_OK; } NTSTATUS ndr_pull_charset(struct ndr_pull *ndr, int ndr_flags, const char **var, uint32_t length, uint8_t byte_mul, int chset) diff --git a/source4/pidl/lib/Parse/Pidl/Samba/NDR/Parser.pm b/source4/pidl/lib/Parse/Pidl/Samba/NDR/Parser.pm index d203c4fa43..0454f90c9a 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba/NDR/Parser.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba/NDR/Parser.pm @@ -923,6 +923,15 @@ sub ParseMemCtxPullEnd($$) pidl "NDR_PULL_SET_MEM_CTX(ndr, $mem_r_ctx, $mem_r_flags);"; } +sub CheckStringTerminator($$$$) +{ + my ($ndr,$e,$l,$length) = @_; + my $nl = GetNextLevel($e, $l); + + # Make sure last element is zero! + pidl "NDR_CHECK(ndr_check_string_terminator($ndr, $length, sizeof($nl->{DATA_TYPE}_t)));"; +} + sub ParseElementPullLevel { my($e,$l,$ndr,$var_name,$env,$primitives,$deferred) = @_; @@ -945,14 +954,16 @@ sub ParseElementPullLevel my $nl = GetNextLevel($e, $l); if (is_charset_array($e,$l)) { + if ($l->{IS_ZERO_TERMINATED}) { + CheckStringTerminator($ndr, $e, $l, $length); + } pidl "NDR_CHECK(ndr_pull_charset($ndr, $ndr_flags, ".get_pointer_to($var_name).", $length, sizeof(" . mapType($nl->{DATA_TYPE}) . "), CH_$e->{PROPERTIES}->{charset}));"; return; } elsif (has_fast_array($e, $l)) { - pidl "NDR_CHECK(ndr_pull_array_$nl->{DATA_TYPE}($ndr, $ndr_flags, $var_name, $length));"; if ($l->{IS_ZERO_TERMINATED}) { - # Make sure last element is zero! - pidl "NDR_CHECK(ndr_check_string_terminator($ndr, $var_name, $length, sizeof(*$var_name)));"; + CheckStringTerminator($ndr,$e,$l,$length); } + pidl "NDR_CHECK(ndr_pull_array_$nl->{DATA_TYPE}($ndr, $ndr_flags, $var_name, $length));"; return; } } elsif ($l->{TYPE} eq "POINTER") { @@ -1002,16 +1013,17 @@ sub ParseElementPullLevel ParseMemCtxPullStart($e,$l, $array_name); if (($primitives and not $l->{IS_DEFERRED}) or ($deferred and $l->{IS_DEFERRED})) { + my $nl = GetNextLevel($e,$l); + + if ($l->{IS_ZERO_TERMINATED}) { + CheckStringTerminator($ndr,$e,$l,$length); + } + pidl "for ($counter = 0; $counter < $length; $counter++) {"; indent; - ParseElementPullLevel($e,GetNextLevel($e,$l), $ndr, $var_name, $env, 1, 0); + ParseElementPullLevel($e, $nl, $ndr, $var_name, $env, 1, 0); deindent; pidl "}"; - - if ($l->{IS_ZERO_TERMINATED}) { - # Make sure last element is zero! - pidl "NDR_CHECK(ndr_check_string_terminator($ndr, $var_name, $length, sizeof(*$var_name)));"; - } } if ($deferred and ContainsDeferred($e, $l)) { |