summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2009-07-27 15:52:16 +0200
committerKarolin Seeger <kseeger@samba.org>2012-04-10 20:35:23 +0200
commit779380df6a9c79bd64045e7c5d0725b5953dc96f (patch)
tree6b214e912e983bb163e5b1d562b95033dc81a90e
parent1cb51ea4230c655057c157eba10462a2443727b6 (diff)
downloadsamba-779380df6a9c79bd64045e7c5d0725b5953dc96f.tar.gz
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)
-rw-r--r--pidl/lib/Parse/Pidl/NDR.pm7
-rw-r--r--pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm2
-rwxr-xr-xpidl/tests/ndr_string.pl110
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;