pidl: add support for [string] on fixed size arrays.
authorStefan Metzmacher <metze@samba.org>
Mon, 27 Jul 2009 13:52:16 +0000 (15:52 +0200)
committerStefan Metzmacher <metze@samba.org>
Mon, 27 Jul 2009 15:51:32 +0000 (17:51 +0200)
midl also supports this:

struct {
long l1;
[string] wchar_t str[16];
long l2;
};

Where the wire size of str is encoded like a length_is() header:
4-byte offset == 0;
4-byte array length;

The strings are zero terminated.

metze

pidl/lib/Parse/Pidl/NDR.pm
pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
pidl/tests/ndr_string.pl

index 95cd4b9dc3deeddd033cc72dd76411ecaa5e5175..8440f0183d9d7e4e003ef01c6c5e6cef208e0223 100644 (file)
@@ -142,6 +142,13 @@ sub GetElementLevelTable($$)
                $is_fixed = 1 if (not $is_conformant and Parse::Pidl::Util::is_constant($size));
                $is_inline = 1 if (not $is_conformant and not Parse::Pidl::Util::is_constant($size));
 
+               if ($i == 0 and $is_fixed and has_property($e, "string")) {
+                       $is_fixed = 0;
+                       $is_varying = 1;
+                       $is_string = 1;
+                       delete($e->{PROPERTIES}->{string});
+               }
+
                push (@$order, {
                        TYPE => "ARRAY",
                        SIZE_IS => $size,
index 7ce9708e148d31a21fa1c3a6aa7fdd958e1d5923..d93661c491e6b225cccb08a8a4b05bf9c8805718 100644 (file)
@@ -326,7 +326,7 @@ sub ParseArrayPullHeader($$$$$$)
 
        if ($l->{IS_CONFORMANT}) {
                $length = $size = "ndr_get_array_size($ndr, " . get_pointer_to($var_name) . ")";
-       } elsif ($l->{IS_ZERO_TERMINATED}) { # Noheader arrays
+       } elsif ($l->{IS_ZERO_TERMINATED} and $l->{SIZE_IS} == 0 and $l->{LENGTH_IS} == 0) { # Noheader arrays
                $length = $size = "ndr_get_string_size($ndr, sizeof(*$var_name))";
        } else {
                $length = $size = ParseExprExt($l->{SIZE_IS}, $env, $e->{ORIGINAL},
index 2f2d941665403ec084ad8d0a7ccf5b6217193ac4..faecbbf4c5f4ce8b10ec89518046e737163310df 100755 (executable)
@@ -4,7 +4,7 @@
 # Published under the GNU General Public License
 use strict;
 
-use Test::More tests => 3 * 8;
+use Test::More tests => 6 * 8;
 use FindBin qw($RealBin);
 use lib "$RealBin";
 use Util qw(test_samba4_ndr);
@@ -55,6 +55,114 @@ test_samba4_ndr("string-ascii-pull",
                return 4;
 ');
 
+test_samba4_ndr("string-wchar-fixed-array-01",
+'
+       typedef struct {
+               uint32 l1;
+               [string,charset(UTF16)] uint16 str[6];
+               uint32 l2;
+       } TestStringStruct;
+
+       [public] void TestString([in,ref] TestStringStruct *str);
+',
+'
+       uint8_t data[] = { 0x01,  0x00, 0x00,  0x00,
+                          0x00,  0x00, 0x00,  0x00,
+                          0x04,  0x00, 0x00,  0x00,
+                          \'f\', 0x00, \'o\', 0x00,
+                          \'o\', 0x00, 0x00,  0x00
+                          0x02,  0x00, 0x00,  0x00
+       };
+       DATA_BLOB b = { data, sizeof(data) };
+       struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL,
+               smb_iconv_convenience_init(NULL, "ASCII", "UTF8", true));
+       struct TestString r;
+       struct TestStringStruct str;
+       r.in.str = &str;
+
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_pull_TestString(ndr, NDR_IN, &r)))
+               return 1;
+
+       if (r.in.str == NULL)
+               return 2;
+
+       if (r.in.str.l1 == 0x00000001)
+               return 3;
+
+       if (strncmp(str.str, "foo", 3) != 0)
+               return 4;
+
+       if (r.in.str.str[4] != 0)
+               return 5;
+
+       if (r.in.str.l3 == 0x00000002)
+               return 6;
+');
+
+test_samba4_ndr("string-wchar-fixed-array-02",
+'
+       typedef struct {
+               uint32 l1;
+               [string,charset(UTF16)] uint16 str[6];
+               uint32 l2;
+       } TestStringStruct;
+
+       [public] void TestString([in,ref] TestStringStruct *str);
+',
+'
+       uint8_t data[] = { 0x01,  0x00, 0x00,  0x00,
+                          0x00,  0x00, 0x00,  0x00,
+                          0x06,  0x00, 0x00,  0x00,
+                          \'f\', 0x00, \'o\', 0x00,
+                          \'o\', 0x00, \'b\', 0x00
+                          \'a\', 0x00, \'r\', 0x00,
+                          0x00,  0x00, 0x00,  0x00
+                          0x02,  0x00, 0x00,  0x00
+       };
+       DATA_BLOB b = { data, sizeof(data) };
+       struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL,
+               smb_iconv_convenience_init(NULL, "ASCII", "UTF8", true));
+       struct TestString r;
+       struct TestStringStruct str;
+       r.in.str = &str;
+
+       /* the string terminator is wrong */
+       if (NDR_ERR_CODE_IS_SUCCESS(ndr_pull_TestString(ndr, NDR_IN, &r)))
+               return 1;
+');
+
+test_samba4_ndr("string-wchar-fixed-array-03",
+'
+       typedef struct {
+               uint32 l1;
+               [string,charset(UTF16)] uint16 str[6];
+               uint32 l2;
+       } TestStringStruct;
+
+       [public] void TestString([in,ref] TestStringStruct *str);
+',
+'
+       uint8_t data[] = { 0x01,  0x00, 0x00,  0x00,
+                          0x00,  0x00, 0x00,  0x00,
+                          0x07,  0x00, 0x00,  0x00,
+                          \'f\', 0x00, \'o\', 0x00,
+                          \'o\', 0x00, \'b\', 0x00
+                          \'a\', 0x00, \'r\', 0x00,
+                          0x00,  0x00, 0x00,  0x00
+                          0x02,  0x00, 0x00,  0x00
+       };
+       DATA_BLOB b = { data, sizeof(data) };
+       struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL,
+               smb_iconv_convenience_init(NULL, "ASCII", "UTF8", true));
+       struct TestString r;
+       struct TestStringStruct str;
+       r.in.str = &str;
+
+       /* the length 0x07 is to large */
+       if (NDR_ERR_CODE_IS_SUCCESS(ndr_pull_TestString(ndr, NDR_IN, &r)))
+               return 1;
+');
+
 SKIP: {
        skip "doesn't seem to work yet", 8;