diff options
author | Stefan Metzmacher <metze@samba.org> | 2009-11-20 11:34:53 +0100 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2009-11-20 13:48:35 +0100 |
commit | 4b6c03a108c45793232697d0558a98268028646e (patch) | |
tree | 8b79ff0c9821e96618216c58212f2fcc5a02c1a6 | |
parent | 7153200f21e1f30ba0ca7d629cc2c4e187ba605f (diff) | |
download | samba-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.h | 1 | ||||
-rw-r--r-- | librpc/ndr/ndr.c | 27 |
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; } |