From 4b6c03a108c45793232697d0558a98268028646e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Nov 2009 11:34:53 +0100 Subject: 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 --- librpc/ndr/libndr.h | 1 + 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; } -- cgit