summaryrefslogtreecommitdiff
path: root/librpc/ndr
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2016-01-06 13:25:45 +0100
committerAndrew Bartlett <abartlet@samba.org>2016-06-27 05:00:15 +0200
commit9722f064e71ba960e6c7db8eda0cbadb60e07519 (patch)
tree1db3ee40311cfdefb954dbea6cd80219b297d145 /librpc/ndr
parent582f506655e3dd5e51611ac9a8de9f317e87bc16 (diff)
downloadsamba-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.c42
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;
}