pidl: get the alignment right for uint1632 enums (NDR64)
authorAndrew Tridgell <tridge@samba.org>
Tue, 6 Oct 2009 09:47:09 +0000 (20:47 +1100)
committerAndrew Tridgell <tridge@samba.org>
Tue, 6 Oct 2009 22:56:22 +0000 (09:56 +1100)
The default enum in NDR63 is 32 bits, not 16 bits. We need a uint1632
type to get the alignment right.

librpc/ndr/libndr.h
librpc/ndr/ndr_basic.c
pidl/lib/Parse/Pidl/NDR.pm
pidl/lib/Parse/Pidl/Typelist.pm

index f4c649c41529f1ff987d206595a9e6b33c79dbb6..45cb24405f3c3af0602745098244b2d88893eb99 100644 (file)
@@ -467,6 +467,7 @@ NDR_SCALAR_PROTO(uint8, uint8_t)
 NDR_SCALAR_PROTO(int8, int8_t)
 NDR_SCALAR_PROTO(uint16, uint16_t)
 NDR_SCALAR_PROTO(int16, int16_t)
+NDR_SCALAR_PROTO(uint1632, uint16_t)
 NDR_SCALAR_PROTO(uint32, uint32_t)
 NDR_SCALAR_PROTO(uint3264, uint32_t)
 NDR_SCALAR_PROTO(int32, int32_t)
@@ -549,8 +550,10 @@ struct GUID GUID_random(void);
 _PUBLIC_ enum ndr_err_code ndr_pull_enum_uint8(struct ndr_pull *ndr, int ndr_flags, uint8_t *v);
 _PUBLIC_ enum ndr_err_code ndr_pull_enum_uint16(struct ndr_pull *ndr, int ndr_flags, uint16_t *v);
 _PUBLIC_ enum ndr_err_code ndr_pull_enum_uint32(struct ndr_pull *ndr, int ndr_flags, uint32_t *v);
+_PUBLIC_ enum ndr_err_code ndr_pull_enum_uint1632(struct ndr_pull *ndr, int ndr_flags, uint16_t *v);
 _PUBLIC_ enum ndr_err_code ndr_push_enum_uint8(struct ndr_push *ndr, int ndr_flags, uint8_t v);
 _PUBLIC_ enum ndr_err_code ndr_push_enum_uint16(struct ndr_push *ndr, int ndr_flags, uint16_t v);
 _PUBLIC_ enum ndr_err_code ndr_push_enum_uint32(struct ndr_push *ndr, int ndr_flags, uint32_t v);
+_PUBLIC_ enum ndr_err_code ndr_push_enum_uint1632(struct ndr_push *ndr, int ndr_flags, uint16_t v);
 
 #endif /* __LIBNDR_H__ */
index 1a19cc9327e975838768c2d46eb318bb74fe9caf..64fa5a62998268b8977683b1befde75bdb8fcef9 100644 (file)
@@ -101,6 +101,24 @@ _PUBLIC_ enum ndr_err_code ndr_pull_uint16(struct ndr_pull *ndr, int ndr_flags,
        return NDR_ERR_SUCCESS;
 }
 
+/*
+  parse a uint1632_t
+*/
+_PUBLIC_ enum ndr_err_code ndr_pull_uint1632(struct ndr_pull *ndr, int ndr_flags, uint16_t *v)
+{
+       if (unlikely(ndr->flags & LIBNDR_FLAG_NDR64)) {
+               uint32_t v32 = 0;
+               enum ndr_err_code err = ndr_pull_uint32(ndr, ndr_flags, &v32);
+               *v = v32;
+               if (unlikely(v32 != *v)) {
+                       DEBUG(0,(__location__ ": non-zero upper 16 bits 0x%08x\n", (unsigned)v32));
+                       return NDR_ERR_NDR64;
+               }
+               return err;
+       }
+       return ndr_pull_uint16(ndr, ndr_flags, v);
+}
+
 /*
   parse a int32_t
 */
@@ -282,9 +300,17 @@ _PUBLIC_ enum ndr_err_code ndr_pull_enum_uint8(struct ndr_pull *ndr, int ndr_fla
 }
 
 /*
-  parse a uint16_t enum (uint32_t on NDR64)
+  parse a uint16_t enum
 */
 _PUBLIC_ enum ndr_err_code ndr_pull_enum_uint16(struct ndr_pull *ndr, int ndr_flags, uint16_t *v)
+{
+       return ndr_pull_uint16(ndr, ndr_flags, v);
+}
+
+/*
+  parse a uint1632_t enum (uint32_t on NDR64)
+*/
+_PUBLIC_ enum ndr_err_code ndr_pull_enum_uint1632(struct ndr_pull *ndr, int ndr_flags, uint16_t *v)
 {
        if (unlikely(ndr->flags & LIBNDR_FLAG_NDR64)) {
                uint32_t v32;
@@ -296,11 +322,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_enum_uint16(struct ndr_pull *ndr, int ndr_fl
                }
                return NDR_ERR_SUCCESS;
        }
-       NDR_PULL_ALIGN(ndr, 2);
-       NDR_PULL_NEED_BYTES(ndr, 2);
-       *v = NDR_SVAL(ndr, ndr->offset);
-       ndr->offset += 2;
-       return NDR_ERR_SUCCESS;
+       return ndr_pull_uint16(ndr, ndr_flags, v);
 }
 
 /*
@@ -320,13 +342,10 @@ _PUBLIC_ enum ndr_err_code ndr_push_enum_uint8(struct ndr_push *ndr, int ndr_fla
 }
 
 /*
-  push a uint16_t enum (uint32_t on NDR64)
+  push a uint16_t enum
 */
 _PUBLIC_ enum ndr_err_code ndr_push_enum_uint16(struct ndr_push *ndr, int ndr_flags, uint16_t v)
 {
-       if (unlikely(ndr->flags & LIBNDR_FLAG_NDR64)) {
-               return ndr_push_uint32(ndr, ndr_flags, v);
-       }
        return ndr_push_uint16(ndr, ndr_flags, v);
 }
 
@@ -338,6 +357,16 @@ _PUBLIC_ enum ndr_err_code ndr_push_enum_uint32(struct ndr_push *ndr, int ndr_fl
        return ndr_push_uint32(ndr, ndr_flags, v);
 }
 
+/*
+  push a uint1632_t enum
+*/
+_PUBLIC_ enum ndr_err_code ndr_push_enum_uint1632(struct ndr_push *ndr, int ndr_flags, uint16_t v)
+{
+       if (unlikely(ndr->flags & LIBNDR_FLAG_NDR64)) {
+               return ndr_push_uint32(ndr, ndr_flags, v);
+       }
+       return ndr_push_uint16(ndr, ndr_flags, v);
+}
 
 /*
   push a WERROR
@@ -420,6 +449,17 @@ _PUBLIC_ enum ndr_err_code ndr_push_uint16(struct ndr_push *ndr, int ndr_flags,
        return NDR_ERR_SUCCESS;
 }
 
+/*
+  push a uint1632
+*/
+_PUBLIC_ enum ndr_err_code ndr_push_uint1632(struct ndr_push *ndr, int ndr_flags, uint16_t v)
+{
+       if (unlikely(ndr->flags & LIBNDR_FLAG_NDR64)) {
+               return ndr_push_uint32(ndr, ndr_flags, v);
+       }
+       return ndr_push_uint16(ndr, ndr_flags, v);
+}
+
 /*
   push a int32_t
 */
@@ -452,11 +492,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_uint3264(struct ndr_push *ndr, int ndr_flags
        if (unlikely(ndr->flags & LIBNDR_FLAG_NDR64)) {
                return ndr_push_hyper(ndr, ndr_flags, v);
        }
-       NDR_PUSH_ALIGN(ndr, 4);
-       NDR_PUSH_NEED_BYTES(ndr, 4);
-       NDR_SIVAL(ndr, ndr->offset, v);
-       ndr->offset += 4;
-       return NDR_ERR_SUCCESS;
+       return ndr_push_uint32(ndr, ndr_flags, v);
 }
 
 /*
@@ -536,6 +572,12 @@ _PUBLIC_ enum ndr_err_code ndr_push_align(struct ndr_push *ndr, size_t size)
                } else {
                        size = 4;
                }
+       } else if (size == 3) {
+               if (ndr->flags & LIBNDR_FLAG_NDR64) {
+                       size = 4;
+               } else {
+                       size = 2;
+               }
        }
        NDR_PUSH_ALIGN(ndr, size);
        return NDR_ERR_SUCCESS;
@@ -550,6 +592,12 @@ _PUBLIC_ enum ndr_err_code ndr_pull_align(struct ndr_pull *ndr, size_t size)
                } else {
                        size = 4;
                }
+       } else if (size == 3) {
+               if (ndr->flags & LIBNDR_FLAG_NDR64) {
+                       size = 4;
+               } else {
+                       size = 2;
+               }
        }
        NDR_PULL_ALIGN(ndr, size);
        return NDR_ERR_SUCCESS;
index 48a4ccbc95cc895e337f05a6da8be49060795e1b..249b778389dce45866ea6a4ab4bb1b14c69d723a 100644 (file)
@@ -50,6 +50,8 @@ my $scalar_alignment = {
        'uint8' => 1,
        'int16' => 2,
        'uint16' => 2,
+       'int1632' => 3,
+       'uint1632' => 3,
        'int32' => 4,
        'uint32' => 4,
        'int3264' => 5,
index 55041a9602300f9ab3ec1ab350ed69a19e1f0948..1d82dee833287de4625f0c6f6dbc2673ba3f589c 100644 (file)
@@ -32,6 +32,8 @@ my %scalars = (
        "uint8"         => "uint8_t",
        "int16"         => "int16_t",
        "uint16"        => "uint16_t",
+       "int1632"       => "int16_t",
+       "uint1632"      => "uint16_t",
        "int32"         => "int32_t",
        "uint32"        => "uint32_t",
        "int3264"       => "int32_t",
@@ -222,7 +224,7 @@ sub enum_type_fn($)
        } elsif (has_property($enum->{PARENT}, "v1_enum")) {
                return "uint32";
        }
-       return "uint16";
+       return "uint1632";
 }
 
 sub bitmap_type_fn($)