summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2009-11-20 11:34:53 +0100
committerStefan Metzmacher <metze@samba.org>2009-11-20 13:48:35 +0100
commit4b6c03a108c45793232697d0558a98268028646e (patch)
tree8b79ff0c9821e96618216c58212f2fcc5a02c1a6
parent7153200f21e1f30ba0ca7d629cc2c4e187ba605f (diff)
downloadsamba-4b6c03a108c45793232697d0558a98268028646e.tar.gz
samba-4b6c03a108c45793232697d0558a98268028646e.tar.bz2
samba-4b6c03a108c45793232697d0558a98268028646e.zip
librpc/ndr: remember the highest offset we parsed with relative pointer buffers
ndr_*_pull_blob_all() will now work if relative pointers are used. metze
-rw-r--r--librpc/ndr/libndr.h1
-rw-r--r--librpc/ndr/ndr.c27
2 files changed, 22 insertions, 6 deletions
diff --git a/librpc/ndr/libndr.h b/librpc/ndr/libndr.h
index 45cb24405f..e881a5c691 100644
--- a/librpc/ndr/libndr.h
+++ b/librpc/ndr/libndr.h
@@ -62,6 +62,7 @@ struct ndr_pull {
struct smb_iconv_convenience *iconv_convenience;
+ uint32_t relative_highest_offset;
uint32_t relative_base_offset;
struct ndr_token_list *relative_base_list;
diff --git a/librpc/ndr/ndr.c b/librpc/ndr/ndr.c
index cb47ca1d60..1969decb5b 100644
--- a/librpc/ndr/ndr.c
+++ b/librpc/ndr/ndr.c
@@ -861,13 +861,22 @@ _PUBLIC_ enum ndr_err_code ndr_pull_struct_blob_all(const DATA_BLOB *blob, TALLO
void *p, ndr_pull_flags_fn_t fn)
{
struct ndr_pull *ndr;
+ uint32_t highest_ofs;
ndr = ndr_pull_init_blob(blob, mem_ctx, iconv_convenience);
NDR_ERR_HAVE_NO_MEMORY(ndr);
NDR_CHECK_FREE(fn(ndr, NDR_SCALARS|NDR_BUFFERS, p));
- if (ndr->offset < ndr->data_size) {
- return ndr_pull_error(ndr, NDR_ERR_UNREAD_BYTES,
- "not all bytes consumed ofs[%u] size[%u]",
- ndr->offset, ndr->data_size);
+ if (ndr->offset > ndr->relative_highest_offset) {
+ highest_ofs = ndr->offset;
+ } else {
+ highest_ofs = ndr->relative_highest_offset;
+ }
+ if (highest_ofs < ndr->data_size) {
+ enum ndr_err_code ret;
+ ret = ndr_pull_error(ndr, NDR_ERR_UNREAD_BYTES,
+ "not all bytes consumed ofs[%u] size[%u]",
+ highest_ofs, ndr->data_size);
+ talloc_free(ndr);
+ return ret;
}
talloc_free(ndr);
return NDR_ERR_SUCCESS;
@@ -898,15 +907,21 @@ _PUBLIC_ enum ndr_err_code ndr_pull_union_blob_all(const DATA_BLOB *blob, TALLOC
uint32_t level, ndr_pull_flags_fn_t fn)
{
struct ndr_pull *ndr;
+ uint32_t highest_ofs;
ndr = ndr_pull_init_blob(blob, mem_ctx, iconv_convenience);
NDR_ERR_HAVE_NO_MEMORY(ndr);
NDR_CHECK_FREE(ndr_pull_set_switch_value(ndr, p, level));
NDR_CHECK_FREE(fn(ndr, NDR_SCALARS|NDR_BUFFERS, p));
- if (ndr->offset < ndr->data_size) {
+ if (ndr->offset > ndr->relative_highest_offset) {
+ highest_ofs = ndr->offset;
+ } else {
+ highest_ofs = ndr->relative_highest_offset;
+ }
+ if (highest_ofs < ndr->data_size) {
enum ndr_err_code ret;
ret = ndr_pull_error(ndr, NDR_ERR_UNREAD_BYTES,
"not all bytes consumed ofs[%u] size[%u]",
- ndr->offset, ndr->data_size);
+ highest_ofs, ndr->data_size);
talloc_free(ndr);
return ret;
}