diff options
author | Stefan Metzmacher <metze@samba.org> | 2016-01-06 13:25:45 +0100 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2016-06-27 05:00:15 +0200 |
commit | 9722f064e71ba960e6c7db8eda0cbadb60e07519 (patch) | |
tree | 1db3ee40311cfdefb954dbea6cd80219b297d145 /librpc/ndr | |
parent | 582f506655e3dd5e51611ac9a8de9f317e87bc16 (diff) | |
download | samba-9722f064e71ba960e6c7db8eda0cbadb60e07519.tar.gz |
librpc/ndr: add support for NDR_ALIGN* to ndr_push_short_relative_ptr2()
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Diffstat (limited to 'librpc/ndr')
-rw-r--r-- | librpc/ndr/ndr.c | 42 |
1 files changed, 36 insertions, 6 deletions
diff --git a/librpc/ndr/ndr.c b/librpc/ndr/ndr.c index f66029ab2cb..78cde20f7d1 100644 --- a/librpc/ndr/ndr.c +++ b/librpc/ndr/ndr.c @@ -1440,9 +1440,44 @@ _PUBLIC_ enum ndr_err_code ndr_push_short_relative_ptr2(struct ndr_push *ndr, co { uint32_t save_offset; uint32_t ptr_offset = 0xFFFF; + uint32_t relative_offset; + size_t pad; + size_t align = 1; + if (p == NULL) { return NDR_ERR_SUCCESS; } + + if (ndr->offset < ndr->relative_base_offset) { + return ndr_push_error(ndr, NDR_ERR_BUFSIZE, + "ndr_push_relative_ptr2 ndr->offset(%u) < ndr->relative_base_offset(%u)", + ndr->offset, ndr->relative_base_offset); + } + + relative_offset = ndr->offset - ndr->relative_base_offset; + + if (ndr->flags & LIBNDR_FLAG_NOALIGN) { + align = 1; + } else if (ndr->flags & LIBNDR_FLAG_ALIGN2) { + align = 2; + } else if (ndr->flags & LIBNDR_FLAG_ALIGN4) { + align = 4; + } else if (ndr->flags & LIBNDR_FLAG_ALIGN8) { + align = 8; + } + + pad = ndr_align_size(relative_offset, align); + if (pad != 0) { + NDR_CHECK(ndr_push_zero(ndr, pad)); + } + + relative_offset = ndr->offset - ndr->relative_base_offset; + if (relative_offset > UINT16_MAX) { + return ndr_push_error(ndr, NDR_ERR_BUFSIZE, + "ndr_push_relative_ptr2 relative_offset(%u) > UINT16_MAX", + relative_offset); + } + save_offset = ndr->offset; NDR_CHECK(ndr_token_retrieve(&ndr->relative_list, p, &ptr_offset)); if (ptr_offset > ndr->offset) { @@ -1451,12 +1486,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_short_relative_ptr2(struct ndr_push *ndr, co ptr_offset, ndr->offset); } ndr->offset = ptr_offset; - if (save_offset < ndr->relative_base_offset) { - return ndr_push_error(ndr, NDR_ERR_BUFSIZE, - "ndr_push_relative_ptr2 save_offset(%u) < ndr->relative_base_offset(%u)", - save_offset, ndr->relative_base_offset); - } - NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, save_offset - ndr->relative_base_offset)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, relative_offset)); ndr->offset = save_offset; return NDR_ERR_SUCCESS; } |