From 779380df6a9c79bd64045e7c5d0725b5953dc96f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 27 Jul 2009 15:52:16 +0200 Subject: pidl: add support for [string] on fixed size arrays. 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 (cherry picked from commit 7ccc9a6ef563cc855752b4e74152420b9be5af43) (cherry picked from commit 75aeb61c38efe28503991834fb5181537cdffc68) --- pidl/lib/Parse/Pidl/NDR.pm | 7 ++ pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm | 2 +- pidl/tests/ndr_string.pl | 110 ++++++++++++++++++++++++++++++- 3 files changed, 117 insertions(+), 2 deletions(-) diff --git a/pidl/lib/Parse/Pidl/NDR.pm b/pidl/lib/Parse/Pidl/NDR.pm index 5ee26d16b68..6e072a19cc9 100644 --- a/pidl/lib/Parse/Pidl/NDR.pm +++ b/pidl/lib/Parse/Pidl/NDR.pm @@ -141,6 +141,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, diff --git a/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm b/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm index c822d6746e5..c4e3eb7d88c 100644 --- a/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm +++ b/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm @@ -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}, diff --git a/pidl/tests/ndr_string.pl b/pidl/tests/ndr_string.pl index 2f2d9416654..faecbbf4c5f 100755 --- a/pidl/tests/ndr_string.pl +++ b/pidl/tests/ndr_string.pl @@ -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; -- cgit v1.2.1