summaryrefslogtreecommitdiffstats
path: root/tools/pidl/lib/Parse
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-09-19 04:14:53 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-09-19 04:14:53 +0000
commita86c5f7cae7ec9a3398300555a0b644689d946a1 (patch)
tree39fe4b107c71174fd1e8a8ceb9a4d2aa14116248 /tools/pidl/lib/Parse
parentReleasing progress-linux version 4.2.6-1~progress7.99u1. (diff)
downloadwireshark-a86c5f7cae7ec9a3398300555a0b644689d946a1.tar.xz
wireshark-a86c5f7cae7ec9a3398300555a0b644689d946a1.zip
Merging upstream version 4.4.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--tools/pidl/lib/Parse/Pidl.pm2
-rw-r--r--tools/pidl/lib/Parse/Pidl/CUtil.pm1
-rw-r--r--tools/pidl/lib/Parse/Pidl/Compat.pm1
-rw-r--r--tools/pidl/lib/Parse/Pidl/Dump.pm1
-rw-r--r--tools/pidl/lib/Parse/Pidl/Expr.pm1
-rw-r--r--tools/pidl/lib/Parse/Pidl/IDL.pm30
-rw-r--r--tools/pidl/lib/Parse/Pidl/NDR.pm187
-rw-r--r--tools/pidl/lib/Parse/Pidl/ODL.pm3
-rw-r--r--tools/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm11
-rw-r--r--tools/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm7
-rw-r--r--tools/pidl/lib/Parse/Pidl/Samba4.pm1
-rw-r--r--tools/pidl/lib/Parse/Pidl/Samba4/COM/Header.pm1
-rw-r--r--tools/pidl/lib/Parse/Pidl/Samba4/COM/Proxy.pm3
-rw-r--r--tools/pidl/lib/Parse/Pidl/Samba4/COM/Stub.pm7
-rw-r--r--tools/pidl/lib/Parse/Pidl/Samba4/Header.pm5
-rw-r--r--tools/pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm23
-rw-r--r--tools/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm522
-rw-r--r--tools/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm40
-rw-r--r--tools/pidl/lib/Parse/Pidl/Samba4/NDR/ServerCompat.pm624
-rw-r--r--tools/pidl/lib/Parse/Pidl/Samba4/Python.pm403
-rw-r--r--tools/pidl/lib/Parse/Pidl/Samba4/TDR.pm13
-rw-r--r--tools/pidl/lib/Parse/Pidl/Samba4/Template.pm1
-rw-r--r--tools/pidl/lib/Parse/Pidl/Typelist.pm62
-rw-r--r--tools/pidl/lib/Parse/Pidl/Util.pm38
-rw-r--r--tools/pidl/lib/Parse/Pidl/Wireshark/Conformance.pm1
-rw-r--r--tools/pidl/lib/Parse/Pidl/Wireshark/NDR.pm127
-rw-r--r--tools/pidl/lib/Parse/Yapp/Driver.pm471
27 files changed, 1584 insertions, 1002 deletions
diff --git a/tools/pidl/lib/Parse/Pidl.pm b/tools/pidl/lib/Parse/Pidl.pm
index 40e36739..e4c39b3d 100644
--- a/tools/pidl/lib/Parse/Pidl.pm
+++ b/tools/pidl/lib/Parse/Pidl.pm
@@ -12,7 +12,7 @@ require Exporter;
@EXPORT_OK = qw(warning error fatal $VERSION);
use strict;
-
+use warnings;
use vars qw ( $VERSION );
$VERSION = '0.02';
diff --git a/tools/pidl/lib/Parse/Pidl/CUtil.pm b/tools/pidl/lib/Parse/Pidl/CUtil.pm
index 9deb6ee1..ccd8fcc3 100644
--- a/tools/pidl/lib/Parse/Pidl/CUtil.pm
+++ b/tools/pidl/lib/Parse/Pidl/CUtil.pm
@@ -11,6 +11,7 @@ use vars qw($VERSION);
$VERSION = '0.01';
use strict;
+use warnings;
sub get_pointer_to($)
{
diff --git a/tools/pidl/lib/Parse/Pidl/Compat.pm b/tools/pidl/lib/Parse/Pidl/Compat.pm
index b8abcb88..062a53b8 100644
--- a/tools/pidl/lib/Parse/Pidl/Compat.pm
+++ b/tools/pidl/lib/Parse/Pidl/Compat.pm
@@ -8,6 +8,7 @@ package Parse::Pidl::Compat;
use Parse::Pidl qw(warning);
use Parse::Pidl::Util qw(has_property);
use strict;
+use warnings;
use vars qw($VERSION);
$VERSION = '0.01';
diff --git a/tools/pidl/lib/Parse/Pidl/Dump.pm b/tools/pidl/lib/Parse/Pidl/Dump.pm
index 4e623db6..5d241b81 100644
--- a/tools/pidl/lib/Parse/Pidl/Dump.pm
+++ b/tools/pidl/lib/Parse/Pidl/Dump.pm
@@ -27,6 +27,7 @@ $VERSION = '0.01';
@EXPORT_OK = qw(DumpType DumpTypedef DumpStruct DumpEnum DumpBitmap DumpUnion DumpFunction);
use strict;
+use warnings;
use Parse::Pidl::Util qw(has_property);
my($res);
diff --git a/tools/pidl/lib/Parse/Pidl/Expr.pm b/tools/pidl/lib/Parse/Pidl/Expr.pm
index 24581d29..967d6876 100644
--- a/tools/pidl/lib/Parse/Pidl/Expr.pm
+++ b/tools/pidl/lib/Parse/Pidl/Expr.pm
@@ -10,6 +10,7 @@
package Parse::Pidl::Expr;
use vars qw ( @ISA );
use strict;
+use warnings;
@ISA= qw ( Parse::Yapp::Driver );
use Parse::Yapp::Driver;
diff --git a/tools/pidl/lib/Parse/Pidl/IDL.pm b/tools/pidl/lib/Parse/Pidl/IDL.pm
index 6927c892..46f9813c 100644
--- a/tools/pidl/lib/Parse/Pidl/IDL.pm
+++ b/tools/pidl/lib/Parse/Pidl/IDL.pm
@@ -10,6 +10,7 @@
package Parse::Pidl::IDL;
use vars qw ( @ISA );
use strict;
+use warnings;
@ISA= qw ( Parse::Yapp::Driver );
use Parse::Yapp::Driver;
@@ -2646,12 +2647,29 @@ sub parse_file($$)
undef $/;
my $cpp = $ENV{CPP};
my $options = "";
- if (! defined $cpp) {
- if (defined $ENV{CC}) {
- $cpp = "$ENV{CC}";
- $options = "-E";
- } else {
- $cpp = "cpp";
+ if ($^O eq "MSWin32") {
+ $cpp = "cpp";
+ }else{
+ if (! defined $cpp) {
+ if (defined $ENV{CC}) {
+ $cpp = "$ENV{CC}";
+ $options = "-E";
+ } else {
+ #
+ # If cc is Clang-based don't use cpp, as
+ # at least some versions of Clang, cpp
+ # doesn't strip // comments, but cc -E
+ # does.
+ #
+
+ my $cc_version = `cc --version`;
+ if ($cc_version =~ /clang/) {
+ $cpp = "cc";
+ $options = "-E"
+ } else {
+ $cpp = "cpp";
+ }
+ }
}
}
my $includes = join('',map { " -I$_" } @$incdirs);
diff --git a/tools/pidl/lib/Parse/Pidl/NDR.pm b/tools/pidl/lib/Parse/Pidl/NDR.pm
index 003156e3..18db6cfe 100644
--- a/tools/pidl/lib/Parse/Pidl/NDR.pm
+++ b/tools/pidl/lib/Parse/Pidl/NDR.pm
@@ -38,6 +38,7 @@ $VERSION = '0.01';
@EXPORT_OK = qw(GetElementLevelTable ParseElement ReturnTypeElement ValidElement align_type mapToScalar ParseType can_contain_deferred is_charset_array);
use strict;
+use warnings;
use Parse::Pidl qw(warning fatal);
use Parse::Pidl::Typelist qw(hasType getType typeIs expandAlias mapScalarType is_fixed_size_scalar);
use Parse::Pidl::Util qw(has_property property_matches);
@@ -57,6 +58,7 @@ my $scalar_alignment = {
'int3264' => 5,
'uint3264' => 5,
'hyper' => 8,
+ 'int64' => 8,
'double' => 8,
'pointer' => 8,
'dlong' => 4,
@@ -64,6 +66,7 @@ my $scalar_alignment = {
'udlongr' => 4,
'DATA_BLOB' => 4,
'string' => 4,
+ 'u16string' => 4,
'string_array' => 4, #???
'time_t' => 4,
'uid_t' => 8,
@@ -80,7 +83,10 @@ my $scalar_alignment = {
'ipv4address' => 4,
'ipv6address' => 4, #16?
'dnsp_name' => 1,
- 'dnsp_string' => 1
+ 'dnsp_string' => 1,
+ 'HRESULT' => 4,
+ 'libndr_flags' => 8,
+ 'ndr_flags_type' => 4,
};
sub GetElementLevelTable($$$)
@@ -115,7 +121,7 @@ sub GetElementLevelTable($$$)
warning($e, "[out] argument `$e->{NAME}' not a pointer") if ($needptrs > $e->{POINTERS});
}
- my $allow_pipe = ($e->{PARENT}->{TYPE} eq "FUNCTION");
+ my $allow_pipe = (($e->{PARENT}->{TYPE} // '') eq "FUNCTION");
my $is_pipe = typeIs($e->{TYPE}, "PIPE");
if ($is_pipe) {
@@ -193,7 +199,7 @@ sub GetElementLevelTable($$$)
$length = $size;
}
- if ($e == $e->{PARENT}->{ELEMENTS}[-1]
+ if ($e == $e->{PARENT}->{ELEMENTS}[-1]
and $e->{PARENT}->{TYPE} ne "FUNCTION") {
$is_surrounding = 1;
}
@@ -252,7 +258,7 @@ sub GetElementLevelTable($$$)
$pt = $pointer_default;
}
- push (@$order, {
+ push (@$order, {
TYPE => "POINTER",
POINTER_TYPE => $pt,
POINTER_INDEX => $pointer_idx,
@@ -260,13 +266,13 @@ sub GetElementLevelTable($$$)
LEVEL => $level
});
- warning($e, "top-level \[out\] pointer `$e->{NAME}' is not a \[ref\] pointer")
+ warning($e, "top-level \[out\] pointer `$e->{NAME}' is not a \[ref\] pointer")
if ($i == 1 and $pt ne "ref" and
- $e->{PARENT}->{TYPE} eq "FUNCTION" and
+ $e->{PARENT}->{TYPE} eq "FUNCTION" and
not has_property($e, "in"));
$pointer_idx++;
-
+
# everything that follows will be deferred
$is_deferred = 1 if ($level ne "TOP");
@@ -283,9 +289,9 @@ sub GetElementLevelTable($$$)
$array_length = $array_size;
$is_varying =0;
}
- }
-
- if (scalar(@size_is) == 0 and has_property($e, "string") and
+ }
+
+ if (scalar(@size_is) == 0 and has_property($e, "string") and
$i == $e->{POINTERS}) {
$is_string = 1;
$is_varying = $is_conformant = has_property($e, "noheader")?0:1;
@@ -307,7 +313,7 @@ sub GetElementLevelTable($$$)
});
$is_deferred = 0;
- }
+ }
}
if ($is_pipe) {
@@ -326,10 +332,10 @@ sub GetElementLevelTable($$$)
if (defined(has_property($e, "subcontext"))) {
my $hdr_size = has_property($e, "subcontext");
my $subsize = has_property($e, "subcontext_size");
- if (not defined($subsize)) {
- $subsize = -1;
+ if (not defined($subsize)) {
+ $subsize = -1;
}
-
+
push (@$order, {
TYPE => "SUBCONTEXT",
HEADER_SIZE => $hdr_size,
@@ -341,7 +347,7 @@ sub GetElementLevelTable($$$)
if (my $switch = has_property($e, "switch_is")) {
push (@$order, {
- TYPE => "SWITCH",
+ TYPE => "SWITCH",
SWITCH_IS => $switch,
IS_DEFERRED => $is_deferred
});
@@ -390,11 +396,11 @@ sub GetTypedefLevelTable($$$$)
}
#####################################################################
-# see if a type contains any deferred data
-sub can_contain_deferred($)
+# see if a type contains any deferred data
+sub can_contain_deferred
{
- sub can_contain_deferred($);
- my ($type) = @_;
+ sub can_contain_deferred;
+ my ($type, @types_visited) = @_;
return 1 unless (hasType($type)); # assume the worst
@@ -402,15 +408,29 @@ sub can_contain_deferred($)
return 0 if (Parse::Pidl::Typelist::is_scalar($type));
- return can_contain_deferred($type->{DATA}) if ($type->{TYPE} eq "TYPEDEF");
+ foreach (@types_visited) {
+ if ($_ == $type) {
+ # we have already encountered this
+ # type, avoid recursion loop here
+ # and return
+ return 0;
+ }
+ }
+
+ return can_contain_deferred($type->{DATA},
+ @types_visited) if ($type->{TYPE} eq "TYPEDEF");
return 0 unless defined($type->{ELEMENTS});
foreach (@{$type->{ELEMENTS}}) {
return 1 if ($_->{POINTERS});
- return 1 if (can_contain_deferred ($_->{TYPE}));
+ push(@types_visited,$type);
+ if (can_contain_deferred ($_->{TYPE},@types_visited)) {
+ pop(@types_visited);
+ return 1;
+ }
+ pop(@types_visited);
}
-
return 0;
}
@@ -419,7 +439,7 @@ sub pointer_type($)
my $e = shift;
return undef unless $e->{POINTERS};
-
+
return "ref" if (has_property($e, "ref"));
return "full" if (has_property($e, "ptr"));
return "sptr" if (has_property($e, "sptr"));
@@ -433,25 +453,25 @@ sub pointer_type($)
#####################################################################
# work out the correct alignment for a structure or union
-sub find_largest_alignment($)
+sub find_largest_alignment
{
- my $s = shift;
+ my ($s, @types_visited) = @_;
my $align = 1;
for my $e (@{$s->{ELEMENTS}}) {
my $a = 1;
-
if ($e->{POINTERS}) {
# this is a hack for NDR64
# the NDR layer translates this into
# an alignment of 4 for NDR and 8 for NDR64
$a = 5;
- } elsif (has_property($e, "subcontext")) {
+ } elsif (has_property($e, "subcontext")) {
$a = 1;
} elsif (has_property($e, "transmit_as")) {
- $a = align_type($e->{PROPERTIES}->{transmit_as});
+ $a = align_type($e->{PROPERTIES}->{transmit_as},
+ @types_visited);
} else {
- $a = align_type($e->{TYPE});
+ $a = align_type($e->{TYPE}, @types_visited);
}
$align = $a if ($align < $a);
@@ -462,37 +482,71 @@ sub find_largest_alignment($)
#####################################################################
# align a type
-sub align_type($)
+sub align_type
{
- sub align_type($);
- my ($e) = @_;
-
+ sub align_type;
+ my ($e, @types_visited) = @_;
if (ref($e) eq "HASH" and $e->{TYPE} eq "SCALAR") {
- return $scalar_alignment->{$e->{NAME}};
+ my $ret = $scalar_alignment->{$e->{NAME}};
+ if (not defined $ret) {
+ warning($e, "no scalar alignment for $e->{NAME}!");
+ return 0;
+ }
+ return $ret;
}
return 0 if ($e eq "EMPTY");
unless (hasType($e)) {
- # it must be an external type - all we can do is guess
+ # it must be an external type - all we can do is guess
# warning($e, "assuming alignment of unknown type '$e' is 4");
return 4;
}
-
my $dt = getType($e);
+ foreach (@types_visited) {
+ if ($_ == $dt) {
+ # Chapt 14 of the DCE 1.1: Remote Procedure Call
+ # specification (available from pubs.opengroup.org)
+ # states:
+ # "The alignment of a structure in the octet stream is
+ # the largest of the alignments of the fields it
+ # contains. These fields may also be constructed types.
+ # The same alignment rules apply recursively to
+ # nested constructed types. "
+ #
+ # in the worst case scenario
+ # struct c1 {
+ # membertypea mema;
+ # membertypeb memb;
+ # struct c1 memc;
+ # }
+ # the nested struct c1 memc when encountered
+ # returns 0 ensuring the alignment will be calculated
+ # based on the other fields
+ return 0;
+ }
+ }
+
+
if ($dt->{TYPE} eq "TYPEDEF") {
- return align_type($dt->{DATA});
+ return align_type($dt->{DATA}, @types_visited);
} elsif ($dt->{TYPE} eq "CONFORMANCE") {
return $dt->{DATA}->{ALIGN};
} elsif ($dt->{TYPE} eq "ENUM") {
- return align_type(Parse::Pidl::Typelist::enum_type_fn($dt));
+ return align_type(Parse::Pidl::Typelist::enum_type_fn($dt),
+ @types_visited);
} elsif ($dt->{TYPE} eq "BITMAP") {
- return align_type(Parse::Pidl::Typelist::bitmap_type_fn($dt));
+ return align_type(Parse::Pidl::Typelist::bitmap_type_fn($dt),
+ @types_visited);
} elsif (($dt->{TYPE} eq "STRUCT") or ($dt->{TYPE} eq "UNION")) {
# Struct/union without body: assume 4
return 4 unless (defined($dt->{ELEMENTS}));
- return find_largest_alignment($dt);
+ my $res;
+ push(@types_visited, $dt);
+ $res = find_largest_alignment($dt, @types_visited);
+ pop(@types_visited);
+ return $res
} elsif (($dt->{TYPE} eq "PIPE")) {
return 5;
}
@@ -539,10 +593,10 @@ sub ParseStruct($$$)
CheckPointerTypes($struct, $pointer_default);
- foreach my $x (@{$struct->{ELEMENTS}})
+ foreach my $x (@{$struct->{ELEMENTS}})
{
my $e = ParseElement($x, $pointer_default, $ms_union);
- if ($x != $struct->{ELEMENTS}[-1] and
+ if ($x != $struct->{ELEMENTS}[-1] and
$e->{LEVELS}[0]->{IS_SURROUNDING}) {
fatal($x, "conformant member not at end of struct");
}
@@ -555,7 +609,7 @@ sub ParseStruct($$$)
$surrounding = $e;
}
- if (defined $e->{TYPE} && $e->{TYPE} eq "string"
+ if (defined $e->{TYPE} && Parse::Pidl::Typelist::is_string_type($e->{TYPE})
&& property_matches($e, "flag", ".*LIBNDR_FLAG_STR_CONFORMANT.*")) {
$surrounding = $struct->{ELEMENTS}[-1];
}
@@ -564,7 +618,7 @@ sub ParseStruct($$$)
if ($struct->{NAME}) {
$align = align_type($struct->{NAME});
}
-
+
return {
TYPE => "STRUCT",
NAME => $struct->{NAME},
@@ -601,7 +655,7 @@ sub ParseUnion($$)
CheckPointerTypes($e, $pointer_default);
- foreach my $x (@{$e->{ELEMENTS}})
+ foreach my $x (@{$e->{ELEMENTS}})
{
my $t;
if ($x->{TYPE} eq "EMPTY") {
@@ -793,7 +847,7 @@ sub ParseFunction($$$$)
if ($d->{RETURN_TYPE} ne "void") {
$rettype = expandAlias($d->{RETURN_TYPE});
}
-
+
return {
NAME => $d->{NAME},
TYPE => "FUNCTION",
@@ -885,7 +939,7 @@ sub ParseInterface($)
$version = "0.0";
- if(defined $idl->{PROPERTIES}->{version}) {
+ if(defined $idl->{PROPERTIES}->{version}) {
my @if_version = split(/\./, $idl->{PROPERTIES}->{version});
if ($if_version[0] == $idl->{PROPERTIES}->{version}) {
$version = $idl->{PROPERTIES}->{version};
@@ -901,9 +955,9 @@ sub ParseInterface($)
@endpoints = split /,/, $idl->{PROPERTIES}->{endpoint};
}
- return {
+ return {
NAME => $idl->{NAME},
- UUID => lc(has_property($idl, "uuid")),
+ UUID => lc(has_property($idl, "uuid") // ''),
VERSION => $version,
TYPE => "INTERFACE",
PROPERTIES => $idl->{PROPERTIES},
@@ -925,7 +979,7 @@ sub Parse($)
return undef unless (defined($idl));
Parse::Pidl::NDR::Validate($idl);
-
+
my @ndr = ();
foreach (@{$idl}) {
@@ -997,10 +1051,10 @@ sub ContainsDeferred($$)
while ($l = GetNextLevel($e,$l))
{
- return 1 if ($l->{IS_DEFERRED});
+ return 1 if ($l->{IS_DEFERRED});
return 1 if ($l->{CONTAINS_DEFERRED});
- }
-
+ }
+
return 0;
}
@@ -1094,6 +1148,7 @@ my %property_list = (
"gensize" => ["TYPEDEF", "STRUCT", "UNION"],
"value" => ["ELEMENT"],
"flag" => ["ELEMENT", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP", "PIPE"],
+ "max_recursion" => ["ELEMENT"],
# generic
"public" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP", "PIPE"],
@@ -1252,7 +1307,7 @@ sub ValidElement($)
has_property($e, "relative") or
has_property($e, "relative_short") or
has_property($e, "ref"))) {
- fatal($e, el_name($e) . " : pointer properties on non-pointer element\n");
+ fatal($e, el_name($e) . " : pointer properties on non-pointer element\n");
}
}
@@ -1298,7 +1353,7 @@ sub ValidUnion($)
ValidProperties($union,"UNION");
- if (has_property($union->{PARENT}, "nodiscriminant") and
+ if (has_property($union->{PARENT}, "nodiscriminant") and
has_property($union->{PARENT}, "switch_type")) {
fatal($union->{PARENT}, $union->{PARENT}->{NAME} . ": switch_type(" . $union->{PARENT}->{PROPERTIES}->{switch_type} . ") on union without discriminant");
}
@@ -1308,12 +1363,12 @@ sub ValidUnion($)
foreach my $e (@{$union->{ELEMENTS}}) {
$e->{PARENT} = $union;
- if (defined($e->{PROPERTIES}->{default}) and
+ if (defined($e->{PROPERTIES}->{default}) and
defined($e->{PROPERTIES}->{case})) {
fatal($e, "Union member $e->{NAME} can not have both default and case properties!");
}
-
- unless (defined ($e->{PROPERTIES}->{default}) or
+
+ unless (defined ($e->{PROPERTIES}->{default}) or
defined ($e->{PROPERTIES}->{case})) {
fatal($e, "Union member $e->{NAME} must have default or case property");
}
@@ -1386,7 +1441,7 @@ sub ValidType($)
{
my ($t) = @_;
- {
+ {
TYPEDEF => \&ValidTypedef,
STRUCT => \&ValidStruct,
UNION => \&ValidUnion,
@@ -1410,29 +1465,29 @@ sub ValidInterface($)
ValidProperties($interface,"INTERFACE");
if (has_property($interface, "pointer_default")) {
- if (not grep (/$interface->{PROPERTIES}->{pointer_default}/,
+ if (not grep (/$interface->{PROPERTIES}->{pointer_default}/,
("ref", "unique", "ptr"))) {
fatal($interface, "Unknown default pointer type `$interface->{PROPERTIES}->{pointer_default}'");
}
}
if (has_property($interface, "object")) {
- if (has_property($interface, "version") &&
+ if (has_property($interface, "version") &&
$interface->{PROPERTIES}->{version} != 0) {
fatal($interface, "Object interfaces must have version 0.0 ($interface->{NAME})");
}
- if (!defined($interface->{BASE}) &&
+ if (!defined($interface->{BASE}) &&
not ($interface->{NAME} eq "IUnknown")) {
fatal($interface, "Object interfaces must all derive from IUnknown ($interface->{NAME})");
}
}
-
+
foreach my $d (@{$data}) {
($d->{TYPE} eq "FUNCTION") && ValidFunction($d);
- ($d->{TYPE} eq "TYPEDEF" or
+ ($d->{TYPE} eq "TYPEDEF" or
$d->{TYPE} eq "STRUCT" or
- $d->{TYPE} eq "UNION" or
+ $d->{TYPE} eq "UNION" or
$d->{TYPE} eq "ENUM" or
$d->{TYPE} eq "BITMAP" or
$d->{TYPE} eq "PIPE") && ValidType($d);
@@ -1447,7 +1502,7 @@ sub Validate($)
my($idl) = shift;
foreach my $x (@{$idl}) {
- ($x->{TYPE} eq "INTERFACE") &&
+ ($x->{TYPE} eq "INTERFACE") &&
ValidInterface($x);
($x->{TYPE} eq "IMPORTLIB") &&
fatal($x, "importlib() not supported");
diff --git a/tools/pidl/lib/Parse/Pidl/ODL.pm b/tools/pidl/lib/Parse/Pidl/ODL.pm
index 14e77fa9..0943f3a8 100644
--- a/tools/pidl/lib/Parse/Pidl/ODL.pm
+++ b/tools/pidl/lib/Parse/Pidl/ODL.pm
@@ -1,5 +1,5 @@
##########################################
-# Converts ODL stuctures to IDL structures
+# Converts ODL structures to IDL structures
# (C) 2004-2005, 2008 Jelmer Vernooij <jelmer@samba.org>
package Parse::Pidl::ODL;
@@ -10,6 +10,7 @@ use Parse::Pidl::Util qw(has_property unmake_str);
use Parse::Pidl::Typelist qw(hasType getType);
use File::Basename;
use strict;
+use warnings;
use vars qw($VERSION);
$VERSION = '0.01';
diff --git a/tools/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm b/tools/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm
index 6acf1c5a..816440ef 100644
--- a/tools/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm
+++ b/tools/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm
@@ -6,12 +6,10 @@
# released under the GNU GPL
package Parse::Pidl::Samba3::ClientNDR;
-
-use Exporter;
-@ISA = qw(Exporter);
-@EXPORT_OK = qw(ParseFunction $res $res_hdr);
+use base Parse::Pidl::Base;
use strict;
+use warnings;
use Parse::Pidl qw(fatal warning error);
use Parse::Pidl::Util qw(has_property ParseExpr genpad);
use Parse::Pidl::NDR qw(ContainsPipe);
@@ -19,13 +17,10 @@ use Parse::Pidl::Typelist qw(mapTypeName);
use Parse::Pidl::Samba4 qw(DeclLong);
use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv);
+
use vars qw($VERSION);
$VERSION = '0.01';
-sub indent($) { my ($self) = @_; $self->{tabs}.="\t"; }
-sub deindent($) { my ($self) = @_; $self->{tabs} = substr($self->{tabs}, 1); }
-sub pidl($$) { my ($self,$txt) = @_; $self->{res} .= $txt ? "$self->{tabs}$txt\n" : "\n"; }
-sub pidl_hdr($$) { my ($self, $txt) = @_; $self->{res_hdr} .= "$txt\n"; }
sub fn_declare($$) { my ($self,$n) = @_; $self->pidl($n); $self->pidl_hdr("$n;"); }
sub new($)
diff --git a/tools/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm b/tools/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm
index c87d17a5..2dcc35e7 100644
--- a/tools/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm
+++ b/tools/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm
@@ -11,6 +11,7 @@ use Exporter;
@EXPORT_OK = qw(DeclLevel);
use strict;
+use warnings;
use Parse::Pidl qw(warning error fatal);
use Parse::Pidl::Typelist qw(mapTypeName scalar_is_reference);
use Parse::Pidl::Util qw(ParseExpr has_property is_constant);
@@ -62,11 +63,11 @@ sub AllocOutVar($$$$$$$)
$l = $nl if ($nl->{TYPE} eq "ARRAY");
} elsif
- # we don't support multi-dimentional arrays yet
+ # we don't support multi-dimensional arrays yet
($l->{TYPE} eq "ARRAY") {
my $nl = GetNextLevel($e, $l);
if ($nl->{TYPE} eq "ARRAY") {
- fatal($e->{ORIGINAL},"multi-dimentional [out] arrays are not supported!");
+ fatal($e->{ORIGINAL},"multi-dimensional [out] arrays are not supported!");
}
} else {
# neither pointer nor array, no need to alloc something.
@@ -103,7 +104,7 @@ sub CallWithStruct($$$$$$)
if (grep(/out/, @{$_->{DIRECTION}})) { $hasout = 1; }
}
- pidl "ZERO_STRUCT(r->out);" if ($hasout);
+ pidl "NDR_ZERO_STRUCT(r->out);" if ($hasout);
foreach (@{$fn->{ELEMENTS}}) {
my @dir = @{$_->{DIRECTION}};
diff --git a/tools/pidl/lib/Parse/Pidl/Samba4.pm b/tools/pidl/lib/Parse/Pidl/Samba4.pm
index b720ab90..6b3f2218 100644
--- a/tools/pidl/lib/Parse/Pidl/Samba4.pm
+++ b/tools/pidl/lib/Parse/Pidl/Samba4.pm
@@ -14,6 +14,7 @@ use Parse::Pidl::NDR qw(GetNextLevel);
use Parse::Pidl::Typelist qw(mapTypeName scalar_is_reference);
use Parse::Pidl qw(fatal error);
use strict;
+use warnings;
use vars qw($VERSION);
$VERSION = '0.01';
diff --git a/tools/pidl/lib/Parse/Pidl/Samba4/COM/Header.pm b/tools/pidl/lib/Parse/Pidl/Samba4/COM/Header.pm
index de7d4547..159f4172 100644
--- a/tools/pidl/lib/Parse/Pidl/Samba4/COM/Header.pm
+++ b/tools/pidl/lib/Parse/Pidl/Samba4/COM/Header.pm
@@ -10,6 +10,7 @@ use vars qw($VERSION);
$VERSION = '0.01';
use strict;
+use warnings;
sub GetArgumentProtoList($)
{
diff --git a/tools/pidl/lib/Parse/Pidl/Samba4/COM/Proxy.pm b/tools/pidl/lib/Parse/Pidl/Samba4/COM/Proxy.pm
index 35e6e3f0..1630cf23 100644
--- a/tools/pidl/lib/Parse/Pidl/Samba4/COM/Proxy.pm
+++ b/tools/pidl/lib/Parse/Pidl/Samba4/COM/Proxy.pm
@@ -14,6 +14,7 @@ use vars qw($VERSION);
$VERSION = '0.01';
use strict;
+use warnings;
my($res);
@@ -101,7 +102,7 @@ static $tn dcom_proxy_$interface->{NAME}_$name(struct $interface->{NAME} *d, TAL
return status;
}
- ZERO_STRUCT(r.in.ORPCthis);
+ NDR_ZERO_STRUCT(r.in.ORPCthis);
r.in.ORPCthis.version.MajorVersion = COM_MAJOR_VERSION;
r.in.ORPCthis.version.MinorVersion = COM_MINOR_VERSION;
";
diff --git a/tools/pidl/lib/Parse/Pidl/Samba4/COM/Stub.pm b/tools/pidl/lib/Parse/Pidl/Samba4/COM/Stub.pm
index 239f5baa..71980383 100644
--- a/tools/pidl/lib/Parse/Pidl/Samba4/COM/Stub.pm
+++ b/tools/pidl/lib/Parse/Pidl/Samba4/COM/Stub.pm
@@ -9,6 +9,7 @@ package Parse::Pidl::Samba4::COM::Stub;
use Parse::Pidl::Util qw(has_property);
use strict;
+use warnings;
use vars qw($VERSION);
$VERSION = '0.01';
@@ -125,8 +126,6 @@ static NTSTATUS $name\__op_ndr_pull(struct dcesrv_call_state *dce_call, TALLOC_C
/* unravel the NDR for the packet */
status = dcerpc_table_$name.calls[opnum].ndr_pull(pull, NDR_IN, *r);
if (!NT_STATUS_IS_OK(status)) {
- dcerpc_log_packet(&dcerpc_table_$name, opnum, NDR_IN,
- &dce_call->pkt.u.request.stub_and_verifier);
dce_call->fault_code = DCERPC_FAULT_NDR;
return NT_STATUS_NET_WRITE_FAULT;
}
@@ -152,8 +151,6 @@ pidl "
}
if (dce_call->fault_code != 0) {
- dcerpc_log_packet(&dcerpc_table_$name, opnum, NDR_IN,
- &dce_call->pkt.u.request.stub_and_verifier);
return NT_STATUS_NET_WRITE_FAULT;
}
@@ -175,8 +172,6 @@ pidl "
}
if (dce_call->fault_code != 0) {
- dcerpc_log_packet(&dcerpc_table_$name, opnum, NDR_IN,
- &dce_call->pkt.u.request.stub_and_verifier);
return NT_STATUS_NET_WRITE_FAULT;
}
diff --git a/tools/pidl/lib/Parse/Pidl/Samba4/Header.pm b/tools/pidl/lib/Parse/Pidl/Samba4/Header.pm
index e9b7bee0..a0b002f6 100644
--- a/tools/pidl/lib/Parse/Pidl/Samba4/Header.pm
+++ b/tools/pidl/lib/Parse/Pidl/Samba4/Header.pm
@@ -11,6 +11,7 @@ require Exporter;
@EXPORT_OK = qw(GenerateFunctionInEnv GenerateFunctionOutEnv EnvSubstituteValue GenerateStructEnv);
use strict;
+use warnings;
use Parse::Pidl qw(fatal);
use Parse::Pidl::Typelist qw(mapTypeName scalar_is_reference);
use Parse::Pidl::Util qw(has_property is_constant unmake_str ParseExpr);
@@ -142,7 +143,7 @@ sub HeaderEnum($$;$)
my $count = 0;
my $with_val = 0;
my $without_val = 0;
- pidl " { __do_not_use_enum_$name=0x7FFFFFFF}\n";
+ pidl " { __do_not_use_enum_$name=INT_MAX}\n";
foreach my $e (@{$enum->{ELEMENTS}}) {
my $t = "$e";
my $name;
@@ -493,7 +494,7 @@ sub EnvSubstituteValue($$)
# Substitute the value() values in the env
foreach my $e (@{$s->{ELEMENTS}}) {
next unless (defined(my $v = has_property($e, "value")));
-
+
$env->{$e->{NAME}} = ParseExpr($v, $env, $e);
}
diff --git a/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm b/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm
index 040cd5a4..84e2bebb 100644
--- a/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm
+++ b/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm
@@ -5,10 +5,7 @@
# released under the GNU GPL
package Parse::Pidl::Samba4::NDR::Client;
-
-use Exporter;
-@ISA = qw(Exporter);
-@EXPORT_OK = qw(Parse);
+use parent Parse::Pidl::Base;
use Parse::Pidl qw(fatal warning error);
use Parse::Pidl::Util qw(has_property ParseExpr genpad);
@@ -17,18 +14,14 @@ use Parse::Pidl::Typelist qw(mapTypeName);
use Parse::Pidl::Samba4 qw(choose_header is_intree DeclLong);
use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv);
+
use vars qw($VERSION);
$VERSION = '0.01';
use strict;
+use warnings;
-sub indent($) { my ($self) = @_; $self->{tabs}.="\t"; }
-sub deindent($) { my ($self) = @_; $self->{tabs} = substr($self->{tabs}, 1); }
-sub pidl($$) { my ($self,$txt) = @_; $self->{res} .= $txt ? "$self->{tabs}$txt\n" : "\n"; }
-sub pidl_hdr($$) { my ($self, $txt) = @_; $self->{res_hdr} .= "$txt\n"; }
-sub pidl_both($$) { my ($self, $txt) = @_; $self->{hdr} .= "$txt\n"; $self->{res_hdr} .= "$txt\n"; }
sub fn_declare($$) { my ($self,$n) = @_; $self->pidl($n); $self->pidl_hdr("$n;"); }
-
sub new($)
{
my ($class) = shift;
@@ -496,7 +489,7 @@ sub ParseFunction_Send($$$$)
if (defined($fn->{RETURN_TYPE})) {
$self->pidl("/* Result */");
- $self->pidl("ZERO_STRUCT(state->orig.out.result);");
+ $self->pidl("NDR_ZERO_STRUCT(state->orig.out.result);");
$self->pidl("");
}
@@ -585,7 +578,7 @@ sub ParseFunction_Done($$$$)
}
$self->pidl("/* Reset temporary structure */");
- $self->pidl("ZERO_STRUCT(state->tmp);");
+ $self->pidl("NDR_ZERO_STRUCT(state->tmp);");
$self->pidl("");
$self->pidl("tevent_req_done(req);");
@@ -698,7 +691,7 @@ sub ParseFunction_Sync($$$$)
if (defined($fn->{RETURN_TYPE})) {
$self->pidl("/* Result */");
- $self->pidl("ZERO_STRUCT(r.out.result);");
+ $self->pidl("NDR_ZERO_STRUCT(r.out.result);");
$self->pidl("");
}
@@ -770,8 +763,8 @@ sub ParseFunction($$$)
# TODO: make this fatal at NDR level
if ($e->{LEVELS}[0]->{TYPE} eq "POINTER") {
if ($e->{LEVELS}[1]->{TYPE} eq "DATA" and
- $e->{LEVELS}[1]->{DATA_TYPE} eq "string") {
- $reason = "is a pointer to type 'string'";
+ Parse::Pidl::Typelist::is_string_type($e->{LEVELS}[1]->{DATA_TYPE})) {
+ $reason = "is a pointer to a string type";
} elsif ($e->{LEVELS}[1]->{TYPE} eq "ARRAY" and
$e->{LEVELS}[1]->{IS_ZERO_TERMINATED}) {
next;
diff --git a/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm b/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
index cfcd29e2..d7386d5b 100644
--- a/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
+++ b/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
@@ -6,14 +6,22 @@
# released under the GNU GPL
package Parse::Pidl::Samba4::NDR::Parser;
+use parent Parse::Pidl::Base;
require Exporter;
-@ISA = qw(Exporter);
+push @ISA, qw(Exporter);
@EXPORT_OK = qw(check_null_pointer NeededFunction NeededElement NeededType $res NeededInterface TypeFunctionName ParseElementPrint);
use strict;
-use Parse::Pidl::Typelist qw(hasType getType mapTypeName typeHasBody);
-use Parse::Pidl::Util qw(has_property ParseExpr ParseExprExt print_uuid unmake_str);
+use warnings;
+use Parse::Pidl::Typelist qw(hasType getType mapTypeName mapTypeSpecifier typeHasBody);
+use Parse::Pidl::Util qw(has_property
+ ParseExpr
+ ParseExprExt
+ print_uuid
+ unmake_str
+ parse_int
+ parse_range);
use Parse::Pidl::CUtil qw(get_pointer_to get_value_of get_array_element);
use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred ContainsPipe is_charset_array);
use Parse::Pidl::Samba4 qw(is_intree choose_header ArrayDynamicallyAllocated);
@@ -49,7 +57,7 @@ sub append_prefix($$)
$pointers++;
} elsif ($l->{TYPE} eq "ARRAY") {
$arrays++;
- if (($pointers == 0) and
+ if (($pointers == 0) and
(not $l->{IS_FIXED}) and
(not $l->{IS_INLINE})) {
return get_value_of($var_name);
@@ -60,7 +68,7 @@ sub append_prefix($$)
}
}
}
-
+
return $var_name;
}
@@ -76,28 +84,26 @@ sub has_fast_array($$)
my $t = getType($nl->{DATA_TYPE});
- # Only uint8 and string have fast array functions at the moment
- return ($t->{NAME} eq "uint8") or ($t->{NAME} eq "string");
+ # Only uint8 has a fast array function at the moment
+ return ($t->{NAME} eq "uint8");
}
-
-####################################
-# pidl() is our basic output routine
-sub pidl($$)
+sub is_public_struct
{
- my ($self, $d) = @_;
- if ($d) {
- $self->{res} .= $self->{tabs};
- $self->{res} .= $d;
+ my ($d) = @_;
+ if (!has_property($d, "public")) {
+ return 0;
+ }
+ my $t = $d;
+ if ($d->{TYPE} eq "TYPEDEF") {
+ $t = $d->{DATA};
}
- $self->{res} .="\n";
+ return $t->{TYPE} eq "STRUCT";
}
-sub pidl_hdr($$) { my ($self, $d) = @_; $self->{res_hdr} .= "$d\n"; }
-
####################################
-# defer() is like pidl(), but adds to
-# a deferred buffer which is then added to the
+# defer() is like pidl(), but adds to
+# a deferred buffer which is then added to the
# output buffer at the end of the structure/union/function
# This is needed to cope with code that must be pushed back
# to the end of a block of elements
@@ -123,18 +129,6 @@ sub add_deferred($)
$self->{defer_tabs} = "";
}
-sub indent($)
-{
- my ($self) = @_;
- $self->{tabs} .= "\t";
-}
-
-sub deindent($)
-{
- my ($self) = @_;
- $self->{tabs} = substr($self->{tabs}, 0, -1);
-}
-
#####################################################################
# declare a function public or static, depending on its attributes
sub fn_declare($$$$)
@@ -165,7 +159,7 @@ sub start_flags($$$)
if (defined $flags) {
$self->pidl("{");
$self->indent;
- $self->pidl("uint32_t _flags_save_$e->{TYPE} = $ndr->flags;");
+ $self->pidl("libndr_flags _flags_save_$e->{TYPE} = $ndr->flags;");
$self->pidl("ndr_set_flags(&$ndr->flags, $flags);");
}
}
@@ -241,7 +235,7 @@ sub check_fully_dereferenced($$)
last;
}
}
-
+
return($origvar) unless (defined($var));
my $e;
foreach (@{$element->{PARENT}->{ELEMENTS}}) {
@@ -264,7 +258,7 @@ sub check_fully_dereferenced($$)
warning($element->{ORIGINAL}, "Got pointer for `$e->{NAME}', expected fully dereferenced variable") if ($nump > length($ptr));
return ($origvar);
}
-}
+}
sub check_null_pointer($$$$)
{
@@ -285,7 +279,7 @@ sub check_null_pointer($$$$)
last;
}
}
-
+
if (defined($var)) {
my $e;
# lookup ptr in $e
@@ -301,7 +295,7 @@ sub check_null_pointer($$$$)
# See if pointer at pointer level $level
# needs to be checked.
foreach my $l (@{$e->{LEVELS}}) {
- if ($l->{TYPE} eq "POINTER" and
+ if ($l->{TYPE} eq "POINTER" and
$l->{POINTER_INDEX} == length($ptr)) {
# No need to check ref pointers
$check = ($l->{POINTER_TYPE} ne "ref");
@@ -316,7 +310,7 @@ sub check_null_pointer($$$$)
warning($element, "unknown dereferenced expression `$expandedvar'");
$check = 1;
}
-
+
$print_fn->("if ($ptr$expandedvar == NULL) $return") if $check;
}
}
@@ -346,22 +340,29 @@ sub ParseArrayPullGetSize($$$$$$)
my $size;
- if ($l->{IS_CONFORMANT}) {
- $size = "ndr_get_array_size($ndr, " . get_pointer_to($var_name) . ")";
+ my $array_size = "size_$e->{NAME}_$l->{LEVEL_INDEX}";
+
+ if ($l->{IS_CONFORMANT} and (defined($l->{SIZE_IS}) or not $l->{IS_ZERO_TERMINATED})) {
+ $self->pidl("NDR_CHECK(ndr_get_array_size($ndr, (void*)" . get_pointer_to($var_name) . ", &$array_size));");
+
+ } elsif ($l->{IS_CONFORMANT}) {
+ # This will be the last use of the array_size token
+ $self->pidl("NDR_CHECK(ndr_steal_array_size($ndr, (void*)" . get_pointer_to($var_name) . ", &$array_size));");
+
} elsif ($l->{IS_ZERO_TERMINATED} and $l->{SIZE_IS} == 0 and $l->{LENGTH_IS} == 0) { # Noheader arrays
$size = "ndr_get_string_size($ndr, sizeof(*$var_name))";
+ $self->pidl("$array_size = $size;");
+
} else {
$size = ParseExprExt($l->{SIZE_IS}, $env, $e->{ORIGINAL},
check_null_pointer($e, $env, sub { $self->pidl(shift); },
"return ndr_pull_error($ndr, NDR_ERR_INVALID_POINTER, \"NULL Pointer for size_is()\");"),
check_fully_dereferenced($e, $env));
+ $self->pidl("$array_size = $size;");
}
- $self->pidl("size_$e->{NAME}_$l->{LEVEL_INDEX} = $size;");
- my $array_size = "size_$e->{NAME}_$l->{LEVEL_INDEX}";
-
if (my $range = has_property($e, "range")) {
- my ($low, $high) = split(/,/, $range, 2);
+ my ($low, $high) = parse_range($range);
if ($low < 0) {
warning(0, "$low is invalid for the range of an array size");
}
@@ -370,7 +371,8 @@ sub ParseArrayPullGetSize($$$$$$)
} else {
$self->pidl("if ($array_size < $low || $array_size > $high) {");
}
- $self->pidl("\treturn ndr_pull_error($ndr, NDR_ERR_RANGE, \"value out of range\");");
+ $self->pidl("\treturn ndr_pull_error($ndr, NDR_ERR_RANGE, \"value (%\"PRIu32\") out of range (%\"PRIu32\" - %\"PRIu32\")\", $array_size, (uint32_t)($low), (uint32_t)($high));");
+
$self->pidl("}");
}
@@ -391,12 +393,16 @@ sub ParseArrayPullGetLength($$$$$$;$)
return $array_size;
}
- my $length = "ndr_get_array_length($ndr, " . get_pointer_to($var_name) .")";
- $self->pidl("length_$e->{NAME}_$l->{LEVEL_INDEX} = $length;");
my $array_length = "length_$e->{NAME}_$l->{LEVEL_INDEX}";
+ if ($l->{IS_VARYING} and (defined($l->{LENGTH_IS}) or not $l->{IS_ZERO_TERMINATED})) {
+ $self->pidl("NDR_CHECK(ndr_get_array_length($ndr, (void*)" . get_pointer_to($var_name) . ", &$array_length));");
+ } else {
+ # This will be the last use of the array_length token
+ $self->pidl("NDR_CHECK(ndr_steal_array_length($ndr, (void*)" . get_pointer_to($var_name) . ", &$array_length));");
+ }
if (my $range = has_property($e, "range")) {
- my ($low, $high) = split(/,/, $range, 2);
+ my ($low, $high) = parse_range($range);
if ($low < 0) {
warning(0, "$low is invalid for the range of an array size");
}
@@ -405,7 +411,7 @@ sub ParseArrayPullGetLength($$$$$$;$)
} else {
$self->pidl("if ($array_length < $low || $array_length > $high) {");
}
- $self->pidl("\treturn ndr_pull_error($ndr, NDR_ERR_RANGE, \"value out of range\");");
+ $self->pidl("\treturn ndr_pull_error($ndr, NDR_ERR_RANGE, \"value (%\"PRIu32\") out of range (%\"PRIu32\" - %\"PRIu32\")\", $array_length, (uint32_t)($low), (uint32_t)($high));");
$self->pidl("}");
}
@@ -432,7 +438,7 @@ sub ParseArrayPullHeader($$$$$$)
if ($array_length ne $array_size) {
$self->pidl("if ($array_length > $array_size) {");
$self->indent;
- $self->pidl("return ndr_pull_error($ndr, NDR_ERR_ARRAY_SIZE, \"Bad array size %u should exceed array length %u\", $array_size, $array_length);");
+ $self->pidl("return ndr_pull_error($ndr, NDR_ERR_ARRAY_SIZE, \"Bad array size %\"PRIu32\": should exceed array length %\"PRIu32\"\", $array_size, $array_length);");
$self->deindent;
$self->pidl("}");
}
@@ -444,7 +450,14 @@ sub ParseArrayPullHeader($$$$$$)
check_null_pointer($e, $env, sub { $self->defer(shift); },
"return ndr_pull_error($ndr, NDR_ERR_INVALID_POINTER, \"NULL Pointer for size_is()\");"),
check_fully_dereferenced($e, $env));
- $self->defer("NDR_CHECK(ndr_check_array_size($ndr, (void*)" . get_pointer_to($var_name) . ", $size));");
+ if (ContainsDeferred($e, $l)) {
+ # We will be needing the array_size token in
+ # the NDR_BUFFERS call, so don't steal it now
+ $self->defer("NDR_CHECK(ndr_check_array_size($ndr, (void*)" . get_pointer_to($var_name) . ", $size));");
+ } else {
+ # This will be deferred until after the last ndr_get_array_size()
+ $self->defer("NDR_CHECK(ndr_check_steal_array_size($ndr, (void*)" . get_pointer_to($var_name) . ", $size));");
+ }
$self->defer_deindent;
$self->defer("}");
}
@@ -452,11 +465,12 @@ sub ParseArrayPullHeader($$$$$$)
if ($l->{IS_VARYING} and (defined($l->{LENGTH_IS}) or not $l->{IS_ZERO_TERMINATED})) {
$self->defer("if ($var_name) {");
$self->defer_indent;
- my $length = ParseExprExt($l->{LENGTH_IS}, $env, $e->{ORIGINAL},
+ my $length = ParseExprExt($l->{LENGTH_IS}, $env, $e->{ORIGINAL},
check_null_pointer($e, $env, sub { $self->defer(shift); },
"return ndr_pull_error($ndr, NDR_ERR_INVALID_POINTER, \"NULL Pointer for length_is()\");"),
check_fully_dereferenced($e, $env));
- $self->defer("NDR_CHECK(ndr_check_array_length($ndr, (void*)" . get_pointer_to($var_name) . ", $length));");
+ # This will be deferred until after the last ndr_get_array_length()
+ $self->defer("NDR_CHECK(ndr_check_steal_array_length($ndr, (void*)" . get_pointer_to($var_name) . ", $length));");
$self->defer_deindent;
$self->defer("}");
}
@@ -468,12 +482,12 @@ sub ParseArrayPullHeader($$$$$$)
return $array_length;
}
-sub compression_alg($$)
+sub compression_alg($$$)
{
- my ($e, $l) = @_;
+ my ($e, $l, $env) = @_;
my ($alg, $clen, $dlen) = split(/,/, $l->{COMPRESSION});
- return $alg;
+ return ParseExpr($alg, $env, $e->{ORIGINAL});
}
sub compression_clen($$$)
@@ -496,13 +510,13 @@ sub ParseCompressionPushStart($$$$$)
{
my ($self,$e,$l,$ndr,$env) = @_;
my $comndr = "$ndr\_compressed";
- my $alg = compression_alg($e, $l);
- my $dlen = compression_dlen($e, $l, $env);
+ my $alg = compression_alg($e, $l, $env);
$self->pidl("{");
$self->indent;
$self->pidl("struct ndr_push *$comndr;");
- $self->pidl("NDR_CHECK(ndr_push_compression_start($ndr, &$comndr, $alg, $dlen));");
+ $self->pidl("NDR_CHECK(ndr_push_compression_state_init($ndr, $alg));");
+ $self->pidl("NDR_CHECK(ndr_push_compression_start($ndr, &$comndr));");
return $comndr;
}
@@ -511,10 +525,10 @@ sub ParseCompressionPushEnd($$$$$)
{
my ($self,$e,$l,$ndr,$env) = @_;
my $comndr = "$ndr\_compressed";
- my $alg = compression_alg($e, $l);
- my $dlen = compression_dlen($e, $l, $env);
+ my $alg = compression_alg($e, $l, $env);
- $self->pidl("NDR_CHECK(ndr_push_compression_end($ndr, $comndr, $alg, $dlen));");
+ $self->pidl("NDR_CHECK(ndr_push_compression_end($ndr, $comndr));");
+ $self->pidl("TALLOC_FREE($ndr->cstate);");
$self->deindent;
$self->pidl("}");
}
@@ -523,7 +537,7 @@ sub ParseCompressionPullStart($$$$$)
{
my ($self,$e,$l,$ndr,$env) = @_;
my $comndr = "$ndr\_compressed";
- my $alg = compression_alg($e, $l);
+ my $alg = compression_alg($e, $l, $env);
my $dlen = compression_dlen($e, $l, $env);
my $clen = compression_clen($e, $l, $env);
@@ -539,7 +553,7 @@ sub ParseCompressionPullEnd($$$$$)
{
my ($self,$e,$l,$ndr,$env) = @_;
my $comndr = "$ndr\_compressed";
- my $alg = compression_alg($e, $l);
+ my $alg = compression_alg($e, $l, $env);
my $dlen = compression_dlen($e, $l, $env);
$self->pidl("NDR_CHECK(ndr_pull_compression_end($ndr, $comndr, $alg, $dlen));");
@@ -589,7 +603,8 @@ sub ParseSubcontextPullStart($$$$$)
$self->pidl("{");
$self->indent;
$self->pidl("struct ndr_pull *$subndr;");
- $self->pidl("NDR_CHECK(ndr_pull_subcontext_start($ndr, &$subndr, $l->{HEADER_SIZE}, $subcontext_size));");
+ $self->pidl("ssize_t sub_size = $subcontext_size;");
+ $self->pidl("NDR_CHECK(ndr_pull_subcontext_start($ndr, &$subndr, $l->{HEADER_SIZE}, sub_size));");
if (defined $l->{COMPRESSION}) {
$subndr = $self->ParseCompressionPullStart($e, $l, $subndr, $env);
@@ -608,7 +623,7 @@ sub ParseSubcontextPullEnd($$$$$)
$self->ParseCompressionPullEnd($e, $l, $subndr, $env);
}
- $self->pidl("NDR_CHECK(ndr_pull_subcontext_end($ndr, $subndr, $l->{HEADER_SIZE}, $subcontext_size));");
+ $self->pidl("NDR_CHECK(ndr_pull_subcontext_end($ndr, $subndr, $l->{HEADER_SIZE}, sub_size));");
$self->deindent;
$self->pidl("}");
}
@@ -631,7 +646,7 @@ sub ParseElementPushLevel
} elsif ($l->{TYPE} eq "POINTER") {
$self->ParsePtrPush($e, $l, $ndr, $var_name);
} elsif ($l->{TYPE} eq "ARRAY") {
- my $length = $self->ParseArrayPushHeader($e, $l, $ndr, $var_name, $env);
+ my $length = $self->ParseArrayPushHeader($e, $l, $ndr, $var_name, $env);
my $nl = GetNextLevel($e, $l);
@@ -646,9 +661,7 @@ sub ParseElementPushLevel
} elsif (has_fast_array($e,$l)) {
$self->pidl("NDR_CHECK(ndr_push_array_$nl->{DATA_TYPE}($ndr, $ndr_flags, $var_name, $length));");
return;
- }
- } elsif ($l->{TYPE} eq "SWITCH") {
- $self->ParseSwitchPush($e, $l, $ndr, $var_name, $env);
+ }
} elsif ($l->{TYPE} eq "DATA") {
$self->ParseDataPush($e, $l, $ndr, $var_name, $primitives, $deferred);
} elsif ($l->{TYPE} eq "TYPEDEF") {
@@ -709,6 +722,14 @@ sub ParseElementPushLevel
$self->pidl("}");
}
} elsif ($l->{TYPE} eq "SWITCH") {
+ my $nl = GetNextLevel($e,$l);
+ my $needs_deferred_switch = is_deferred_switch_non_empty($nl);
+
+ # Avoid setting a switch value if it will not be
+ # consumed again in the NDR_BUFFERS pull
+ if ($needs_deferred_switch or !$deferred) {
+ $self->ParseSwitchPush($e, $l, $ndr, $var_name, $env);
+ }
$self->ParseElementPushLevel($e, GetNextLevel($e, $l), $ndr, $var_name, $env, $primitives, $deferred);
}
}
@@ -886,13 +907,13 @@ sub ParseElementPrint($$$$$)
my $length;
if ($l->{IS_CONFORMANT} or $l->{IS_VARYING}) {
- $var_name = get_pointer_to($var_name);
+ $var_name = get_pointer_to($var_name);
}
-
+
if ($l->{IS_ZERO_TERMINATED} and not defined($l->{LENGTH_IS})) {
$length = "ndr_string_length($var_name, sizeof(*$var_name))";
} else {
- $length = ParseExprExt($l->{LENGTH_IS}, $env, $e->{ORIGINAL},
+ $length = ParseExprExt($l->{LENGTH_IS}, $env, $e->{ORIGINAL},
check_null_pointer($e, $env, sub { $self->pidl(shift); }, "return;"), check_fully_dereferenced($e, $env));
}
@@ -906,7 +927,7 @@ sub ParseElementPrint($$$$$)
} else {
my $counter = "cntr_$e->{NAME}_$l->{LEVEL_INDEX}";
- $self->pidl("$ndr->print($ndr, \"\%s: ARRAY(\%d)\", \"$e->{NAME}\", (int)$length);");
+ $self->pidl("$ndr->print($ndr, \"%s: ARRAY(%\"PRIu32\")\", \"$e->{NAME}\", (uint32_t)($length));");
$self->pidl("$ndr->depth++;");
$self->pidl("for ($counter = 0; $counter < ($length); $counter++) {");
$self->indent;
@@ -916,10 +937,10 @@ sub ParseElementPrint($$$$$)
} elsif ($l->{TYPE} eq "DATA") {
$self->ParseDataPrint($e, $l, $ndr, $var_name);
} elsif ($l->{TYPE} eq "SWITCH") {
- my $switch_var = ParseExprExt($l->{SWITCH_IS}, $env, $e->{ORIGINAL},
+ my $switch_var = ParseExprExt($l->{SWITCH_IS}, $env, $e->{ORIGINAL},
check_null_pointer($e, $env, sub { $self->pidl(shift); }, "return;"), check_fully_dereferenced($e, $env));
$self->pidl("ndr_print_set_switch_value($ndr, " . get_pointer_to($var_name) . ", $switch_var);");
- }
+ }
}
foreach my $l (reverse @{$e->{LEVELS}}) {
@@ -956,7 +977,7 @@ sub ParseElementPrint($$$$$)
sub ParseSwitchPull($$$$$$)
{
my($self,$e,$l,$ndr,$var_name,$env) = @_;
- my $switch_var = ParseExprExt($l->{SWITCH_IS}, $env, $e->{ORIGINAL},
+ my $switch_var = ParseExprExt($l->{SWITCH_IS}, $env, $e->{ORIGINAL},
check_null_pointer($e, $env, sub { $self->pidl(shift); },
"return ndr_pull_error($ndr, NDR_ERR_INVALID_POINTER, \"NULL Pointer for switch_is()\");"),
check_fully_dereferenced($e, $env));
@@ -970,7 +991,7 @@ sub ParseSwitchPull($$$$$$)
sub ParseSwitchPush($$$$$$)
{
my($self,$e,$l,$ndr,$var_name,$env) = @_;
- my $switch_var = ParseExprExt($l->{SWITCH_IS}, $env, $e->{ORIGINAL},
+ my $switch_var = ParseExprExt($l->{SWITCH_IS}, $env, $e->{ORIGINAL},
check_null_pointer($e, $env, sub { $self->pidl(shift); },
"return ndr_push_error($ndr, NDR_ERR_INVALID_POINTER, \"NULL Pointer for switch_is()\");"),
check_fully_dereferenced($e, $env));
@@ -993,15 +1014,22 @@ sub ParseDataPull($$$$$$$)
$var_name = get_pointer_to($var_name);
+ if (my $depth = has_property($e, "max_recursion")) {
+ my $d = parse_int($depth);
+ $self->pidl("NDR_RECURSION_CHECK($ndr, $d);");
+ }
$self->pidl("NDR_CHECK(".TypeFunctionName("ndr_pull", $l->{DATA_TYPE})."($ndr, $ndr_flags, $var_name));");
+ if (has_property($e, "max_recursion")) {
+ $self->pidl("NDR_RECURSION_UNWIND($ndr);");
+ }
my $pl = GetPrevLevel($e, $l);
my $range = has_property($e, "range");
- if ($range and $pl->{TYPE} ne "ARRAY") {
+ if ($range and (not $pl or $pl->{TYPE} ne "ARRAY")) {
$var_name = get_value_of($var_name);
my $signed = Parse::Pidl::Typelist::is_signed($l->{DATA_TYPE});
- my ($low, $high) = split(/,/, $range, 2);
+ my ($low, $high) = parse_range($range);
if ($low < 0 and not $signed) {
warning(0, "$low is invalid for the range of an unsigned type");
}
@@ -1010,7 +1038,20 @@ sub ParseDataPull($$$$$$$)
} else {
$self->pidl("if ($var_name < $low || $var_name > $high) {");
}
- $self->pidl("\treturn ndr_pull_error($ndr, NDR_ERR_RANGE, \"value out of range\");");
+
+ my $data_type = mapTypeName($l->{DATA_TYPE});
+ my $fmt = mapTypeSpecifier($data_type);
+
+ if (!defined($fmt)) {
+ if (getType($l->{DATA_TYPE})->{DATA}->{TYPE} eq "ENUM") {
+ $data_type = "int";
+ $fmt = "d";
+ } else {
+ die("Format ($data_type) not supported");
+ }
+ }
+
+ $self->pidl("\treturn ndr_pull_error($ndr, NDR_ERR_RANGE, \"value (%$fmt) out of range (%$fmt - %$fmt)\", ($data_type)($var_name), ($data_type)($low), ($data_type)($high));");
$self->pidl("}");
}
} else {
@@ -1044,14 +1085,14 @@ sub CalcNdrFlags($$$)
my $scalars = 0;
my $buffers = 0;
- # Add NDR_SCALARS if this one is deferred
+ # Add NDR_SCALARS if this one is deferred
# and deferreds may be pushed
$scalars = 1 if ($l->{IS_DEFERRED} and $deferred);
- # Add NDR_SCALARS if this one is not deferred and
+ # Add NDR_SCALARS if this one is not deferred and
# primitives may be pushed
$scalars = 1 if (!$l->{IS_DEFERRED} and $primitives);
-
+
# Add NDR_BUFFERS if this one contains deferred stuff
# and deferreds may be pushed
$buffers = 1 if ($l->{CONTAINS_DEFERRED} and $deferred);
@@ -1079,7 +1120,7 @@ sub ParseMemCtxPullFlags($$$$)
my $nl = GetNextLevel($e, $l);
return undef if ($nl->{TYPE} eq "PIPE");
return undef if ($nl->{TYPE} eq "ARRAY");
- return undef if (($nl->{TYPE} eq "DATA") and ($nl->{DATA_TYPE} eq "string"));
+ return undef if (($nl->{TYPE} eq "DATA") and (Parse::Pidl::Typelist::is_string_type($nl->{DATA_TYPE})));
if ($l->{LEVEL} eq "TOP") {
$mem_flags = "LIBNDR_FLAG_REF_ALLOC";
@@ -1134,7 +1175,7 @@ sub ParseElementPullLevel
if (has_property($e, "skip") or has_property($e, "skip_noinit")) {
$self->pidl("/* [skip] '$var_name' */");
if (not has_property($e, "skip_noinit")) {
- $self->pidl("ZERO_STRUCT($var_name);");
+ $self->pidl("NDR_ZERO_STRUCT($var_name);");
}
return;
}
@@ -1174,8 +1215,6 @@ sub ParseElementPullLevel
}
} elsif ($l->{TYPE} eq "POINTER") {
$self->ParsePtrPull($e, $l, $ndr, $var_name);
- } elsif ($l->{TYPE} eq "SWITCH") {
- $self->ParseSwitchPull($e, $l, $ndr, $var_name, $env);
} elsif ($l->{TYPE} eq "DATA") {
$self->ParseDataPull($e, $l, $ndr, $var_name, $primitives, $deferred);
} elsif ($l->{TYPE} eq "TYPEDEF") {
@@ -1217,7 +1256,7 @@ sub ParseElementPullLevel
$self->deindent;
$self->pidl("}");
}
- } elsif ($l->{TYPE} eq "ARRAY" and
+ } elsif ($l->{TYPE} eq "ARRAY" and
not has_fast_array($e,$l) and not is_charset_array($e, $l)) {
my $length = $array_length;
my $counter = "cntr_$e->{NAME}_$l->{LEVEL_INDEX}";
@@ -1247,16 +1286,28 @@ sub ParseElementPullLevel
if ($deferred and ContainsDeferred($e, $l)) {
$self->pidl("for ($counter = 0; $counter < ($length); $counter++) {");
+ $self->defer("for ($counter = 0; $counter < ($length); $counter++) {");
+ $self->defer_indent;
$self->indent;
$self->ParseElementPullLevel($e,GetNextLevel($e,$l), $ndr, $var_name, $env, 0, 1);
$self->deindent;
+ $self->defer_deindent;
$self->pidl("}");
+ $self->defer("}");
}
$self->ParseMemCtxPullEnd($e, $l, $ndr);
} elsif ($l->{TYPE} eq "SWITCH") {
- $self->ParseElementPullLevel($e, GetNextLevel($e,$l), $ndr, $var_name, $env, $primitives, $deferred);
+ my $nl = GetNextLevel($e,$l);
+ my $needs_deferred_switch = is_deferred_switch_non_empty($nl);
+
+ # Avoid setting a switch value if it will not be
+ # consumed again in the NDR_BUFFERS pull
+ if ($needs_deferred_switch or !$deferred) {
+ $self->ParseSwitchPull($e, $l, $ndr, $var_name, $env);
+ }
+ $self->ParseElementPullLevel($e, $nl, $ndr, $var_name, $env, $primitives, $deferred);
}
}
@@ -1307,21 +1358,21 @@ sub ParsePtrPull($$$$$)
my $nl = GetNextLevel($e, $l);
my $next_is_array = ($nl->{TYPE} eq "ARRAY");
- my $next_is_string = (($nl->{TYPE} eq "DATA") and
- ($nl->{DATA_TYPE} eq "string"));
+ my $next_is_string = (($nl->{TYPE} eq "DATA") and
+ (Parse::Pidl::Typelist::is_string_type($nl->{DATA_TYPE})));
if ($l->{POINTER_TYPE} eq "ref" and $l->{LEVEL} eq "TOP") {
if (!$next_is_array and !$next_is_string) {
$self->pidl("if ($ndr->flags & LIBNDR_FLAG_REF_ALLOC) {");
- $self->pidl("\tNDR_PULL_ALLOC($ndr, $var_name);");
+ $self->pidl("\tNDR_PULL_ALLOC($ndr, $var_name);");
$self->pidl("}");
}
return;
} elsif ($l->{POINTER_TYPE} eq "ref" and $l->{LEVEL} eq "EMBEDDED") {
$self->pidl("NDR_CHECK(ndr_pull_ref_ptr($ndr, &_ptr_$e->{NAME}));");
- } elsif (($l->{POINTER_TYPE} eq "unique") or
+ } elsif (($l->{POINTER_TYPE} eq "unique") or
($l->{POINTER_TYPE} eq "relative") or
($l->{POINTER_TYPE} eq "full")) {
$self->pidl("NDR_CHECK(ndr_pull_generic_ptr($ndr, &_ptr_$e->{NAME}));");
@@ -1343,10 +1394,10 @@ sub ParsePtrPull($$$$$)
# allocation, as we forced it to NULL just above, and
# we may not know the declared type anyway.
} else {
- # Don't do this for arrays, they're allocated at the actual level
+ # Don't do this for arrays, they're allocated at the actual level
# of the array
- unless ($next_is_array or $next_is_string) {
- $self->pidl("NDR_PULL_ALLOC($ndr, $var_name);");
+ unless ($next_is_array or $next_is_string) {
+ $self->pidl("NDR_PULL_ALLOC($ndr, $var_name);");
} else {
# FIXME: Yes, this is nasty.
# We allocate an array twice
@@ -1398,10 +1449,10 @@ sub ParseStructPushPrimitives($$$$$)
if (defined($struct->{SURROUNDING_ELEMENT})) {
my $e = $struct->{SURROUNDING_ELEMENT};
- if (defined($e->{LEVELS}[0]) and
+ if (defined($e->{LEVELS}[0]) and
$e->{LEVELS}[0]->{TYPE} eq "ARRAY") {
my $size;
-
+
if ($e->{LEVELS}[0]->{IS_ZERO_TERMINATED}) {
if (has_property($e, "charset")) {
$size = "ndr_charset_length($varname->$e->{NAME}, CH_$e->{PROPERTIES}->{charset})";
@@ -1450,7 +1501,7 @@ sub ParseStructPushDeferred($$$$)
sub ParseStructPush($$$$)
{
my ($self, $struct, $ndr, $varname) = @_;
-
+
return unless defined($struct->{ELEMENTS});
my $env = GenerateStructEnv($struct, $varname);
@@ -1530,7 +1581,7 @@ sub ParseEnumPrint($$$$$)
$self->deindent;
$self->pidl("}");
-
+
$self->pidl("ndr_print_enum($ndr, name, \"$enum->{TYPE}\", val, $varname);");
$self->end_flags($enum, $ndr);
@@ -1539,7 +1590,7 @@ sub ParseEnumPrint($$$$$)
sub DeclEnum($$$$)
{
my ($e,$t,$name,$varname) = @_;
- return "enum $name " .
+ return "enum $name " .
($t eq "pull"?"*":"") . $varname;
}
@@ -1622,7 +1673,7 @@ sub ParseBitmapPrint($$$$$)
sub DeclBitmap($$$$)
{
my ($e,$t,$name,$varname) = @_;
- return mapTypeName(Parse::Pidl::Typelist::bitmap_type_fn($e)) .
+ return mapTypeName(Parse::Pidl::Typelist::bitmap_type_fn($e)) .
($t eq "pull"?" *":" ") . $varname;
}
@@ -1651,7 +1702,7 @@ sub ParseStructPrint($$$$$)
$self->start_flags($struct, $ndr);
$self->pidl("$ndr->depth++;");
-
+
$self->ParseElementPrint($_, $ndr, $env->{$_->{NAME}}, $env)
foreach (@{$struct->{ELEMENTS}});
$self->pidl("$ndr->depth--;");
@@ -1669,7 +1720,7 @@ sub DeclarePtrVariables($$)
foreach my $l (@{$e->{LEVELS}}) {
my $size = 32;
- if ($l->{TYPE} eq "POINTER" and
+ if ($l->{TYPE} eq "POINTER" and
not ($l->{POINTER_TYPE} eq "ref" and $l->{LEVEL} eq "TOP")) {
if ($l->{POINTER_TYPE} eq "relative_short") {
$size = 16;
@@ -1833,13 +1884,16 @@ sub ParseStructNdrSize($$$$)
sub DeclStruct($$$$)
{
my ($e,$t,$name,$varname) = @_;
+ if ($t eq "base") {
+ return "struct $name $varname";
+ }
return ($t ne "pull"?"const ":"") . "struct $name *$varname";
}
sub ArgsStructNdrSize($$$)
{
my ($d, $name, $varname) = @_;
- return "const struct $name *$varname, int flags";
+ return "const struct $name *$varname, libndr_flags flags";
}
$typefamily{STRUCT} = {
@@ -1871,8 +1925,6 @@ sub ParseUnionPushPrimitives($$$$)
my $have_default = 0;
- $self->pidl("uint32_t level = ndr_push_get_switch_value($ndr, $varname);");
-
if (defined($e->{SWITCH_TYPE})) {
if (defined($e->{ALIGN})) {
$self->pidl("NDR_CHECK(ndr_push_union_align($ndr, $e->{ALIGN}));");
@@ -1917,7 +1969,7 @@ sub ParseUnionPushPrimitives($$$$)
}
if (! $have_default) {
$self->pidl("default:");
- $self->pidl("\treturn ndr_push_error($ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u at \%s\", level, __location__);");
+ $self->pidl("\treturn ndr_push_error($ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value %\"PRIu32, level);");
}
$self->deindent;
$self->pidl("}");
@@ -1929,7 +1981,6 @@ sub ParseUnionPushDeferred($$$$)
my $have_default = 0;
- $self->pidl("uint32_t level = ndr_push_get_switch_value($ndr, $varname);");
if (defined($e->{PROPERTIES}{relative_base})) {
# retrieve the current offset as base for relative pointers
# based on the toplevel struct/union
@@ -1953,7 +2004,7 @@ sub ParseUnionPushDeferred($$$$)
}
if (! $have_default) {
$self->pidl("default:");
- $self->pidl("\treturn ndr_push_error($ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u at \%s\", level, __location__);");
+ $self->pidl("\treturn ndr_push_error($ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value %\"PRIu32, level);");
}
$self->deindent;
$self->pidl("}");
@@ -1966,17 +2017,28 @@ sub ParseUnionPush($$$$)
my ($self,$e,$ndr,$varname) = @_;
my $have_default = 0;
+ $self->pidl("uint32_t level;");
$self->start_flags($e, $ndr);
$self->pidl("NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);");
$self->pidl("if (ndr_flags & NDR_SCALARS) {");
$self->indent;
+ $self->pidl("/* This token is not used again (except perhaps below in the NDR_BUFFERS case) */");
+ $self->pidl("NDR_CHECK(ndr_push_steal_switch_value($ndr, $varname, &level));");
+
$self->ParseUnionPushPrimitives($e, $ndr, $varname);
$self->deindent;
$self->pidl("}");
if (is_deferred_switch_non_empty($e)) {
$self->pidl("if (ndr_flags & NDR_BUFFERS) {");
$self->indent;
+ # In case we had ndr_flags of NDR_SCALERS|NDR_BUFFERS
+ $self->pidl("if (!(ndr_flags & NDR_SCALARS)) {");
+ $self->indent;
+ $self->pidl("/* We didn't get it above, and the token is not needed after this. */");
+ $self->pidl("NDR_CHECK(ndr_push_steal_switch_value($ndr, $varname, &level));");
+ $self->deindent;
+ $self->pidl("}");
$self->ParseUnionPushDeferred($e, $ndr, $varname);
$self->deindent;
$self->pidl("}");
@@ -1998,7 +2060,7 @@ sub ParseUnionPrint($$$$$)
$self->start_flags($e, $ndr);
- $self->pidl("level = ndr_print_get_switch_value($ndr, $varname);");
+ $self->pidl("level = ndr_print_steal_switch_value($ndr, $varname);");
$self->pidl("ndr_print_union($ndr, name, level, \"$name\");");
@@ -2038,9 +2100,17 @@ sub ParseUnionPullPrimitives($$$$$)
$self->pidl("NDR_CHECK(ndr_pull_union_align($ndr, $e->{ALIGN}));");
}
+ my $data_type = mapTypeName($switch_type);
+ my $fmt = mapTypeSpecifier($data_type);
+
+ if (!defined($fmt)) {
+ $data_type = "int";
+ $fmt = "%d";
+ }
+
$self->pidl("NDR_CHECK(ndr_pull_$switch_type($ndr, NDR_SCALARS, &_level));");
- $self->pidl("if (_level != level) {");
- $self->pidl("\treturn ndr_pull_error($ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value %u for $varname at \%s\", _level, __location__);");
+ $self->pidl("if (_level != level) {");
+ $self->pidl("\treturn ndr_pull_error($ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value %$fmt for $varname at \%s\", ($data_type)_level, __location__);");
$self->pidl("}");
}
@@ -2058,7 +2128,7 @@ sub ParseUnionPullPrimitives($$$$$)
foreach my $el (@{$e->{ELEMENTS}}) {
if ($el->{CASE} eq "default") {
$have_default = 1;
- }
+ }
$self->pidl("$el->{CASE}: {");
if ($el->{TYPE} ne "EMPTY") {
@@ -2077,7 +2147,7 @@ sub ParseUnionPullPrimitives($$$$$)
}
if (! $have_default) {
$self->pidl("default:");
- $self->pidl("\treturn ndr_pull_error($ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u at \%s\", level, __location__);");
+ $self->pidl("\treturn ndr_pull_error($ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value %\"PRIu32\" at %s\", level, __location__);");
}
$self->deindent;
$self->pidl("}");
@@ -2088,21 +2158,21 @@ sub ParseUnionPullDeferred($$$$)
my ($self,$e,$ndr,$varname) = @_;
my $have_default = 0;
- if (defined($e->{PROPERTIES}{relative_base})) {
- # retrieve the current offset as base for relative pointers
- # based on the toplevel struct/union
- $self->pidl("NDR_CHECK(ndr_pull_setup_relative_base_offset2($ndr, $varname));");
- }
$self->pidl("switch (level) {");
$self->indent;
foreach my $el (@{$e->{ELEMENTS}}) {
if ($el->{CASE} eq "default") {
$have_default = 1;
- }
+ }
$self->pidl("$el->{CASE}:");
if ($el->{TYPE} ne "EMPTY") {
$self->indent;
+ if (defined($e->{PROPERTIES}{relative_base})) {
+ # retrieve the current offset as base for relative pointers
+ # based on the toplevel struct/union
+ $self->pidl("NDR_CHECK(ndr_pull_setup_relative_base_offset2($ndr, $varname));");
+ }
$self->ParseElementPull($el, $ndr, {$el->{NAME} => "$varname->$el->{NAME}"}, 0, 1);
$self->deindent;
}
@@ -2111,7 +2181,7 @@ sub ParseUnionPullDeferred($$$$)
}
if (! $have_default) {
$self->pidl("default:");
- $self->pidl("\treturn ndr_pull_error($ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u at \%s\", level, __location__);");
+ $self->pidl("\treturn ndr_pull_error($ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value %\"PRIu32\" at %s\", level, __location__);");
}
$self->deindent;
$self->pidl("}");
@@ -2149,20 +2219,21 @@ sub ParseUnionPull($$$$)
$self->pidl("NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);");
$self->pidl("if (ndr_flags & NDR_SCALARS) {");
$self->indent;
- if (! $needs_deferred_switch) {
- $self->pidl("/* This token is not used again */");
- $self->pidl("level = ndr_pull_steal_switch_value($ndr, $varname);");
- } else {
- $self->pidl("level = ndr_pull_get_switch_value($ndr, $varname);");
- }
+ $self->pidl("/* This token is not used again (except perhaps below in the NDR_BUFFERS case) */");
+ $self->pidl("NDR_CHECK(ndr_pull_steal_switch_value($ndr, $varname, &level));");
$self->ParseUnionPullPrimitives($e,$ndr,$varname,$switch_type);
$self->deindent;
$self->pidl("}");
if ($needs_deferred_switch) {
$self->pidl("if (ndr_flags & NDR_BUFFERS) {");
$self->indent;
- $self->pidl("/* The token is not needed after this. */");
- $self->pidl("level = ndr_pull_steal_switch_value($ndr, $varname);");
+ # In case we had ndr_flags of NDR_SCALERS|NDR_BUFFERS
+ $self->pidl("if (!(ndr_flags & NDR_SCALARS)) {");
+ $self->indent;
+ $self->pidl("/* We didn't get it above, and the token is not needed after this. */");
+ $self->pidl("NDR_CHECK(ndr_pull_steal_switch_value($ndr, $varname, &level));");
+ $self->deindent;
+ $self->pidl("}");
$self->ParseUnionPullDeferred($e,$ndr,$varname);
$self->deindent;
$self->pidl("}");
@@ -2175,13 +2246,16 @@ sub ParseUnionPull($$$$)
sub DeclUnion($$$$)
{
my ($e,$t,$name,$varname) = @_;
+ if ($t eq "base") {
+ return "union $name $varname";
+ }
return ($t ne "pull"?"const ":"") . "union $name *$varname";
}
sub ArgsUnionNdrSize($$)
{
my ($d,$name) = @_;
- return "const union $name *r, uint32_t level, int flags";
+ return "const union $name *r, uint32_t level, libndr_flags flags";
}
$typefamily{UNION} = {
@@ -2192,7 +2266,7 @@ $typefamily{UNION} = {
SIZE_FN_ARGS => \&ArgsUnionNdrSize,
SIZE_FN_BODY => \&ParseUnionNdrSize,
};
-
+
#####################################################################
# parse a typedef - push side
sub ParseTypedefPush($$$$)
@@ -2240,7 +2314,7 @@ sub ParseTypedefNdrSize($$$$)
sub DeclTypedef($$$$)
{
my ($e, $t, $name, $varname) = @_;
-
+
return $typefamily{$e->{DATA}->{TYPE}}->{DECL}->($e->{DATA}, $t, $name, $varname);
}
@@ -2273,7 +2347,7 @@ sub ParsePipePushChunk($$)
my $args = $typefamily{$struct->{TYPE}}->{DECL}->($struct, "push", $name, $varname);
- $self->fn_declare("push", $struct, "enum ndr_err_code ndr_push_$name(struct ndr_push *$ndr, int ndr_flags, $args)") or return;
+ $self->fn_declare("push", $struct, "enum ndr_err_code ndr_push_$name(struct ndr_push *$ndr, ndr_flags_type ndr_flags, $args)") or return;
return if has_property($t, "nopush");
@@ -2306,7 +2380,7 @@ sub ParsePipePullChunk($$)
my $args = $typefamily{$struct->{TYPE}}->{DECL}->($struct, "pull", $name, $varname);
- $self->fn_declare("pull", $struct, "enum ndr_err_code ndr_pull_$name(struct ndr_pull *$ndr, int ndr_flags, $args)") or return;
+ $self->fn_declare("pull", $struct, "enum ndr_err_code ndr_pull_$name(struct ndr_pull *$ndr, ndr_flags_type ndr_flags, $args)") or return;
return if has_property($struct, "nopull");
@@ -2359,11 +2433,11 @@ sub ParseFunctionPrint($$)
my($self, $fn) = @_;
my $ndr = "ndr";
- $self->pidl_hdr("void ndr_print_$fn->{NAME}(struct ndr_print *$ndr, const char *name, int flags, const struct $fn->{NAME} *r);");
+ $self->pidl_hdr("void ndr_print_$fn->{NAME}(struct ndr_print *$ndr, const char *name, ndr_flags_type flags, const struct $fn->{NAME} *r);");
return if has_property($fn, "noprint");
- $self->pidl("_PUBLIC_ void ndr_print_$fn->{NAME}(struct ndr_print *$ndr, const char *name, int flags, const struct $fn->{NAME} *r)");
+ $self->pidl("_PUBLIC_ void ndr_print_$fn->{NAME}(struct ndr_print *$ndr, const char *name, ndr_flags_type flags, const struct $fn->{NAME} *r)");
$self->pidl("{");
$self->indent;
@@ -2394,7 +2468,7 @@ sub ParseFunctionPrint($$)
$self->pidl("$ndr->depth--;");
$self->deindent;
$self->pidl("}");
-
+
$self->pidl("if (flags & NDR_OUT) {");
$self->indent;
$self->pidl("ndr_print_struct($ndr, \"out\", \"$fn->{NAME}\");");
@@ -2412,7 +2486,7 @@ sub ParseFunctionPrint($$)
$self->pidl("$ndr->depth--;");
$self->deindent;
$self->pidl("}");
-
+
$self->pidl("$ndr->depth--;");
$self->deindent;
$self->pidl("}");
@@ -2422,18 +2496,18 @@ sub ParseFunctionPrint($$)
#####################################################################
# parse a function
sub ParseFunctionPush($$)
-{
+{
my($self, $fn) = @_;
my $ndr = "ndr";
- $self->fn_declare("push", $fn, "enum ndr_err_code ndr_push_$fn->{NAME}(struct ndr_push *$ndr, int flags, const struct $fn->{NAME} *r)") or return;
+ $self->fn_declare("push", $fn, "enum ndr_err_code ndr_push_$fn->{NAME}(struct ndr_push *$ndr, ndr_flags_type flags, const struct $fn->{NAME} *r)") or return;
return if has_property($fn, "nopush");
$self->pidl("{");
$self->indent;
- foreach my $e (@{$fn->{ELEMENTS}}) {
+ foreach my $e (@{$fn->{ELEMENTS}}) {
$self->DeclareArrayVariables($e);
}
@@ -2482,7 +2556,7 @@ sub ParseFunctionPush($$)
if ($fn->{RETURN_TYPE}) {
$self->pidl("NDR_CHECK(ndr_push_$fn->{RETURN_TYPE}($ndr, NDR_SCALARS, r->out.result));");
}
-
+
$self->deindent;
$self->pidl("}");
$self->pidl("return NDR_ERR_SUCCESS;");
@@ -2496,8 +2570,8 @@ sub AllocateArrayLevel($$$$$$)
my ($self,$e,$l,$ndr,$var,$size) = @_;
my $pl = GetPrevLevel($e, $l);
- if (defined($pl) and
- $pl->{TYPE} eq "POINTER" and
+ if (defined($pl) and
+ $pl->{TYPE} eq "POINTER" and
$pl->{POINTER_TYPE} eq "ref"
and not $l->{IS_ZERO_TERMINATED}) {
$self->pidl("if ($ndr->flags & LIBNDR_FLAG_REF_ALLOC) {");
@@ -2516,18 +2590,18 @@ sub AllocateArrayLevel($$$$$$)
#####################################################################
# parse a function
sub ParseFunctionPull($$)
-{
+{
my($self,$fn) = @_;
my $ndr = "ndr";
# pull function args
- $self->fn_declare("pull", $fn, "enum ndr_err_code ndr_pull_$fn->{NAME}(struct ndr_pull *$ndr, int flags, struct $fn->{NAME} *r)") or return;
+ $self->fn_declare("pull", $fn, "enum ndr_err_code ndr_pull_$fn->{NAME}(struct ndr_pull *$ndr, ndr_flags_type flags, struct $fn->{NAME} *r)") or return;
$self->pidl("{");
$self->indent;
# declare any internal pointers we need
- foreach my $e (@{$fn->{ELEMENTS}}) {
+ foreach my $e (@{$fn->{ELEMENTS}}) {
$self->DeclarePtrVariables($e);
$self->DeclareArrayVariables($e, "pull");
}
@@ -2551,7 +2625,7 @@ sub ParseFunctionPull($$)
# out to be too tricky (tridge)
foreach my $e (@{$fn->{ELEMENTS}}) {
next unless grep(/out/, @{$e->{DIRECTION}});
- $self->pidl("ZERO_STRUCT(r->out);");
+ $self->pidl("NDR_ZERO_STRUCT(r->out);");
$self->pidl("");
last;
}
@@ -2568,12 +2642,12 @@ sub ParseFunctionPull($$)
foreach my $e (@{$fn->{ELEMENTS}}) {
next unless (grep(/out/, @{$e->{DIRECTION}}));
- next unless ($e->{LEVELS}[0]->{TYPE} eq "POINTER" and
+ next unless ($e->{LEVELS}[0]->{TYPE} eq "POINTER" and
$e->{LEVELS}[0]->{POINTER_TYPE} eq "ref");
- next if (($e->{LEVELS}[1]->{TYPE} eq "DATA") and
- ($e->{LEVELS}[1]->{DATA_TYPE} eq "string"));
+ next if (($e->{LEVELS}[1]->{TYPE} eq "DATA") and
+ (Parse::Pidl::Typelist::is_string_type($e->{LEVELS}[1]->{DATA_TYPE})));
next if ($e->{LEVELS}[1]->{TYPE} eq "PIPE");
- next if (($e->{LEVELS}[1]->{TYPE} eq "ARRAY")
+ next if (($e->{LEVELS}[1]->{TYPE} eq "ARRAY")
and $e->{LEVELS}[1]->{IS_ZERO_TERMINATED});
if ($e->{LEVELS}[1]->{TYPE} eq "ARRAY") {
@@ -2596,11 +2670,11 @@ sub ParseFunctionPull($$)
}
} else {
$self->pidl("NDR_PULL_ALLOC($ndr, r->out.$e->{NAME});");
-
+
if (grep(/in/, @{$e->{DIRECTION}})) {
$self->pidl("*r->out.$e->{NAME} = *r->in.$e->{NAME};");
} else {
- $self->pidl("ZERO_STRUCTP(r->out.$e->{NAME});");
+ $self->pidl("NDR_ZERO_STRUCTP(r->out.$e->{NAME});");
}
}
}
@@ -2608,10 +2682,35 @@ sub ParseFunctionPull($$)
$self->add_deferred();
$self->deindent;
$self->pidl("}");
-
+
$self->pidl("if (flags & NDR_OUT) {");
$self->indent;
+ $self->pidl("#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION");
+
+ # This is for fuzzers of ndr_pull where the out elements refer to
+ # in elements in size_is or length_is.
+ #
+ # Not actually very harmful but also not useful outside a fuzzer
+ foreach my $e (@{$fn->{ELEMENTS}}) {
+ next unless (grep(/in/, @{$e->{DIRECTION}}));
+ next unless ($e->{LEVELS}[0]->{TYPE} eq "POINTER" and
+ $e->{LEVELS}[0]->{POINTER_TYPE} eq "ref");
+ next if (($e->{LEVELS}[1]->{TYPE} eq "DATA") and
+ (Parse::Pidl::Typelist::is_string_type($e->{LEVELS}[1]->{DATA_TYPE})));
+ next if ($e->{LEVELS}[1]->{TYPE} eq "PIPE");
+ next if ($e->{LEVELS}[1]->{TYPE} eq "ARRAY");
+
+ $self->pidl("if (r->in.$e->{NAME} == NULL) {");
+ $self->indent;
+ $self->pidl("NDR_PULL_ALLOC($ndr, r->in.$e->{NAME});");
+ $self->pidl("NDR_ZERO_STRUCTP(r->in.$e->{NAME});");
+ $self->deindent;
+ $self->pidl("}");
+ }
+
+ $self->pidl("#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */");
+
$env = GenerateFunctionOutEnv($fn);
foreach my $e (@{$fn->{ELEMENTS}}) {
next unless grep(/out/, @{$e->{DIRECTION}});
@@ -2676,7 +2775,7 @@ sub ParseGeneratePipeArray($$$)
$self->deindent;
$self->pidl("},");
}
- $self->pidl("{ NULL, NULL, 0, NULL, NULL, NULL }");
+ $self->pidl("{ .name = NULL }");
$self->deindent;
$self->pidl("};");
$self->pidl("");
@@ -2752,27 +2851,57 @@ sub FunctionCallEntry($$)
return 1;
}
+sub StructEntry($$)
+{
+ my ($self, $d) = @_;
+ my $type_decl = $typefamily{$d->{TYPE}}->{DECL}->($d, "base", $d->{NAME}, "");
+
+ $self->pidl("\t{");
+ $self->pidl("\t\t.name = \"$d->{NAME}\",");
+ $self->pidl("\t\t.struct_size = sizeof($type_decl),");
+ $self->pidl("\t\t.ndr_push = (ndr_push_flags_fn_t) ndr_push_$d->{NAME},");
+ $self->pidl("\t\t.ndr_pull = (ndr_pull_flags_fn_t) ndr_pull_$d->{NAME},");
+ $self->pidl("\t\t.ndr_print = (ndr_print_function_t) ndr_print_flags_$d->{NAME},");
+ $self->pidl("\t},");
+ return 1;
+}
+
#####################################################################
# produce a function call table
sub FunctionTable($$)
{
my($self,$interface) = @_;
my $count = 0;
+ my $count_public_structs = 0;
my $uname = uc $interface->{NAME};
- return if ($#{$interface->{FUNCTIONS}}+1 == 0);
- return unless defined ($interface->{PROPERTIES}->{uuid});
+ foreach my $d (@{$interface->{TYPES}}) {
+ next unless (is_public_struct($d));
+ $count_public_structs += 1;
+ }
+ return if ($#{$interface->{FUNCTIONS}}+1 == 0 and
+ $count_public_structs == 0);
foreach my $d (@{$interface->{INHERITED_FUNCTIONS}},@{$interface->{FUNCTIONS}}) {
$self->FunctionCallPipes($d);
}
+ $self->pidl("static const struct ndr_interface_public_struct $interface->{NAME}\_public_structs[] = {");
+
+ foreach my $d (@{$interface->{TYPES}}) {
+ next unless (is_public_struct($d));
+ $self->StructEntry($d);
+ }
+ $self->pidl("\t{ .name = NULL }");
+ $self->pidl("};");
+ $self->pidl("");
+
$self->pidl("static const struct ndr_interface_call $interface->{NAME}\_calls[] = {");
foreach my $d (@{$interface->{INHERITED_FUNCTIONS}},@{$interface->{FUNCTIONS}}) {
$count += $self->FunctionCallEntry($d);
}
- $self->pidl("\t{ NULL, 0, NULL, NULL, NULL }");
+ $self->pidl("\t{ .name = NULL }");
$self->pidl("};");
$self->pidl("");
@@ -2781,7 +2910,7 @@ sub FunctionTable($$)
$self->pidl("\t$ep, ");
}
my $endpoint_count = $#{$interface->{ENDPOINTS}}+1;
-
+
$self->pidl("};");
$self->pidl("");
@@ -2795,18 +2924,22 @@ sub FunctionTable($$)
$interface->{PROPERTIES}->{authservice} = "\"host\"";
}
- $self->AuthServiceStruct($interface->{NAME},
+ $self->AuthServiceStruct($interface->{NAME},
$interface->{PROPERTIES}->{authservice});
$self->pidl("\nconst struct ndr_interface_table ndr_table_$interface->{NAME} = {");
$self->pidl("\t.name\t\t= \"$interface->{NAME}\",");
- $self->pidl("\t.syntax_id\t= {");
- $self->pidl("\t\t" . print_uuid($interface->{UUID}) .",");
- $self->pidl("\t\tNDR_$uname\_VERSION");
- $self->pidl("\t},");
- $self->pidl("\t.helpstring\t= NDR_$uname\_HELPSTRING,");
+ if (defined $interface->{PROPERTIES}->{uuid}) {
+ $self->pidl("\t.syntax_id\t= {");
+ $self->pidl("\t\t" . print_uuid($interface->{UUID}) .",");
+ $self->pidl("\t\tNDR_$uname\_VERSION");
+ $self->pidl("\t},");
+ $self->pidl("\t.helpstring\t= NDR_$uname\_HELPSTRING,");
+ }
$self->pidl("\t.num_calls\t= $count,");
$self->pidl("\t.calls\t\t= $interface->{NAME}\_calls,");
+ $self->pidl("\t.num_public_structs\t= $count_public_structs,");
+ $self->pidl("\t.public_structs\t\t= $interface->{NAME}\_public_structs,");
$self->pidl("\t.endpoints\t= &$interface->{NAME}\_endpoints,");
$self->pidl("\t.authservices\t= &$interface->{NAME}\_authservices");
$self->pidl("};");
@@ -2840,7 +2973,7 @@ sub HeaderInclude
#####################################################################
# generate prototypes and defines for the interface definitions
-# FIXME: these prototypes are for the DCE/RPC client functions, not the
+# FIXME: these prototypes are for the DCE/RPC client functions, not the
# NDR parser and so do not belong here, technically speaking
sub HeaderInterface($$$)
{
@@ -2862,7 +2995,7 @@ sub HeaderInterface($$$)
if (defined $interface->{PROPERTIES}->{uuid}) {
my $name = uc $interface->{NAME};
- $self->pidl_hdr("#define NDR_$name\_UUID " .
+ $self->pidl_hdr("#define NDR_$name\_UUID " .
Parse::Pidl::Util::make_str(lc($interface->{UUID})));
$self->pidl_hdr("#define NDR_$name\_VERSION $interface->{VERSION}");
@@ -2871,7 +3004,15 @@ sub HeaderInterface($$$)
if(!defined $interface->{PROPERTIES}->{helpstring}) { $interface->{PROPERTIES}->{helpstring} = "NULL"; }
$self->pidl_hdr("#define NDR_$name\_HELPSTRING $interface->{PROPERTIES}->{helpstring}");
+ }
+ my $count_public_structs = 0;
+ foreach my $d (@{$interface->{TYPES}}) {
+ next unless (has_property($d, "public"));
+ $count_public_structs += 1;
+ }
+ if ($#{$interface->{FUNCTIONS}}+1 > 0 or
+ $count_public_structs > 0) {
$self->pidl_hdr("extern const struct ndr_interface_table ndr_table_$interface->{NAME};");
}
@@ -2879,12 +3020,12 @@ sub HeaderInterface($$$)
next if has_property($_, "noopnum");
next if grep(/^$_->{NAME}$/,@{$interface->{INHERITED_FUNCTIONS}});
my $u_name = uc $_->{NAME};
-
+
my $val = sprintf("0x%02x", $count);
if (defined($interface->{BASE})) {
$val .= " + NDR_" . uc $interface->{BASE} . "_CALL_COUNT";
}
-
+
$self->pidl_hdr("#define NDR_$u_name ($val)");
$self->pidl_hdr("");
@@ -2919,7 +3060,7 @@ sub ParseTypePushFunction($$$)
my $args = $typefamily{$e->{TYPE}}->{DECL}->($e, "push", $e->{NAME}, $varname);
- $self->fn_declare("push", $e, "enum ndr_err_code ".TypeFunctionName("ndr_push", $e)."(struct ndr_push *$ndr, int ndr_flags, $args)") or return;
+ $self->fn_declare("push", $e, "enum ndr_err_code ".TypeFunctionName("ndr_push", $e)."(struct ndr_push *$ndr, ndr_flags_type ndr_flags, $args)") or return;
$self->pidl("{");
$self->indent;
@@ -2948,7 +3089,7 @@ sub ParseTypePullFunction($$)
my $args = $typefamily{$e->{TYPE}}->{DECL}->($e, "pull", $e->{NAME}, $varname);
- $self->fn_declare("pull", $e, "enum ndr_err_code ".TypeFunctionName("ndr_pull", $e)."(struct ndr_pull *$ndr, int ndr_flags, $args)") or return;
+ $self->fn_declare("pull", $e, "enum ndr_err_code ".TypeFunctionName("ndr_pull", $e)."(struct ndr_pull *$ndr, ndr_flags_type ndr_flags, $args)") or return;
$self->pidl("{");
$self->indent;
@@ -2975,6 +3116,18 @@ sub ParseTypePrintFunction($$$)
$self->pidl_hdr("void ".TypeFunctionName("ndr_print", $e)."(struct ndr_print *ndr, const char *name, $args);");
+ if (is_public_struct($e)) {
+ $self->pidl("static void ".TypeFunctionName("ndr_print_flags", $e).
+ "(struct ndr_print *$ndr, const char *name, ndr_flags_type unused, $args)"
+ );
+ $self->pidl("{");
+ $self->indent;
+ $self->pidl(TypeFunctionName("ndr_print", $e)."($ndr, name, $varname);");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+ }
+
return if (has_property($e, "noprint"));
$self->pidl("_PUBLIC_ void ".TypeFunctionName("ndr_print", $e)."(struct ndr_print *$ndr, const char *name, $args)");
@@ -3040,8 +3193,8 @@ sub ParseInterface($$$)
($needed->{TypeFunctionName("ndr_print", $d)}) && $self->ParseTypePrintFunction($d, "r");
# Make sure we don't generate a function twice...
- $needed->{TypeFunctionName("ndr_push", $d)} =
- $needed->{TypeFunctionName("ndr_pull", $d)} =
+ $needed->{TypeFunctionName("ndr_push", $d)} =
+ $needed->{TypeFunctionName("ndr_pull", $d)} =
$needed->{TypeFunctionName("ndr_print", $d)} = 0;
($needed->{"ndr_size_$d->{NAME}"}) && $self->ParseTypeNdrSize($d);
@@ -3054,7 +3207,16 @@ sub ParseInterface($$$)
($needed->{"ndr_print_$d->{NAME}"}) && $self->ParseFunctionPrint($d);
}
+ # Allow compilation of generated files where replacement functions
+ # for structures declared nopull/nopush have not been provided.
+ #
+ # This makes sense when only the print functions are used
+ #
+ # Otherwise the ndr_table XXX will reference these
+
+ $self->pidl("#ifndef SKIP_NDR_TABLE_$interface->{NAME}");
$self->FunctionTable($interface);
+ $self->pidl("#endif /* SKIP_NDR_TABLE_$interface->{NAME} */");
$self->pidl_hdr("#endif /* _HEADER_NDR_$interface->{NAME} */");
}
@@ -3116,7 +3278,7 @@ sub NeededElement($$$)
return if ($e->{TYPE} eq "EMPTY");
- return if (ref($e->{TYPE}) eq "HASH" and
+ return if (ref($e->{TYPE}) eq "HASH" and
not defined($e->{TYPE}->{NAME}));
my ($t, $rt);
@@ -3180,7 +3342,7 @@ sub NeededType($$$)
return unless defined($t->{ELEMENTS});
for my $e (@{$t->{ELEMENTS}}) {
$e->{PARENT} = $t;
- if (has_property($e, "compression")) {
+ if (has_property($e, "compression")) {
$needed->{"compression"} = 1;
}
NeededElement($e, $req, $needed);
@@ -3198,7 +3360,7 @@ sub NeededInterface($$)
foreach (reverse @{$interface->{TYPES}}) {
if (has_property($_, "public")) {
- $needed->{TypeFunctionName("ndr_pull", $_)} = $needed->{TypeFunctionName("ndr_push", $_)} =
+ $needed->{TypeFunctionName("ndr_pull", $_)} = $needed->{TypeFunctionName("ndr_push", $_)} =
$needed->{TypeFunctionName("ndr_print", $_)} = 1;
}
@@ -3215,7 +3377,7 @@ sub TypeFunctionName($$)
{
my ($prefix, $t) = @_;
- return "$prefix\_$t->{NAME}" if (ref($t) eq "HASH" and
+ return "$prefix\_$t->{NAME}" if (ref($t) eq "HASH" and
$t->{TYPE} eq "TYPEDEF");
return "$prefix\_$t->{TYPE}_$t->{NAME}" if (ref($t) eq "HASH");
return "$prefix\_$t";
diff --git a/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm b/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm
index ad36f000..73359987 100644
--- a/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm
+++ b/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm
@@ -7,6 +7,7 @@
package Parse::Pidl::Samba4::NDR::Server;
use strict;
+use warnings;
use Parse::Pidl::Util;
use vars qw($VERSION);
@@ -81,10 +82,10 @@ sub Boilerplate_Iface($)
my $if_version = $interface->{VERSION};
pidl "
-static NTSTATUS $name\__op_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface, uint32_t if_version)
+static NTSTATUS $name\__op_bind(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface)
{
#ifdef DCESRV_INTERFACE_$uname\_BIND
- return DCESRV_INTERFACE_$uname\_BIND(dce_call,iface);
+ return DCESRV_INTERFACE_$uname\_BIND(context,iface);
#else
return NT_STATUS_OK;
#endif
@@ -120,9 +121,6 @@ static NTSTATUS $name\__op_ndr_pull(struct dcesrv_call_state *dce_call, TALLOC_C
/* unravel the NDR for the packet */
ndr_err = ndr_table_$name.calls[opnum].ndr_pull(pull, NDR_IN, *r);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- dcerpc_log_packet(dce_call->conn->packet_log_dir,
- &ndr_table_$name, opnum, NDR_IN,
- &dce_call->pkt.u.request.stub_and_verifier);
dce_call->fault_code = DCERPC_FAULT_NDR;
return NT_STATUS_NET_WRITE_FAULT;
}
@@ -145,9 +143,6 @@ pidl "
}
if (dce_call->fault_code != 0) {
- dcerpc_log_packet(dce_call->conn->packet_log_dir,
- &ndr_table_$name, opnum, NDR_IN,
- &dce_call->pkt.u.request.stub_and_verifier);
return NT_STATUS_NET_WRITE_FAULT;
}
@@ -169,9 +164,6 @@ pidl "
}
if (dce_call->fault_code != 0) {
- dcerpc_log_packet(dce_call->conn->packet_log_dir,
- &ndr_table_$name, opnum, NDR_IN,
- &dce_call->pkt.u.request.stub_and_verifier);
return NT_STATUS_NET_WRITE_FAULT;
}
@@ -201,6 +193,7 @@ static const struct dcesrv_interface dcesrv\_$name\_interface = {
.dispatch = $name\__op_dispatch,
.reply = $name\__op_reply,
.ndr_push = $name\__op_ndr_push,
+ .local = NULL,
#ifdef DCESRV_INTERFACE_$uname\_FLAGS
.flags = DCESRV_INTERFACE_$uname\_FLAGS
#else
@@ -223,12 +216,22 @@ sub Boilerplate_Ep_Server($)
static NTSTATUS $name\__op_init_server(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint_server *ep_server)
{
int i;
+#ifdef DCESRV_INTERFACE_$uname\_NCACN_NP_SECONDARY_ENDPOINT
+ const char *ncacn_np_secondary_endpoint =
+ DCESRV_INTERFACE_$uname\_NCACN_NP_SECONDARY_ENDPOINT;
+#else
+ const char *ncacn_np_secondary_endpoint = NULL;
+#endif
for (i=0;i<ndr_table_$name.endpoints->count;i++) {
NTSTATUS ret;
const char *name = ndr_table_$name.endpoints->names[i];
- ret = dcesrv_interface_register(dce_ctx, name, &dcesrv_$name\_interface, NULL);
+ ret = dcesrv_interface_register(dce_ctx,
+ name,
+ ncacn_np_secondary_endpoint,
+ &dcesrv_$name\_interface,
+ NULL);
if (!NT_STATUS_IS_OK(ret)) {
DEBUG(1,(\"$name\_op_init_server: failed to register endpoint \'%s\'\\n\",name));
return ret;
@@ -238,6 +241,11 @@ static NTSTATUS $name\__op_init_server(struct dcesrv_context *dce_ctx, const str
return NT_STATUS_OK;
}
+static NTSTATUS $name\__op_shutdown_server(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint_server *ep_server)
+{
+ return NT_STATUS_OK;
+}
+
static bool $name\__op_interface_by_uuid(struct dcesrv_interface *iface, const struct GUID *uuid, uint32_t if_version)
{
if (dcesrv_$name\_interface.syntax_id.if_version == if_version &&
@@ -266,12 +274,20 @@ NTSTATUS dcerpc_server_$name\_init(TALLOC_CTX *ctx)
/* fill in our name */
.name = \"$name\",
+ /* Initialization flag */
+ .initialized = false,
+
/* fill in all the operations */
#ifdef DCESRV_INTERFACE_$uname\_INIT_SERVER
.init_server = DCESRV_INTERFACE_$uname\_INIT_SERVER,
#else
.init_server = $name\__op_init_server,
#endif
+#ifdef DCESRV_INTERFACE_$uname\_SHUTDOWN_SERVER
+ .shutdown_server = DCESRV_INTERFACE_$uname\_SHUTDOWN_SERVER,
+#else
+ .shutdown_server = $name\__op_shutdown_server,
+#endif
.interface_by_uuid = $name\__op_interface_by_uuid,
.interface_by_name = $name\__op_interface_by_name
};
diff --git a/tools/pidl/lib/Parse/Pidl/Samba4/NDR/ServerCompat.pm b/tools/pidl/lib/Parse/Pidl/Samba4/NDR/ServerCompat.pm
new file mode 100644
index 00000000..aaa10ffd
--- /dev/null
+++ b/tools/pidl/lib/Parse/Pidl/Samba4/NDR/ServerCompat.pm
@@ -0,0 +1,624 @@
+###################################################
+# server boilerplate generator
+# Copyright tridge@samba.org 2003
+# Copyright metze@samba.org 2004
+# Copyright scabrero@samba.org 2019
+# released under the GNU GPL
+
+package Parse::Pidl::Samba4::NDR::ServerCompat;
+
+use Exporter;
+@ISA = qw(Exporter);
+@EXPORT_OK = qw(Parse);
+
+use Parse::Pidl::Util qw(print_uuid has_property ParseExpr);
+use Parse::Pidl::Typelist qw(mapTypeName);
+use Parse::Pidl qw(error fatal);
+use Parse::Pidl::NDR qw(ContainsPipe GetNextLevel);
+use Parse::Pidl::Samba4 qw(ElementStars);
+use Parse::Pidl::Samba4::Header qw(GenerateFunctionOutEnv);
+
+use vars qw($VERSION);
+$VERSION = '1.0';
+
+use strict;
+
+sub indent($) { my ($self) = @_; $self->{tabs}.="\t"; }
+sub deindent($) { my ($self) = @_; $self->{tabs} = substr($self->{tabs}, 1); }
+sub pidl($$) { my ($self,$txt) = @_; $self->{res} .= $txt ? "$self->{tabs}$txt\n" : "\n"; }
+sub pidlnoindent($$) { my ($self,$txt) = @_; $self->{res} .= $txt ? "$txt\n" : "\n"; }
+sub pidl_hdr($$) { my ($self, $txt) = @_; $self->{res_hdr} .= "$txt\n"; }
+sub pidl_both($$) { my ($self, $txt) = @_; $self->{hdr} .= "$txt\n"; $self->{res_hdr} .= "$txt\n"; }
+
+sub new($)
+{
+ my ($class) = shift;
+ my $self = { res => "", res_hdr => "", tabs => "" };
+ bless($self, $class);
+}
+
+sub decl_level($$)
+{
+ my ($self, $e, $l) = @_;
+ my $res = "";
+
+ if (has_property($e, "charset")) {
+ $res .= "const char";
+ } else {
+ $res .= mapTypeName($e->{TYPE});
+ }
+
+ my $stars = ElementStars($e, $l);
+
+ $res .= " ".$stars unless ($stars eq "");
+
+ return $res;
+}
+
+sub alloc_out_var($$$$$)
+{
+ my ($self, $e, $mem_ctx, $name, $env, $alloc_error_block) = @_;
+
+ my $l = $e->{LEVELS}[0];
+
+ # we skip pointer to arrays
+ if ($l->{TYPE} eq "POINTER") {
+ my $nl = GetNextLevel($e, $l);
+ $l = $nl if ($nl->{TYPE} eq "ARRAY");
+ } elsif
+
+ # we don't support multi-dimensional arrays yet
+ ($l->{TYPE} eq "ARRAY") {
+ my $nl = GetNextLevel($e, $l);
+ if ($nl->{TYPE} eq "ARRAY") {
+ fatal($e->{ORIGINAL},"multi-dimensional [out] arrays are not supported!");
+ }
+ } else {
+ # neither pointer nor array, no need to alloc something.
+ return;
+ }
+
+ if ($l->{TYPE} eq "ARRAY") {
+ unless(defined($l->{SIZE_IS})) {
+ error($e->{ORIGINAL}, "No size known for array `$e->{NAME}'");
+ $self->pidl("#error No size known for array `$e->{NAME}'");
+ } else {
+ my $size = ParseExpr($l->{SIZE_IS}, $env, $e);
+ $self->pidl("$name = talloc_zero_array($mem_ctx, " . $self->decl_level($e, 1) . ", $size);");
+ }
+ } else {
+ $self->pidl("$name = talloc_zero($mem_ctx, " . $self->decl_level($e, 1) . ");");
+ }
+
+ $self->pidl("if ($name == NULL) {");
+ $self->indent();
+ foreach (@{$alloc_error_block}) {
+ $self->pidl($_);
+ }
+ $self->deindent();
+ $self->pidl("}");
+ $self->pidl("");
+}
+
+sub gen_fn_out($$)
+{
+ my ($self, $fn, $alloc_error_block) = @_;
+
+ my $hasout = 0;
+ foreach (@{$fn->{ELEMENTS}}) {
+ if (grep(/out/, @{$_->{DIRECTION}})) {
+ $hasout = 1;
+ }
+ }
+
+ if ($hasout) {
+ $self->pidl("NDR_ZERO_STRUCT(r2->out);");
+ }
+
+ foreach (@{$fn->{ELEMENTS}}) {
+ my @dir = @{$_->{DIRECTION}};
+ if (grep(/in/, @dir) and grep(/out/, @dir)) {
+ $self->pidl("r2->out.$_->{NAME} = r2->in.$_->{NAME};");
+ }
+ }
+
+ foreach (@{$fn->{ELEMENTS}}) {
+ next if ContainsPipe($_, $_->{LEVELS}[0]);
+
+ my @dir = @{$_->{DIRECTION}};
+
+ if (grep(/in/, @dir) and grep(/out/, @dir)) {
+ # noop
+ } elsif (grep(/out/, @dir) and not has_property($_, "represent_as")) {
+ my $env = GenerateFunctionOutEnv($fn, "r2->");
+ $self->alloc_out_var($_, "r2", "r2->out.$_->{NAME}", $env, $alloc_error_block);
+ }
+
+ }
+}
+
+#####################################################
+# generate the switch statement for function dispatch
+sub gen_dispatch_switch($)
+{
+ my ($self, $interface) = @_;
+
+ my @alloc_error_block = ("status = NT_STATUS_NO_MEMORY;",
+ "p->fault_state = DCERPC_FAULT_CANT_PERFORM;",
+ "goto fail;");
+ foreach my $fn (@{$interface->{FUNCTIONS}}) {
+ next if not defined($fn->{OPNUM});
+
+ my $fname = $fn->{NAME};
+ my $ufname = uc($fname);
+
+ $self->pidl("case $fn->{OPNUM}: { /* $fn->{NAME} */");
+ $self->indent();
+ $self->pidl("struct $fname *r2 = (struct $fname *)r;");
+ $self->pidl("if (DEBUGLEVEL >= 10) {");
+ $self->indent();
+ $self->pidl("NDR_PRINT_FUNCTION_DEBUG($fname, NDR_IN, r2);");
+ $self->deindent();
+ $self->pidl("}");
+
+ $self->gen_fn_out($fn, \@alloc_error_block);
+
+ $self->pidl_hdr("struct $fname;");
+
+ if ($fn->{RETURN_TYPE} && $fn->{RETURN_TYPE} ne "void") {
+ $self->pidl_hdr(mapTypeName($fn->{RETURN_TYPE}) . " _$fname(struct pipes_struct *p, struct $fname *r);");
+ $self->pidl("r2->out.result = _$fname(p, r2);");
+ } else {
+ $self->pidl_hdr("void _$fname(struct pipes_struct *p, struct $fname *r);");
+ $self->pidl("_$fname(p, r2);");
+ }
+
+ $self->pidl("break;");
+ $self->deindent();
+ $self->pidl("}");
+ }
+}
+
+#####################################################
+# generate the switch statement for function reply
+sub gen_reply_switch($)
+{
+ my ($self, $interface) = @_;
+
+ foreach my $fn (@{$interface->{FUNCTIONS}}) {
+ next if not defined($fn->{OPNUM});
+
+ $self->pidl("case $fn->{OPNUM}: { /* $fn->{NAME} */");
+ $self->indent();
+ $self->pidl("struct $fn->{NAME} *r2 = (struct $fn->{NAME} *)r;");
+ $self->pidl("if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {");
+ $self->indent();
+ $self->pidl("DEBUG(5,(\"function $fn->{NAME} replied async\\n\"));");
+ $self->deindent();
+ $self->pidl("}");
+ $self->pidl("if (DEBUGLEVEL >= 10 && dce_call->fault_code == 0) {");
+ $self->indent();
+ $self->pidl("NDR_PRINT_FUNCTION_DEBUG($fn->{NAME}, NDR_OUT | NDR_SET_VALUES, r2);");
+ $self->deindent();
+ $self->pidl("}");
+ $self->pidl("if (dce_call->fault_code != 0) {");
+ $self->indent();
+ $self->pidl("DBG_WARNING(\"dcerpc_fault %s in $fn->{NAME}\\n\", dcerpc_errstr(mem_ctx, dce_call->fault_code));");
+ $self->deindent();
+ $self->pidl("}");
+ $self->pidl("break;");
+ $self->deindent();
+ $self->pidl("}");
+ }
+}
+
+#####################################################################
+# produce boilerplate code for a interface
+sub boilerplate_iface($)
+{
+ my ($self, $interface) = @_;
+
+ my $name = $interface->{NAME};
+ my $uname = uc $name;
+ my $uuid = lc($interface->{UUID});
+ my $if_version = $interface->{VERSION};
+
+ $self->pidl("static NTSTATUS $name\__op_bind(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface)");
+ $self->pidl("{");
+ $self->indent();
+ $self->pidlnoindent("#ifdef DCESRV_INTERFACE_$uname\_BIND");
+ $self->pidl("return DCESRV_INTERFACE_$uname\_BIND(context,iface);");
+ $self->pidlnoindent("#else");
+ $self->pidl("return NT_STATUS_OK;");
+ $self->deindent();
+ $self->pidl("#endif");
+ $self->pidl("}");
+ $self->pidl("");
+
+ $self->pidl("static void $name\__op_unbind(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface)");
+ $self->pidl("{");
+ $self->pidlnoindent("#ifdef DCESRV_INTERFACE_$uname\_UNBIND");
+ $self->indent();
+ $self->pidl("DCESRV_INTERFACE_$uname\_UNBIND(context, iface);");
+ $self->pidlnoindent("#else");
+ $self->pidl("return;");
+ $self->pidlnoindent("#endif");
+ $self->deindent();
+ $self->pidl("}");
+ $self->pidl("");
+
+ $self->pidl_hdr("NTSTATUS $name\__op_ndr_pull(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_pull *pull, void **r);");
+ $self->pidl("NTSTATUS $name\__op_ndr_pull(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_pull *pull, void **r)");
+ $self->pidl("{");
+ $self->indent();
+ $self->pidl("enum ndr_err_code ndr_err;");
+ $self->pidl("uint16_t opnum = dce_call->pkt.u.request.opnum;");
+ $self->pidl("");
+ $self->pidl("dce_call->fault_code = 0;");
+ $self->pidl("");
+ $self->pidl("if (opnum >= ndr_table_$name.num_calls) {");
+ $self->indent();
+ $self->pidl("dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR;");
+ $self->pidl("return NT_STATUS_NET_WRITE_FAULT;");
+ $self->deindent();
+ $self->pidl("}");
+ $self->pidl("");
+ $self->pidl("*r = talloc_named(mem_ctx, ndr_table_$name.calls[opnum].struct_size, \"struct %s\", ndr_table_$name.calls[opnum].name);");
+ $self->pidl("NT_STATUS_HAVE_NO_MEMORY(*r);");
+ $self->pidl("");
+ $self->pidl("/* unravel the NDR for the packet */");
+ $self->pidl("ndr_err = ndr_table_$name.calls[opnum].ndr_pull(pull, NDR_IN, *r);");
+ $self->pidl("if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {");
+ $self->indent();
+ $self->pidl("dce_call->fault_code = DCERPC_FAULT_NDR;");
+ $self->pidl("return NT_STATUS_NET_WRITE_FAULT;");
+ $self->deindent();
+ $self->pidl("}");
+ $self->pidl("");
+ $self->pidl("return NT_STATUS_OK;");
+ $self->deindent();
+ $self->pidl("}");
+ $self->pidl("");
+
+ $self->pidl("static NTSTATUS $name\__op_dispatch_internal(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r, enum s3compat_rpc_dispatch dispatch)");
+ $self->pidl("{");
+ $self->indent();
+ $self->pidl("uint16_t opnum = dce_call->pkt.u.request.opnum;");
+ $self->pidl("struct pipes_struct *p = NULL;");
+ $self->pidl("NTSTATUS status = NT_STATUS_OK;");
+ $self->pidl("bool impersonated = false;");
+ $self->pidl("");
+ $self->pidl("/* Retrieve pipes struct */");
+ $self->pidl("p = dcesrv_get_pipes_struct(dce_call->conn);");
+ $self->pidl("p->dce_call = dce_call;");
+ $self->pidl("p->mem_ctx = mem_ctx;");
+ $self->pidl("/* Reset pipes struct fault state */");
+ $self->pidl("p->fault_state = 0;");
+ $self->pidl("");
+
+ $self->pidl("/* Impersonate */");
+ $self->pidl("if (dispatch == S3COMPAT_RPC_DISPATCH_EXTERNAL) {");
+ $self->indent();
+ $self->pidl("impersonated = become_authenticated_pipe_user(dce_call->auth_state->session_info);");
+ $self->pidl("if (!impersonated) {");
+ $self->indent();
+ $self->pidl("dce_call->fault_code = DCERPC_FAULT_ACCESS_DENIED;");
+ $self->pidl("status = NT_STATUS_NET_WRITE_FAULT;");
+ $self->pidl("goto fail;");
+ $self->deindent();
+ $self->pidl("}");
+ $self->deindent();
+ $self->pidl("}");
+ $self->pidl("");
+
+ $self->pidl("switch (opnum) {");
+ $self->gen_dispatch_switch($interface);
+ $self->pidl("default:");
+ $self->indent();
+ $self->pidl("dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR;");
+ $self->pidl("break;");
+ $self->deindent();
+ $self->pidl("}");
+ $self->pidl("");
+
+ $self->pidlnoindent("fail:");
+ $self->pidl("/* Unimpersonate */");
+ $self->pidl("if (impersonated) {");
+ $self->indent();
+ $self->pidl("unbecome_authenticated_pipe_user();");
+ $self->deindent();
+ $self->pidl("}");
+ $self->pidl("");
+
+ $self->pidl("p->dce_call = NULL;");
+ $self->pidl("p->mem_ctx = NULL;");
+ $self->pidl("/* Check pipes struct fault state */");
+ $self->pidl("if (p->fault_state != 0) {");
+ $self->indent();
+ $self->pidl("dce_call->fault_code = p->fault_state;");
+ $self->deindent();
+ $self->pidl("}");
+ $self->pidl("if (dce_call->fault_code != 0) {");
+ $self->indent();
+ $self->pidl("status = NT_STATUS_NET_WRITE_FAULT;");
+ $self->deindent();
+ $self->pidl("}");
+ $self->pidl("");
+
+ $self->pidl("return status;");
+ $self->deindent();
+ $self->pidl("}");
+ $self->pidl("");
+
+ $self->pidl_hdr("NTSTATUS $name\__op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r);");
+ $self->pidl("NTSTATUS $name\__op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)");
+ $self->pidl("{");
+ $self->indent();
+ $self->pidl("return $name\__op_dispatch_internal(dce_call, mem_ctx, r, S3COMPAT_RPC_DISPATCH_EXTERNAL);");
+ $self->deindent();
+ $self->pidl("}");
+ $self->pidl("");
+
+ $self->pidl_hdr("NTSTATUS $name\__op_reply(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r);");
+ $self->pidl("NTSTATUS $name\__op_reply(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)");
+ $self->pidl("{");
+ $self->indent();
+ $self->pidl("uint16_t opnum = dce_call->pkt.u.request.opnum;");
+ $self->pidl("");
+ $self->pidl("switch (opnum) {");
+ $self->gen_reply_switch($interface);
+ $self->pidl("default:");
+ $self->indent();
+ $self->pidl("dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR;");
+ $self->pidl("break;");
+ $self->deindent();
+ $self->pidl("}");
+ $self->pidl("");
+
+ $self->pidl("if (dce_call->fault_code != 0) {");
+ $self->indent();
+ $self->pidl("return NT_STATUS_NET_WRITE_FAULT;");
+ $self->deindent();
+ $self->pidl("}");
+ $self->pidl("");
+ $self->pidl("return NT_STATUS_OK;");
+ $self->deindent();
+ $self->pidl("}");
+ $self->pidl("");
+
+ $self->pidl_hdr("NTSTATUS $name\__op_ndr_push(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_push *push, const void *r);");
+ $self->pidl("NTSTATUS $name\__op_ndr_push(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_push *push, const void *r)");
+ $self->pidl("{");
+ $self->indent();
+ $self->pidl("enum ndr_err_code ndr_err;");
+ $self->pidl("uint16_t opnum = dce_call->pkt.u.request.opnum;");
+ $self->pidl("");
+ $self->pidl("ndr_err = ndr_table_$name.calls[opnum].ndr_push(push, NDR_OUT, r);");
+ $self->pidl("if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {");
+ $self->indent();
+ $self->pidl("dce_call->fault_code = DCERPC_FAULT_NDR;");
+ $self->pidl("return NT_STATUS_NET_WRITE_FAULT;");
+ $self->deindent();
+ $self->pidl("}");
+ $self->pidl("");
+ $self->pidl("return NT_STATUS_OK;");
+ $self->deindent();
+ $self->pidl("}");
+ $self->pidl("");
+
+ ##############################
+ #### LOCAL DISPATCH ####
+ ##############################
+ $self->pidl_hdr("NTSTATUS $name\__op_local(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r);");
+ $self->pidl("NTSTATUS $name\__op_local(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)");
+ $self->pidl("{");
+ $self->indent();
+ $self->pidl("return $name\__op_dispatch_internal(dce_call, mem_ctx, r, S3COMPAT_RPC_DISPATCH_INTERNAL);");
+ $self->deindent();
+ $self->pidl("}");
+ $self->pidl("");
+
+ $self->pidl("static const struct dcesrv_interface dcesrv\_$name\_interface = {");
+ $self->indent();
+ $self->pidl(".name = \"$name\",");
+ $self->pidl(".syntax_id = {".print_uuid($uuid).",$if_version},");
+ $self->pidl(".bind = $name\__op_bind,");
+ $self->pidl(".unbind = $name\__op_unbind,");
+ $self->pidl(".ndr_pull = $name\__op_ndr_pull,");
+ $self->pidl(".dispatch = $name\__op_dispatch,");
+ $self->pidl(".reply = $name\__op_reply,");
+ $self->pidl(".ndr_push = $name\__op_ndr_push,");
+ $self->pidl(".local = $name\__op_local,");
+ $self->pidlnoindent("#ifdef DCESRV_INTERFACE_$uname\_FLAGS");
+ $self->pidl(".flags = DCESRV_INTERFACE_$uname\_FLAGS");
+ $self->pidlnoindent("#else");
+ $self->pidl(".flags = 0");
+ $self->pidlnoindent("#endif");
+ $self->deindent();
+ $self->pidl("};");
+ $self->pidl("");
+}
+
+#####################################################################
+# produce boilerplate code for an endpoint server
+sub boilerplate_ep_server($)
+{
+ my ($self, $interface) = @_;
+ my $name = $interface->{NAME};
+ my $uname = uc $name;
+
+ $self->pidl("static NTSTATUS $name\__op_init_server(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint_server *ep_server)");
+ $self->pidl("{");
+ $self->indent();
+ $self->pidl("uint32_t i;");
+ $self->pidl("NTSTATUS ret;");
+ $self->pidl("");
+ $self->pidlnoindent("#ifdef DCESRV_INTERFACE_$uname\_NCACN_NP_SECONDARY_ENDPOINT");
+ $self->pidl("const char *ncacn_np_secondary_endpoint = DCESRV_INTERFACE_$uname\_NCACN_NP_SECONDARY_ENDPOINT;");
+ $self->pidlnoindent("#else");
+ $self->pidl("const char *ncacn_np_secondary_endpoint = NULL;");
+ $self->pidlnoindent("#endif");
+ $self->pidl("");
+ $self->pidl("for (i=0;i<ndr_table_$name.endpoints->count;i++) {");
+ $self->indent();
+ $self->pidl("const char *name = ndr_table_$name.endpoints->names[i];");
+ $self->pidl("");
+ $self->pidl("ret = dcesrv_interface_register(dce_ctx, name, ncacn_np_secondary_endpoint, &dcesrv_$name\_interface, NULL);");
+ $self->pidl("if (!NT_STATUS_IS_OK(ret)) {");
+ $self->indent();
+ $self->pidl("DBG_ERR(\"Failed to register endpoint \'%s\'\\n\",name);");
+ $self->pidl("return ret;");
+ $self->deindent();
+ $self->pidl("}");
+ $self->deindent();
+ $self->pidl("}");
+ $self->pidl("");
+ $self->pidl("return NT_STATUS_OK;");
+ $self->deindent();
+ $self->pidl("}");
+ $self->pidl("");
+
+ $self->pidl("static NTSTATUS $name\__op_shutdown_server(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint_server *ep_server)");
+ $self->pidl("{");
+ $self->indent();
+ $self->pidl("return NT_STATUS_OK;");
+ $self->deindent();
+ $self->pidl("}");
+ $self->pidl("");
+
+ $self->pidl("static bool $name\__op_interface_by_uuid(struct dcesrv_interface *iface, const struct GUID *uuid, uint32_t if_version)");
+ $self->pidl("{");
+ $self->indent();
+ $self->pidl("if (dcesrv_$name\_interface.syntax_id.if_version == if_version && GUID_equal(\&dcesrv\_$name\_interface.syntax_id.uuid, uuid)) {");
+ $self->indent();
+ $self->pidl("memcpy(iface,&dcesrv\_$name\_interface, sizeof(*iface));");
+ $self->pidl("return true;");
+ $self->deindent();
+ $self->pidl("}");
+ $self->pidl("");
+ $self->pidl("return false;");
+ $self->deindent();
+ $self->pidl("}");
+ $self->pidl("");
+
+ $self->pidl("static bool $name\__op_interface_by_name(struct dcesrv_interface *iface, const char *name)");
+ $self->pidl("{");
+ $self->indent();
+ $self->pidl("if (strcmp(dcesrv_$name\_interface.name, name)==0) {");
+ $self->indent();
+ $self->pidl("memcpy(iface, &dcesrv_$name\_interface, sizeof(*iface));");
+ $self->pidl("return true;");
+ $self->deindent();
+ $self->pidl("}");
+ $self->pidl("");
+ $self->pidl("return false;");
+ $self->deindent();
+ $self->pidl("}");
+ $self->pidl("");
+
+ $self->pidl("static const struct dcesrv_endpoint_server $name\_ep_server = {");
+ $self->indent();
+ $self->pidl("/* fill in our name */");
+ $self->pidl(".name = \"$name\",");
+ $self->pidl("");
+ $self->pidl("/* Initialization flag */");
+ $self->pidl(".initialized = false,");
+ $self->pidl("");
+ $self->pidl("/* fill in all the operations */");
+ $self->pidlnoindent("#ifdef DCESRV_INTERFACE_$uname\_INIT_SERVER");
+ $self->pidl(".init_server = DCESRV_INTERFACE_$uname\_INIT_SERVER,");
+ $self->pidlnoindent("#else");
+ $self->pidl(".init_server = $name\__op_init_server,");
+ $self->pidlnoindent("#endif");
+ $self->pidlnoindent("#ifdef DCESRV_INTERFACE_$uname\_SHUTDOWN_SERVER");
+ $self->pidl(".shutdown_server = DCESRV_INTERFACE_$uname\_SHUTDOWN_SERVER,");
+ $self->pidlnoindent("#else");
+ $self->pidl(".shutdown_server = $name\__op_shutdown_server,");
+ $self->pidlnoindent("#endif");
+ $self->pidl(".interface_by_uuid = $name\__op_interface_by_uuid,");
+ $self->pidl(".interface_by_name = $name\__op_interface_by_name");
+ $self->deindent();
+ $self->pidl("};");
+ $self->pidl("");
+
+ $self->pidl("const struct dcesrv_endpoint_server *$name\_get_ep_server(void)");
+ $self->pidl("{");
+ $self->indent();
+ $self->pidl("return &$name\_ep_server;");
+ $self->deindent();
+ $self->pidl("}");
+}
+
+#####################################################################
+# dcerpc server boilerplate from a parsed IDL structure
+sub parse_interface($)
+{
+ my ($self, $interface) = @_;
+ my $count = 0;
+ my $uif = uc($interface->{NAME});
+
+
+ $self->pidl_hdr("#ifndef __NDR_${uif}_SCOMPAT_H__");
+ $self->pidl_hdr("#define __NDR_${uif}_SCOMPAT_H__");
+ $self->pidl_hdr("");
+ $self->pidl_hdr("struct pipes_struct;");
+ $self->pidl_hdr("struct dcesrv_endpoint_server;");
+ $self->pidl_hdr("struct dcesrv_call_state;");
+ $self->pidl_hdr("");
+ $self->pidl_hdr("const struct dcesrv_endpoint_server *$interface->{NAME}\_get_ep_server(void);");
+ $self->pidl_hdr("");
+
+ if (!defined $interface->{PROPERTIES}->{uuid}) {
+ $self->pidl_hdr("#endif /* __NDR_${uif}_SCOMPAT_H__ */");
+ return;
+ }
+
+ if (!defined $interface->{PROPERTIES}->{version}) {
+ $interface->{PROPERTIES}->{version} = "0.0";
+ }
+
+ foreach my $fn (@{$interface->{FUNCTIONS}}) {
+ if (defined($fn->{OPNUM})) { $count++; }
+ }
+
+ if ($count == 0) {
+ $self->pidl_hdr("#endif /* __NDR_${uif}_SCOMPAT_H__ */");
+ return;
+ }
+
+ $self->pidl("/* $interface->{NAME} - dcerpc server boilerplate generated by pidl */");
+ $self->boilerplate_iface($interface);
+ $self->boilerplate_ep_server($interface);
+
+ $self->pidl_hdr("#endif /* __NDR_${uif}_SCOMPAT_H__ */");
+}
+
+sub Parse($$)
+{
+ my ($self, $ndr, $h_scompat, $header) = @_;
+
+ $self->pidl("/* s3 compat server functions auto-generated by pidl */");
+ $self->pidl("#include \"$header\"");
+ $self->pidl("#include \"$h_scompat\"");
+
+ $self->pidl("#include <librpc/rpc/dcesrv_core.h>");
+ $self->pidl("#include <rpc_server/rpc_config.h>");
+ $self->pidl("#include <rpc_server/rpc_server.h>");
+ $self->pidl("#include <util/debug.h>");
+ $self->pidl("");
+ $self->pidl("enum s3compat_rpc_dispatch {");
+ $self->indent();
+ $self->pidl("S3COMPAT_RPC_DISPATCH_EXTERNAL = 0x00000001,");
+ $self->pidl("S3COMPAT_RPC_DISPATCH_INTERNAL = 0x00000002,");
+ $self->deindent();
+ $self->pidl("};");
+ $self->pidl("");
+
+ foreach my $x (@{$ndr}) {
+ $self->parse_interface($x) if ($x->{TYPE} eq "INTERFACE" and not defined($x->{PROPERTIES}{object}));
+ }
+
+ return ($self->{res}, $self->{res_hdr});
+}
+
+1;
diff --git a/tools/pidl/lib/Parse/Pidl/Samba4/Python.pm b/tools/pidl/lib/Parse/Pidl/Samba4/Python.pm
index f418ac48..d7ccf830 100644
--- a/tools/pidl/lib/Parse/Pidl/Samba4/Python.pm
+++ b/tools/pidl/lib/Parse/Pidl/Samba4/Python.pm
@@ -4,11 +4,10 @@
# released under the GNU GPL
package Parse::Pidl::Samba4::Python;
-
-use Exporter;
-@ISA = qw(Exporter);
+use parent Parse::Pidl::Base;
use strict;
+use warnings;
use Parse::Pidl qw(warning fatal error);
use Parse::Pidl::Typelist qw(hasType resolveType getType mapTypeName expandAlias bitmap_type_fn enum_type_fn);
use Parse::Pidl::Util qw(has_property ParseExpr unmake_str);
@@ -17,6 +16,7 @@ use Parse::Pidl::CUtil qw(get_value_of get_pointer_to);
use Parse::Pidl::Samba4 qw(ArrayDynamicallyAllocated);
use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv EnvSubstituteValue GenerateStructEnv);
+
use vars qw($VERSION);
$VERSION = '0.01';
@@ -34,41 +34,11 @@ sub new($) {
bless($self, $class);
}
-sub pidl_hdr ($$)
-{
- my $self = shift;
- $self->{res_hdr} .= shift;
-}
-
-sub pidl($$)
-{
- my ($self, $d) = @_;
- if ($d) {
- if ((!($d =~ /^#/))) {
- $self->{res} .= $self->{tabs};
- }
- $self->{res} .= $d;
- }
- $self->{res} .= "\n";
-}
-
-sub indent($)
-{
- my ($self) = @_;
- $self->{tabs} .= "\t";
-}
-
-sub deindent($)
-{
- my ($self) = @_;
- $self->{tabs} = substr($self->{tabs}, 0, -1);
-}
-
sub PrettifyTypeName($$)
{
my ($name, $basename) = @_;
- $basename =~ s/^.*\.([^.]+)$/\1/;
+ $basename =~ s/^.*\.([^.]+)$/$1/;
$name =~ s/^$basename\_//;
@@ -83,7 +53,7 @@ sub Import
foreach (@imports) {
$_ = unmake_str($_);
s/\.idl$//;
- $self->pidl_hdr("#include \"librpc/gen_ndr/$_\.h\"\n");
+ $self->pidl_hdr("#include \"librpc/gen_ndr/$_\.h\"");
$self->register_module_import("samba.dcerpc.$_");
}
}
@@ -199,8 +169,16 @@ sub PythonElementGetSet($$$$$$) {
$self->pidl("static PyObject *py_$name\_get_$e->{NAME}(PyObject *obj, void *closure)");
$self->pidl("{");
$self->indent;
- $self->pidl("$cname *object = ($cname *)pytalloc_get_ptr(obj);");
+ $self->pidl("$cname *object = pytalloc_get_ptr(obj);");
$self->pidl("PyObject *py_$e->{NAME};");
+ my $l = $e->{LEVELS}[0];
+ if ($l->{TYPE} eq "POINTER") {
+ $self->pidl("if ($varname == NULL) {");
+ $self->indent;
+ $self->pidl("Py_RETURN_NONE;");
+ $self->deindent;
+ $self->pidl("}");
+ }
$self->ConvertObjectToPython("pytalloc_get_mem_ctx(obj)", $env, $e, $varname, "py_$e->{NAME}", "return NULL;");
$self->pidl("return py_$e->{NAME};");
$self->deindent;
@@ -210,9 +188,8 @@ sub PythonElementGetSet($$$$$$) {
$self->pidl("static int py_$name\_set_$e->{NAME}(PyObject *py_obj, PyObject *value, void *closure)");
$self->pidl("{");
$self->indent;
- $self->pidl("$cname *object = ($cname *)pytalloc_get_ptr(py_obj);");
+ $self->pidl("$cname *object = pytalloc_get_ptr(py_obj);");
my $mem_ctx = "pytalloc_get_mem_ctx(py_obj)";
- my $l = $e->{LEVELS}[0];
my $nl = GetNextLevel($e, $l);
if ($l->{TYPE} eq "POINTER" and
not ($nl->{TYPE} eq "ARRAY" and ($nl->{IS_FIXED} or is_charset_array($e, $nl))) and
@@ -279,10 +256,10 @@ sub PythonStruct($$$$$$)
# If the struct is not public there ndr_pull/ndr_push functions will
# be static so not callable from here
if (has_property($d, "public")) {
- $self->pidl("static PyObject *py_$name\_ndr_pack(PyObject *py_obj)");
+ $self->pidl("static PyObject *py_$name\_ndr_pack(PyObject *py_obj, PyObject *Py_UNUSED(ignored))");
$self->pidl("{");
$self->indent;
- $self->pidl("$cname *object = ($cname *)pytalloc_get_ptr(py_obj);");
+ $self->pidl("$cname *object = pytalloc_get_ptr(py_obj);");
$self->pidl("PyObject *ret = NULL;");
$self->pidl("DATA_BLOB blob;");
$self->pidl("enum ndr_err_code err;");
@@ -312,8 +289,8 @@ sub PythonStruct($$$$$$)
$self->pidl("static PyObject *py_$name\_ndr_unpack(PyObject *py_obj, PyObject *args, PyObject *kwargs)");
$self->pidl("{");
$self->indent;
- $self->pidl("$cname *object = ($cname *)pytalloc_get_ptr(py_obj);");
- $self->pidl("DATA_BLOB blob;");
+ $self->pidl("$cname *object = pytalloc_get_ptr(py_obj);");
+ $self->pidl("DATA_BLOB blob = {.data = NULL, .length = 0};");
$self->pidl("Py_ssize_t blob_length = 0;");
$self->pidl("enum ndr_err_code err;");
$self->pidl("const char * const kwnames[] = { \"data_blob\", \"allow_remaining\", NULL };");
@@ -359,15 +336,15 @@ sub PythonStruct($$$$$$)
$self->pidl("}");
$self->pidl("");
- $self->pidl("static PyObject *py_$name\_ndr_print(PyObject *py_obj)");
+ $self->pidl("static PyObject *py_$name\_ndr_print(PyObject *py_obj, PyObject *Py_UNUSED(ignored))");
$self->pidl("{");
$self->indent;
- $self->pidl("$cname *object = ($cname *)pytalloc_get_ptr(py_obj);");
+ $self->pidl("$cname *object = pytalloc_get_ptr(py_obj);");
$self->pidl("PyObject *ret;");
$self->pidl("char *retstr;");
$self->pidl("");
$self->pidl("retstr = ndr_print_struct_string(pytalloc_get_mem_ctx(py_obj), (ndr_print_fn_t)ndr_print_$name, \"$name\", object);");
- $self->pidl("ret = PyStr_FromString(retstr);");
+ $self->pidl("ret = PyUnicode_FromString(retstr);");
$self->pidl("talloc_free(retstr);");
$self->pidl("");
$self->pidl("return ret;");
@@ -379,7 +356,7 @@ sub PythonStruct($$$$$$)
$self->pidl("static PyMethodDef $py_methods\[] = {");
$self->indent;
$self->pidl("{ \"__ndr_pack__\", (PyCFunction)py_$name\_ndr_pack, METH_NOARGS, \"S.ndr_pack(object) -> blob\\nNDR pack\" },");
- $self->pidl("{ \"__ndr_unpack__\", (PyCFunction)py_$name\_ndr_unpack, METH_VARARGS|METH_KEYWORDS, \"S.ndr_unpack(class, blob, allow_remaining=False) -> None\\nNDR unpack\" },");
+ $self->pidl("{ \"__ndr_unpack__\", PY_DISCARD_FUNC_SIG(PyCFunction,py_$name\_ndr_unpack), METH_VARARGS|METH_KEYWORDS, \"S.ndr_unpack(class, blob, allow_remaining=False) -> None\\nNDR unpack\" },");
$self->pidl("{ \"__ndr_print__\", (PyCFunction)py_$name\_ndr_print, METH_NOARGS, \"S.ndr_print(object) -> None\\nNDR print\" },");
$self->pidl("{ NULL, NULL, 0, NULL }");
$self->deindent;
@@ -387,7 +364,7 @@ sub PythonStruct($$$$$$)
$self->pidl("");
}
- $self->pidl_hdr("static PyTypeObject $name\_Type;\n");
+ $self->pidl_hdr("static PyTypeObject $name\_Type;");
$self->pidl("");
my $docstring = $self->DocString($d, $name);
my $typeobject = "$name\_Type";
@@ -491,7 +468,62 @@ sub PythonFunctionStruct($$$$)
$self->pidl("static PyObject *py_$name\_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)");
$self->pidl("{");
$self->indent;
- $self->pidl("return pytalloc_new($cname, type);");
+
+ # This creates a new, zeroed C structure and python object.
+ # These may not be valid or sensible values, but this is as
+ # well as we can do.
+
+ $self->pidl("PyObject *self = pytalloc_new($cname, type);");
+
+ # If there are any children that are ref pointers, we need to
+ # allocate something for them to point to just as the pull
+ # routine will when parsing the structure from NDR.
+ #
+ # We then make those pointers point to zeroed memory
+ #
+ # A ref pointer is a pointer in the C structure but a scalar
+ # on the wire. It is for a remote function like:
+ #
+ # int foo(int *i)
+ #
+ # This may be called with the pointer by reference eg foo(&i)
+ #
+ # That is why this only goes as far as the next level; deeply
+ # nested pointer chains will end in a NULL.
+
+ my @ref_elements;
+ foreach my $e (@{$fn->{ELEMENTS}}) {
+ if (has_property($e, "ref") && ! has_property($e, "charset")) {
+ if (!has_property($e, 'in') && !has_property($e, 'out')) {
+ die "ref pointer that is not in or out";
+ }
+ push @ref_elements, $e;
+ }
+ }
+ if (@ref_elements) {
+ $self->pidl("$cname *_self = ($cname *)pytalloc_get_ptr(self);");
+ $self->pidl("TALLOC_CTX *mem_ctx = pytalloc_get_mem_ctx(self);");
+ foreach my $e (@ref_elements) {
+ my $ename = $e->{NAME};
+ my $t = mapTypeName($e->{TYPE});
+ my $p = $e->{ORIGINAL}->{POINTERS} // 1;
+ if ($p > 1) {
+ $self->pidl("/* a pointer to a NULL pointer */");
+ $t .= ' ' . '*' x ($p - 1);
+ }
+
+ # We checked in the loop above that each ref
+ # pointer is in or out (or both)
+ if (has_property($e, 'in')) {
+ $self->pidl("_self->in.$ename = talloc_zero(mem_ctx, $t);");
+ }
+
+ if (has_property($e, 'out')) {
+ $self->pidl("_self->out.$ename = talloc_zero(mem_ctx, $t);");
+ }
+ }
+ }
+ $self->pidl("return self;");
$self->deindent;
$self->pidl("}");
$self->pidl("");
@@ -499,19 +531,19 @@ sub PythonFunctionStruct($$$$)
my $py_methods = "NULL";
my $ndr_call = "const struct ndr_interface_call *call = NULL;";
- my $object_ptr = "$cname *object = ($cname *)pytalloc_get_ptr(py_obj);";
+ my $object_ptr = "$cname *object = pytalloc_get_ptr(py_obj);";
- $self->pidl("static PyObject *py_$name\_ndr_opnum(PyTypeObject *type)");
+ $self->pidl("static PyObject *py_$name\_ndr_opnum(PyTypeObject *type, PyObject *Py_UNUSED(ignored))");
$self->pidl("{");
$self->indent;
$self->pidl("");
$self->pidl("");
- $self->pidl("return PyInt_FromLong($fn->{OPNUM});");
+ $self->pidl("return PyLong_FromLong($fn->{OPNUM});");
$self->deindent;
$self->pidl("}");
$self->pidl("");
- $self->pidl("static PyObject *py_$name\_ndr_pack(PyObject *py_obj, int ndr_inout_flags, uint32_t ndr_push_flags)");
+ $self->pidl("static PyObject *py_$name\_ndr_pack(PyObject *py_obj, ndr_flags_type ndr_inout_flags, libndr_flags ndr_push_flags)");
$self->pidl("{");
$self->indent;
$self->pidl("$ndr_call");
@@ -562,7 +594,7 @@ sub PythonFunctionStruct($$$$)
$self->pidl("const char * const kwnames[] = { \"bigendian\", \"ndr64\", NULL };");
$self->pidl("PyObject *bigendian_obj = NULL;");
$self->pidl("PyObject *ndr64_obj = NULL;");
- $self->pidl("uint32_t ndr_push_flags = 0;");
+ $self->pidl("libndr_flags ndr_push_flags = 0;");
$self->pidl("");
$self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, \"|OO:__ndr_pack_in__\",");
$self->indent;
@@ -597,7 +629,7 @@ sub PythonFunctionStruct($$$$)
$self->pidl("const char * const kwnames[] = { \"bigendian\", \"ndr64\", NULL };");
$self->pidl("PyObject *bigendian_obj = NULL;");
$self->pidl("PyObject *ndr64_obj = NULL;");
- $self->pidl("uint32_t ndr_push_flags = 0;");
+ $self->pidl("libndr_flags ndr_push_flags = 0;");
$self->pidl("");
$self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, \"|OO:__ndr_pack_out__\",");
$self->indent;
@@ -626,7 +658,7 @@ sub PythonFunctionStruct($$$$)
$self->pidl("}");
$self->pidl("");
- $self->pidl("static PyObject *py_$name\_ndr_unpack(PyObject *py_obj, const DATA_BLOB *blob, int ndr_inout_flags, uint32_t ndr_pull_flags, bool allow_remaining)");
+ $self->pidl("static PyObject *py_$name\_ndr_unpack(PyObject *py_obj, const DATA_BLOB *blob, ndr_flags_type ndr_inout_flags, libndr_flags ndr_pull_flags, bool allow_remaining)");
$self->pidl("{");
$self->indent;
$self->pidl("$ndr_call");
@@ -703,7 +735,7 @@ sub PythonFunctionStruct($$$$)
$self->pidl("const char * const kwnames[] = { \"data_blob\", \"bigendian\", \"ndr64\", \"allow_remaining\", NULL };");
$self->pidl("PyObject *bigendian_obj = NULL;");
$self->pidl("PyObject *ndr64_obj = NULL;");
- $self->pidl("uint32_t ndr_pull_flags = LIBNDR_FLAG_REF_ALLOC;");
+ $self->pidl("libndr_flags ndr_pull_flags = LIBNDR_FLAG_REF_ALLOC;");
$self->pidl("PyObject *allow_remaining_obj = NULL;");
$self->pidl("bool allow_remaining = false;");
$self->pidl("");
@@ -751,7 +783,7 @@ sub PythonFunctionStruct($$$$)
$self->pidl("const char * const kwnames[] = { \"data_blob\", \"bigendian\", \"ndr64\", \"allow_remaining\", NULL };");
$self->pidl("PyObject *bigendian_obj = NULL;");
$self->pidl("PyObject *ndr64_obj = NULL;");
- $self->pidl("uint32_t ndr_pull_flags = LIBNDR_FLAG_REF_ALLOC;");
+ $self->pidl("libndr_flags ndr_pull_flags = LIBNDR_FLAG_REF_ALLOC;");
$self->pidl("PyObject *allow_remaining_obj = NULL;");
$self->pidl("bool allow_remaining = false;");
$self->pidl("");
@@ -791,7 +823,7 @@ sub PythonFunctionStruct($$$$)
$self->pidl("}");
$self->pidl("");
- $self->pidl("static PyObject *py_$name\_ndr_print(PyObject *py_obj, const char *name, int ndr_inout_flags)");
+ $self->pidl("static PyObject *py_$name\_ndr_print(PyObject *py_obj, const char *name, ndr_flags_type ndr_inout_flags)");
$self->pidl("{");
$self->indent;
$self->pidl("$ndr_call");
@@ -809,7 +841,7 @@ sub PythonFunctionStruct($$$$)
$self->pidl("call = &ndr_table_$iface\.calls[$fn->{OPNUM}];");
$self->pidl("");
$self->pidl("retstr = ndr_print_function_string(pytalloc_get_mem_ctx(py_obj), call->ndr_print, name, ndr_inout_flags, object);");
- $self->pidl("ret = PyStr_FromString(retstr);");
+ $self->pidl("ret = PyUnicode_FromString(retstr);");
$self->pidl("TALLOC_FREE(retstr);");
$self->pidl("");
$self->pidl("return ret;");
@@ -817,7 +849,7 @@ sub PythonFunctionStruct($$$$)
$self->pidl("}");
$self->pidl("");
- $self->pidl("static PyObject *py_$name\_ndr_print_in(PyObject *py_obj)");
+ $self->pidl("static PyObject *py_$name\_ndr_print_in(PyObject *py_obj, PyObject *Py_UNUSED(ignored))");
$self->pidl("{");
$self->indent;
$self->pidl("return py_$name\_ndr_print(py_obj, \"$name\_in\", NDR_IN);");
@@ -825,7 +857,7 @@ sub PythonFunctionStruct($$$$)
$self->pidl("}");
$self->pidl("");
- $self->pidl("static PyObject *py_$name\_ndr_print_out(PyObject *py_obj)");
+ $self->pidl("static PyObject *py_$name\_ndr_print_out(PyObject *py_obj, PyObject *Py_UNUSED(ignored))");
$self->pidl("{");
$self->indent;
$self->pidl("return py_$name\_ndr_print(py_obj, \"$name\_out\", NDR_OUT);");
@@ -840,19 +872,19 @@ sub PythonFunctionStruct($$$$)
$self->indent;
$self->pidl("\"$modulename.$prettyname.opnum() -> ".sprintf("%d (0x%02x)", $fn->{OPNUM}, $fn->{OPNUM})." \" },");
$self->deindent;
- $self->pidl("{ \"__ndr_pack_in__\", (PyCFunction)py_$name\_ndr_pack_in, METH_VARARGS|METH_KEYWORDS,");
+ $self->pidl("{ \"__ndr_pack_in__\", PY_DISCARD_FUNC_SIG(PyCFunction,py_$name\_ndr_pack_in), METH_VARARGS|METH_KEYWORDS,");
$self->indent;
$self->pidl("\"S.ndr_pack_in(object, bigendian=False, ndr64=False) -> blob\\nNDR pack input\" },");
$self->deindent;
- $self->pidl("{ \"__ndr_pack_out__\", (PyCFunction)py_$name\_ndr_pack_out, METH_VARARGS|METH_KEYWORDS,");
+ $self->pidl("{ \"__ndr_pack_out__\", PY_DISCARD_FUNC_SIG(PyCFunction,py_$name\_ndr_pack_out), METH_VARARGS|METH_KEYWORDS,");
$self->indent;
$self->pidl("\"S.ndr_pack_out(object, bigendian=False, ndr64=False) -> blob\\nNDR pack output\" },");
$self->deindent;
- $self->pidl("{ \"__ndr_unpack_in__\", (PyCFunction)py_$name\_ndr_unpack_in, METH_VARARGS|METH_KEYWORDS,");
+ $self->pidl("{ \"__ndr_unpack_in__\", PY_DISCARD_FUNC_SIG(PyCFunction,py_$name\_ndr_unpack_in), METH_VARARGS|METH_KEYWORDS,");
$self->indent;
$self->pidl("\"S.ndr_unpack_in(class, blob, bigendian=False, ndr64=False, allow_remaining=False) -> None\\nNDR unpack input\" },");
$self->deindent;
- $self->pidl("{ \"__ndr_unpack_out__\", (PyCFunction)py_$name\_ndr_unpack_out, METH_VARARGS|METH_KEYWORDS,");
+ $self->pidl("{ \"__ndr_unpack_out__\", PY_DISCARD_FUNC_SIG(PyCFunction,py_$name\_ndr_unpack_out), METH_VARARGS|METH_KEYWORDS,");
$self->indent;
$self->pidl("\"S.ndr_unpack_out(class, blob, bigendian=False, ndr64=False, allow_remaining=False) -> None\\nNDR unpack output\" },");
$self->deindent;
@@ -863,7 +895,7 @@ sub PythonFunctionStruct($$$$)
$self->pidl("};");
$self->pidl("");
- $self->pidl_hdr("static PyTypeObject $name\_Type;\n");
+ $self->pidl_hdr("static PyTypeObject $name\_Type;");
$self->pidl("");
my $docstring = $self->DocString($fn, $name);
my $typeobject = "$name\_Type";
@@ -1235,7 +1267,7 @@ sub PythonType($$$$)
$self->pidl("PyObject *in = NULL;");
$self->pidl("$typename *out = NULL;");
$self->pidl("");
- $self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, \"OiO:import\",");
+ $self->pidl("if (!PyArg_ParseTupleAndKeywords(args, kwargs, \"OiO:export\",");
$self->indent;
$self->pidl("discard_const_p(char *, kwnames),");
$self->pidl("&mem_ctx_obj,");
@@ -1269,12 +1301,12 @@ sub PythonType($$$$)
$py_methods = "py_$d->{NAME}_methods";
$self->pidl("static PyMethodDef $py_methods\[] = {");
$self->indent;
- $self->pidl("{ \"__import__\", (PyCFunction)py_$d->{NAME}\_import,");
+ $self->pidl("{ \"__import__\", PY_DISCARD_FUNC_SIG(PyCFunction,py_$d->{NAME}\_import),");
$self->indent;
$self->pidl("METH_VARARGS|METH_KEYWORDS|METH_CLASS,");
$self->pidl("\"T.__import__(mem_ctx, level, in) => ret.\" },");
$self->deindent;
- $self->pidl("{ \"__export__\", (PyCFunction)py_$d->{NAME}\_export,");
+ $self->pidl("{ \"__export__\", PY_DISCARD_FUNC_SIG(PyCFunction,py_$d->{NAME}\_export),");
$self->indent;
$self->pidl("METH_VARARGS|METH_KEYWORDS|METH_CLASS,");
$self->pidl("\"T.__export__(mem_ctx, level, in) => ret.\" },");
@@ -1294,7 +1326,7 @@ sub PythonType($$$$)
$self->pidl("");
$self->pidl("");
- $self->pidl_hdr("static PyTypeObject $typeobject;\n");
+ $self->pidl_hdr("static PyTypeObject $typeobject;");
$self->pidl("static PyTypeObject $typeobject = {");
$self->indent;
$self->pidl("PyVarObject_HEAD_INIT(NULL, 0)");
@@ -1349,7 +1381,7 @@ sub Interface($$$)
}
if (defined $interface->{PROPERTIES}->{uuid}) {
- $self->pidl_hdr("static PyTypeObject $interface->{NAME}_InterfaceType;\n");
+ $self->pidl_hdr("static PyTypeObject $interface->{NAME}_InterfaceType;");
$self->pidl("");
my @fns = ();
@@ -1387,7 +1419,7 @@ sub Interface($$$)
my ($infn, $outfn, $callfn, $prettyname, $docstring, $opnum) = @$d;
$self->pidl("{ \"$prettyname\", $docstring, (py_dcerpc_call_fn)$callfn, (py_data_pack_fn)$infn, (py_data_unpack_fn)$outfn, $opnum, &ndr_table_$interface->{NAME} },");
}
- $self->pidl("{ NULL }");
+ $self->pidl("{0}");
$self->deindent;
$self->pidl("};");
$self->pidl("");
@@ -1446,9 +1478,9 @@ sub Interface($$$)
$self->pidl("");
- my $signature = "\"$interface->{NAME}_abstract_syntax()\\n\"";
+ $signature = "\"$interface->{NAME}_abstract_syntax()\\n\"";
- my $docstring = $self->DocString($interface, $interface->{NAME}."_syntax");
+ $docstring = $self->DocString($interface, $interface->{NAME}."_syntax");
if ($docstring) {
$docstring = "$signature$docstring";
@@ -1482,7 +1514,7 @@ sub Interface($$$)
""]);
}
- $self->pidl_hdr("\n");
+ $self->pidl_hdr("");
}
sub register_module_method($$$$$)
@@ -1635,7 +1667,6 @@ sub ConvertStringFromPythonData($$$$$)
$self->pidl("unicode = PyUnicode_AsEncodedString($py_var, \"utf-8\", \"ignore\");");
$self->pidl("if (unicode == NULL) {");
$self->indent;
- $self->pidl("PyErr_NoMemory();");
$self->pidl("$fail");
$self->deindent;
$self->pidl("}");
@@ -1669,6 +1700,27 @@ sub ConvertStringFromPythonData($$$$$)
$self->pidl("}");
}
+sub ConvertU16StringFromPythonData($$$$$)
+{
+ my ($self, $mem_ctx, $py_var, $target, $fail) = @_;
+
+ $self->pidl("{");
+ $self->indent;
+ $self->pidl("unsigned char *str = NULL;");
+ $self->pidl("");
+ $self->pidl("str = PyUtf16String_FromBytes(");
+ $self->pidl(" $mem_ctx, $py_var);");
+ $self->pidl("if (str == NULL) {");
+ $self->indent;
+ $self->pidl("$fail");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+ $self->pidl("$target = str;");
+ $self->deindent;
+ $self->pidl("}");
+}
+
sub ConvertObjectFromPythonData($$$$$$;$$)
{
my ($self, $mem_ctx, $cvar, $ctype, $target, $fail, $location, $switch) = @_;
@@ -1715,21 +1767,8 @@ sub ConvertObjectFromPythonData($$$$$$;$$)
$self->pidl("}");
$self->pidl("if (test_var > uint_max) {");
$self->indent;
- $self->pidl("PyErr_Format(PyExc_OverflowError, \"Expected type %s or %s within range 0 - %llu, got %llu\",\\");
- $self->pidl(" PyInt_Type.tp_name, PyLong_Type.tp_name, uint_max, test_var);");
- $self->pidl($fail);
- $self->deindent;
- $self->pidl("}");
- $self->pidl("$target = test_var;");
- $self->deindent;
- $self->pidl("} else if (PyInt_Check($cvar)) {");
- $self->indent;
- $self->pidl("long test_var;");
- $self->pidl("test_var = PyInt_AsLong($cvar);");
- $self->pidl("if (test_var < 0 || test_var > uint_max) {");
- $self->indent;
- $self->pidl("PyErr_Format(PyExc_OverflowError, \"Expected type %s or %s within range 0 - %llu, got %ld\",\\");
- $self->pidl(" PyInt_Type.tp_name, PyLong_Type.tp_name, uint_max, test_var);");
+ $self->pidl("PyErr_Format(PyExc_OverflowError, \"Expected type %s within range 0 - %llu, got %llu\",");
+ $self->pidl(" PyLong_Type.tp_name, uint_max, test_var);");
$self->pidl($fail);
$self->deindent;
$self->pidl("}");
@@ -1737,8 +1776,8 @@ sub ConvertObjectFromPythonData($$$$$$;$$)
$self->deindent;
$self->pidl("} else {");
$self->indent;
- $self->pidl("PyErr_Format(PyExc_TypeError, \"Expected type %s or %s\",\\");
- $self->pidl(" PyInt_Type.tp_name, PyLong_Type.tp_name);");
+ $self->pidl("PyErr_Format(PyExc_TypeError, \"Expected type %s\",");
+ $self->pidl(" PyLong_Type.tp_name);");
$self->pidl($fail);
$self->deindent;
$self->pidl("}");
@@ -1767,21 +1806,8 @@ sub ConvertObjectFromPythonData($$$$$$;$$)
$self->pidl("}");
$self->pidl("if (test_var < int_min || test_var > int_max) {");
$self->indent;
- $self->pidl("PyErr_Format(PyExc_OverflowError, \"Expected type %s or %s within range %lld - %lld, got %lld\",\\");
- $self->pidl(" PyInt_Type.tp_name, PyLong_Type.tp_name, int_min, int_max, test_var);");
- $self->pidl($fail);
- $self->deindent;
- $self->pidl("}");
- $self->pidl("$target = test_var;");
- $self->deindent;
- $self->pidl("} else if (PyInt_Check($cvar)) {");
- $self->indent;
- $self->pidl("long test_var;");
- $self->pidl("test_var = PyInt_AsLong($cvar);");
- $self->pidl("if (test_var < int_min || test_var > int_max) {");
- $self->indent;
- $self->pidl("PyErr_Format(PyExc_OverflowError, \"Expected type %s or %s within range %lld - %lld, got %ld\",\\");
- $self->pidl(" PyInt_Type.tp_name, PyLong_Type.tp_name, int_min, int_max, test_var);");
+ $self->pidl("PyErr_Format(PyExc_OverflowError, \"Expected type %s within range %lld - %lld, got %lld\",");
+ $self->pidl(" PyLong_Type.tp_name, int_min, int_max, test_var);");
$self->pidl($fail);
$self->deindent;
$self->pidl("}");
@@ -1789,8 +1815,8 @@ sub ConvertObjectFromPythonData($$$$$$;$$)
$self->deindent;
$self->pidl("} else {");
$self->indent;
- $self->pidl("PyErr_Format(PyExc_TypeError, \"Expected type %s or %s\",\\");
- $self->pidl(" PyInt_Type.tp_name, PyLong_Type.tp_name);");
+ $self->pidl("PyErr_Format(PyExc_TypeError, \"Expected type %s\",");
+ $self->pidl(" PyLong_Type.tp_name);");
$self->pidl($fail);
$self->deindent;
$self->pidl("}");
@@ -1803,7 +1829,8 @@ sub ConvertObjectFromPythonData($$$$$$;$$)
my $ctype_name = $self->use_type_variable($ctype);
unless (defined ($ctype_name)) {
error($location, "Unable to determine origin of type `" . mapTypeName($ctype) . "'");
- $self->pidl("PyErr_SetString(PyExc_TypeError, \"Can not convert C Type " . mapTypeName($ctype) . " from Python\");");
+ $self->pidl("PyErr_SetString(PyExc_TypeError, \"Cannot convert Python object to NDR $target\");");
+ $self->pidl("$fail");
return;
}
$self->pidl("PY_CHECK_TYPE($ctype_name, $cvar, $fail);");
@@ -1849,18 +1876,24 @@ sub ConvertObjectFromPythonData($$$$$$;$$)
return;
}
+ if ($actual_ctype->{TYPE} eq "SCALAR" and
+ $actual_ctype->{NAME} eq "u16string") {
+ $self->ConvertU16StringFromPythonData($mem_ctx, $cvar, $target, $fail);
+ return;
+ }
+
if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "NTSTATUS") {
- $self->pidl("$target = NT_STATUS(PyInt_AsLong($cvar));");
+ $self->pidl("$target = NT_STATUS(PyLong_AsLong($cvar));");
return;
}
if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "WERROR") {
- $self->pidl("$target = W_ERROR(PyInt_AsLong($cvar));");
+ $self->pidl("$target = W_ERROR(PyLong_AsLong($cvar));");
return;
}
if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "HRESULT") {
- $self->pidl("$target = HRES_ERROR(PyInt_AsLong($cvar));");
+ $self->pidl("$target = HRES_ERROR(PyLong_AsLong($cvar));");
return;
}
@@ -1893,8 +1926,7 @@ sub ConvertObjectFromPythonLevel($$$$$$$$$)
if ($recurse == 0) {
$self->pidl("if ($py_var == NULL) {");
$self->indent;
- $self->pidl("PyErr_Format(PyExc_AttributeError, \"Cannot delete NDR object: " .
- mapTypeName($var_name) . "\");");
+ $self->pidl("PyErr_Format(PyExc_AttributeError, \"Cannot delete NDR object: $var_name\");");
$self->pidl($fail);
$self->deindent;
$self->pidl("}");
@@ -1902,6 +1934,9 @@ sub ConvertObjectFromPythonLevel($$$$$$$$$)
$recurse = $recurse + 1;
if ($l->{TYPE} eq "POINTER") {
+ my $need_deindent = 0;
+ my $need_deref = 0;
+
if ($l->{POINTER_TYPE} ne "ref") {
$self->pidl("if ($py_var == Py_None) {");
$self->indent;
@@ -1909,10 +1944,13 @@ sub ConvertObjectFromPythonLevel($$$$$$$$$)
$self->deindent;
$self->pidl("} else {");
$self->indent;
+ $need_deindent = 1;
+ if ($nl->{TYPE} eq "POINTER") {
+ $need_deref = 1;
+ }
}
- # if we want to handle more than one level of pointer in python interfaces
- # then this is where we would need to allocate it
- if ($l->{POINTER_TYPE} eq "ref") {
+
+ if ($l->{POINTER_TYPE} eq "ref" or $need_deref == 1) {
$self->pidl("$var_name = talloc_ptrtype($mem_ctx, $var_name);");
$self->pidl("if ($var_name == NULL) {");
$self->indent;
@@ -1932,11 +1970,20 @@ sub ConvertObjectFromPythonLevel($$$$$$$$$)
} else {
$self->pidl("$var_name = NULL;");
}
+ if ($need_deref == 1) {
+ my $ndr_pointer_typename = $self->import_type_variable("samba.dcerpc.base", "ndr_pointer");
+ $self->pidl("$py_var = py_dcerpc_ndr_pointer_deref($ndr_pointer_typename, $py_var);");
+ $self->pidl("if ($py_var == NULL) {");
+ $self->indent;
+ $self->pidl($fail);
+ $self->deindent;
+ $self->pidl("}");
+ }
unless ($nl->{TYPE} eq "DATA" and Parse::Pidl::Typelist::scalar_is_reference($nl->{DATA_TYPE})) {
$var_name = get_value_of($var_name);
}
$self->ConvertObjectFromPythonLevel($env, $mem_ctx, $py_var, $e, $nl, $var_name, $fail, $recurse);
- if ($l->{POINTER_TYPE} ne "ref") {
+ if ($need_deindent == 1) {
$self->deindent;
$self->pidl("}");
}
@@ -1955,7 +2002,7 @@ sub ConvertObjectFromPythonLevel($$$$$$$$$)
$self->pidl("int $counter;");
if (ArrayDynamicallyAllocated($e, $l)) {
$self->pidl("$var_name = talloc_array_ptrtype($mem_ctx, $var_name, PyList_GET_SIZE($py_var));");
- $self->pidl("if (!$var_name) { $fail; }");
+ $self->pidl("if (!$var_name) { $fail }");
$self->pidl("talloc_set_name_const($var_name, \"ARRAY: $var_name\");");
} else {
$self->pidl("if (ARRAY_SIZE($var_name) != PyList_GET_SIZE($py_var)) {");
@@ -1967,7 +2014,11 @@ sub ConvertObjectFromPythonLevel($$$$$$$$$)
}
$self->pidl("for ($counter = 0; $counter < PyList_GET_SIZE($py_var); $counter++) {");
$self->indent;
- $self->ConvertObjectFromPythonLevel($env, $var_name, "PyList_GET_ITEM($py_var, $counter)", $e, $nl, $var_name."[$counter]", $fail, 0);
+ if (ArrayDynamicallyAllocated($e, $l)) {
+ $self->ConvertObjectFromPythonLevel($env, $var_name, "PyList_GET_ITEM($py_var, $counter)", $e, $nl, "($var_name)"."[$counter]", $fail, 0);
+ } else {
+ $self->ConvertObjectFromPythonLevel($env, $mem_ctx, "PyList_GET_ITEM($py_var, $counter)", $e, $nl, "($var_name)"."[$counter]", $fail, 0);
+ }
$self->deindent;
$self->pidl("}");
$self->deindent;
@@ -2015,15 +2066,15 @@ sub ConvertScalarToPython($$$$)
$ctypename = expandAlias($ctypename);
if ($ctypename =~ /^(int64|dlong)$/) {
- return "ndr_PyLong_FromLongLong($cvar)";
+ return "PyLong_FromLongLong($cvar)";
}
if ($ctypename =~ /^(uint64|hyper|NTTIME_hyper|NTTIME|NTTIME_1sec|udlong|udlongr|uid_t|gid_t)$/) {
- return "ndr_PyLong_FromUnsignedLongLong($cvar)";
+ return "PyLong_FromUnsignedLongLong($cvar)";
}
if ($ctypename =~ /^(char|int|int8|int16|int32|time_t)$/) {
- return "PyInt_FromLong($cvar)";
+ return "PyLong_FromLong($cvar)";
}
# Needed to ensure unsigned values in a 32 or 16 bit enum is
@@ -2031,11 +2082,11 @@ sub ConvertScalarToPython($$$$)
# possibly 64 bit unsigned long. (enums are signed in C,
# unsigned in NDR)
if ($ctypename =~ /^(uint32|uint3264)$/) {
- return "ndr_PyLong_FromUnsignedLongLong((uint32_t)$cvar)";
+ return "PyLong_FromUnsignedLongLong((uint32_t)($cvar))";
}
if ($ctypename =~ /^(uint|uint8|uint16|uint1632)$/) {
- return "PyInt_FromLong((uint16_t)$cvar)";
+ return "PyLong_FromLong((uint16_t)($cvar))";
}
if ($ctypename eq "DATA_BLOB") {
@@ -2062,6 +2113,10 @@ sub ConvertScalarToPython($$$$)
return "PyString_FromStringOrNULL($cvar)";
}
+ if ($ctypename eq "u16string") {
+ return "PyBytes_FromUtf16StringOrNULL($cvar)";
+ }
+
# Not yet supported
if ($ctypename eq "string_array") {
return "pytalloc_GenericObject_reference_ex($mem_ctx, $cvar)";
@@ -2138,6 +2193,10 @@ sub ConvertObjectToPythonLevel($$$$$$$)
}
if ($l->{TYPE} eq "POINTER") {
+ my $need_wrap = 0;
+ if ($l->{POINTER_TYPE} ne "ref" and $nl->{TYPE} eq "POINTER") {
+ $need_wrap = 1;
+ }
if ($l->{POINTER_TYPE} ne "ref") {
if ($recurse == 0) {
$self->pidl("if ($var_name == NULL) {");
@@ -2164,6 +2223,19 @@ sub ConvertObjectToPythonLevel($$$$$$$)
$self->deindent;
$self->pidl("}");
}
+ if ($need_wrap) {
+ my $py_var_wrap = undef;
+ $need_wrap = 1;
+ $self->pidl("{");
+ $self->indent;
+ $py_var_wrap = "py_$e->{NAME}_level_$l->{LEVEL_INDEX}";
+ $self->pidl("PyObject *$py_var_wrap = $py_var;");
+ my $ndr_pointer_typename = $self->import_type_variable("samba.dcerpc.base", "ndr_pointer");
+ $self->pidl("$py_var = py_dcerpc_ndr_pointer_wrap($ndr_pointer_typename, $py_var_wrap);");
+ $self->pidl("Py_XDECREF($py_var_wrap);");
+ $self->deindent;
+ $self->pidl("}");
+ }
} elsif ($l->{TYPE} eq "ARRAY") {
if ($pl && $pl->{TYPE} eq "POINTER") {
$var_name = get_pointer_to($var_name);
@@ -2199,7 +2271,11 @@ sub ConvertObjectToPythonLevel($$$$$$$)
$self->indent;
my $member_var = "py_$e->{NAME}_$l->{LEVEL_INDEX}";
$self->pidl("PyObject *$member_var;");
- $self->ConvertObjectToPythonLevel($var_name, $env, $e, $nl, $var_name."[$counter]", $member_var, $fail, $recurse);
+ if (ArrayDynamicallyAllocated($e, $l)) {
+ $self->ConvertObjectToPythonLevel($var_name, $env, $e, $nl, "($var_name)"."[$counter]", $member_var, $fail, $recurse);
+ } else {
+ $self->ConvertObjectToPythonLevel($mem_ctx, $env, $e, $nl, "($var_name)"."[$counter]", $member_var, $fail, $recurse);
+ }
$self->pidl("PyList_SetItem($py_var, $counter, $member_var);");
$self->deindent;
$self->pidl("}");
@@ -2219,6 +2295,10 @@ sub ConvertObjectToPythonLevel($$$$$$$)
}
my $conv = $self->ConvertObjectToPythonData($mem_ctx, $l->{DATA_TYPE}, $var_name, $e->{ORIGINAL});
$self->pidl("$py_var = $conv;");
+ if ($conv eq "NULL") {
+ $self->pidl("PyErr_SetString(PyExc_NotImplementedError, \"Cannot convert NDR $var_name to Python\");");
+ $self->pidl("$fail");
+ }
} elsif ($l->{TYPE} eq "SUBCONTEXT") {
$self->ConvertObjectToPythonLevel($mem_ctx, $env, $e, $nl, $var_name, $py_var, $fail, $recurse);
} else {
@@ -2240,19 +2320,37 @@ sub Parse($$$$$)
$self->{BASENAME} = $basename;
+ my $ndr_hdr_include = "";
+ if (defined($ndr_hdr)) {
+ $ndr_hdr_include = "#include \"$ndr_hdr\"";
+ }
$self->pidl_hdr("
/* Python wrapper functions auto-generated by pidl */
#define PY_SSIZE_T_CLEAN 1 /* We use Py_ssize_t for PyArg_ParseTupleAndKeywords */
-#include <Python.h>
+#include \"lib/replace/system/python.h\"
#include \"python/py3compat.h\"
#include \"includes.h\"
+#include \"python/modules.h\"
#include <pytalloc.h>
#include \"librpc/rpc/pyrpc.h\"
#include \"librpc/rpc/pyrpc_util.h\"
#include \"$hdr\"
-#include \"$ndr_hdr\"
+$ndr_hdr_include
/*
+ * Suppress compiler warnings if the generated code does not call these
+ * functions
+ */
+#ifndef _MAYBE_UNUSED_
+#ifdef __has_attribute
+#if __has_attribute(unused)
+#define _MAYBE_UNUSED_ __attribute__ ((unused))
+#else
+#define _MAYBE_UNUSED_
+#endif
+#endif
+#endif
+/*
* These functions are here to ensure they can be optimized out by
* the compiler based on the constant input values
*/
@@ -2273,7 +2371,7 @@ static inline unsigned long long ndr_sizeof2uintmax(size_t var_size)
return 0;
}
-static inline long long ndr_sizeof2intmax(size_t var_size)
+static inline _MAYBE_UNUSED_ long long ndr_sizeof2intmax(size_t var_size)
{
switch (var_size) {
case 8:
@@ -2288,25 +2386,6 @@ static inline long long ndr_sizeof2intmax(size_t var_size)
return 0;
}
-
-static inline PyObject *ndr_PyLong_FromLongLong(long long v)
-{
- if (v > LONG_MAX || v < LONG_MIN) {
- return PyLong_FromLongLong(v);
- } else {
- return PyInt_FromLong(v);
- }
-}
-
-static inline PyObject *ndr_PyLong_FromUnsignedLongLong(unsigned long long v)
-{
- if (v > LONG_MAX) {
- return PyLong_FromUnsignedLongLong(v);
- } else {
- return PyInt_FromLong(v);
- }
-}
-
");
foreach my $x (@$ndr) {
@@ -2340,9 +2419,9 @@ static inline PyObject *ndr_PyLong_FromUnsignedLongLong(unsigned long long v)
$self->pidl("MODULE_INIT_FUNC($basename)");
$self->pidl("{");
$self->indent;
- $self->pidl("PyObject *m;");
+ $self->pidl("PyObject *m = NULL;");
foreach my $h (@{$self->{module_imports}}) {
- $self->pidl("PyObject *$h->{'key'};");
+ $self->pidl("PyObject *$h->{'key'} = NULL;");
}
$self->pidl("");
@@ -2351,20 +2430,20 @@ static inline PyObject *ndr_PyLong_FromUnsignedLongLong(unsigned long long v)
my $module_path = $h->{'val'};
$self->pidl("$var_name = PyImport_ImportModule(\"$module_path\");");
$self->pidl("if ($var_name == NULL)");
- $self->pidl("\treturn NULL;");
+ $self->pidl("\tgoto out;");
$self->pidl("");
}
foreach my $h (@{$self->{type_imports}}) {
my $type_var = "$h->{'key'}\_Type";
my $module_path = $h->{'val'};
- $self->pidl_hdr("static PyTypeObject *$type_var;\n");
+ $self->pidl_hdr("static PyTypeObject *$type_var;");
my $pretty_name = PrettifyTypeName($h->{'key'}, $module_path);
my $module_var = "dep_$module_path";
$module_var =~ s/\./_/g;
$self->pidl("$type_var = (PyTypeObject *)PyObject_GetAttrString($module_var, \"$pretty_name\");");
$self->pidl("if ($type_var == NULL)");
- $self->pidl("\treturn NULL;");
+ $self->pidl("\tgoto out;");
$self->pidl("");
}
@@ -2372,7 +2451,7 @@ static inline PyObject *ndr_PyLong_FromUnsignedLongLong(unsigned long long v)
foreach (@{$self->{ready_types}}) {
$self->pidl("if (PyType_Ready($_) < 0)");
- $self->pidl("\treturn NULL;");
+ $self->pidl("\tgoto out;");
}
$self->pidl($_) foreach (@{$self->{postreadycode}});
@@ -2388,16 +2467,16 @@ static inline PyObject *ndr_PyLong_FromUnsignedLongLong(unsigned long long v)
$self->pidl("m = PyModule_Create(&moduledef);");
$self->pidl("if (m == NULL)");
- $self->pidl("\treturn NULL;");
+ $self->pidl("\tgoto out;");
$self->pidl("");
foreach my $h (@{$self->{constants}}) {
my $pretty_name = PrettifyTypeName($h->{'key'}, $basename);
my $py_obj;
my ($ctype, $cvar) = @{$h->{'val'}};
if ($cvar =~ /^[0-9]+$/ or $cvar =~ /^0x[0-9a-fA-F]+$/) {
- $py_obj = "ndr_PyLong_FromUnsignedLongLong($cvar)";
+ $py_obj = "PyLong_FromUnsignedLongLong($cvar)";
} elsif ($cvar =~ /^".*"$/) {
- $py_obj = "PyStr_FromString($cvar)";
+ $py_obj = "PyUnicode_FromString($cvar)";
} else {
$py_obj = $self->ConvertObjectToPythonData("NULL", expandAlias($ctype), $cvar, undef);
}
@@ -2414,7 +2493,11 @@ static inline PyObject *ndr_PyLong_FromUnsignedLongLong(unsigned long long v)
$self->pidl("#ifdef PY_MOD_".uc($basename)."_PATCH");
$self->pidl("PY_MOD_".uc($basename)."_PATCH(m);");
$self->pidl("#endif");
-
+ $self->pidl("out:");
+ foreach my $h (@{$self->{module_imports}}) {
+ my $mod_var = $h->{'key'};
+ $self->pidl("Py_XDECREF($mod_var);");
+ }
$self->pidl("return m;");
$self->pidl("");
$self->deindent;
diff --git a/tools/pidl/lib/Parse/Pidl/Samba4/TDR.pm b/tools/pidl/lib/Parse/Pidl/Samba4/TDR.pm
index c0749304..c3282879 100644
--- a/tools/pidl/lib/Parse/Pidl/Samba4/TDR.pm
+++ b/tools/pidl/lib/Parse/Pidl/Samba4/TDR.pm
@@ -9,25 +9,20 @@ use Parse::Pidl::Util qw(has_property ParseExpr is_constant);
use Parse::Pidl::Samba4 qw(is_intree choose_header);
use Parse::Pidl::Typelist qw(mapTypeName);
-use Exporter;
-@ISA = qw(Exporter);
-@EXPORT_OK = qw(ParserType $ret $ret_hdr);
+use base Parse::Pidl::Base;
use vars qw($VERSION);
$VERSION = '0.01';
use strict;
+use warnings;
sub new($) {
my ($class) = shift;
- my $self = { ret => "", ret_hdr => "", tabs => "" };
+ my $self = { res => "", res_hdr => "", tabs => "" };
bless($self, $class);
}
-sub indent($) { my $self = shift; $self->{tabs}.="\t"; }
-sub deindent($) { my $self = shift; $self->{tabs} = substr($self->{tabs}, 1); }
-sub pidl($$) { my $self = shift; $self->{ret} .= $self->{tabs}.(shift)."\n"; }
-sub pidl_hdr($$) { my $self = shift; $self->{ret_hdr} .= (shift)."\n"; }
sub typearg($) {
my $t = shift;
return(", const char *name") if ($t eq "print");
@@ -277,7 +272,7 @@ sub Parser($$$$)
$self->pidl_hdr("");
foreach (@$idl) { $self->ParserInterface($_) if ($_->{TYPE} eq "INTERFACE"); }
- return ($self->{ret_hdr}, $self->{ret});
+ return ($self->{res_hdr}, $self->{res});
}
1;
diff --git a/tools/pidl/lib/Parse/Pidl/Samba4/Template.pm b/tools/pidl/lib/Parse/Pidl/Samba4/Template.pm
index 175bb124..870d2388 100644
--- a/tools/pidl/lib/Parse/Pidl/Samba4/Template.pm
+++ b/tools/pidl/lib/Parse/Pidl/Samba4/Template.pm
@@ -11,6 +11,7 @@ $VERSION = '0.01';
use Parse::Pidl::Util qw(genpad);
use strict;
+use warnings;
my($res);
diff --git a/tools/pidl/lib/Parse/Pidl/Typelist.pm b/tools/pidl/lib/Parse/Pidl/Typelist.pm
index 774554f0..2a98a16b 100644
--- a/tools/pidl/lib/Parse/Pidl/Typelist.pm
+++ b/tools/pidl/lib/Parse/Pidl/Typelist.pm
@@ -7,27 +7,30 @@ package Parse::Pidl::Typelist;
require Exporter;
@ISA = qw(Exporter);
-@EXPORT_OK = qw(hasType getType resolveType mapTypeName scalar_is_reference expandAlias
+@EXPORT_OK = qw(hasType getType resolveType mapTypeName mapTypeSpecifier scalar_is_reference expandAlias
mapScalarType addType typeIs is_signed is_scalar enum_type_fn
bitmap_type_fn mapType typeHasBody is_fixed_size_scalar
+ is_string_type
);
use vars qw($VERSION);
$VERSION = '0.01';
use Parse::Pidl::Util qw(has_property);
use strict;
+use warnings;
my %types = ();
my @reference_scalars = (
"string", "string_array", "nbt_string", "dns_string",
"wrepl_nbt_name", "dnsp_name", "dnsp_string",
- "ipv4address", "ipv6address"
+ "ipv4address", "ipv6address", "u16string"
);
my @non_fixed_size_scalars = (
"string", "string_array", "nbt_string", "dns_string",
- "wrepl_nbt_name", "dnsp_name", "dnsp_string"
+ "wrepl_nbt_name", "dnsp_name", "dnsp_string",
+ "u16string"
);
# a list of known scalar types
@@ -45,6 +48,7 @@ my %scalars = (
"int3264" => "int32_t",
"uint3264" => "uint32_t",
"hyper" => "uint64_t",
+ "int64" => "int64_t",
"dlong" => "int64_t",
"udlong" => "uint64_t",
"udlongr" => "uint64_t",
@@ -52,6 +56,7 @@ my %scalars = (
"pointer" => "void*",
"DATA_BLOB" => "DATA_BLOB",
"string" => "const char *",
+ "u16string" => "const unsigned char *",
"string_array" => "const char **",
"time_t" => "time_t",
"uid_t" => "uid_t",
@@ -70,6 +75,8 @@ my %scalars = (
"ipv6address" => "const char *",
"dnsp_name" => "const char *",
"dnsp_string" => "const char *",
+ "libndr_flags" => "libndr_flags",
+ "ndr_flags_type"=> "ndr_flags_type",
);
my %aliases = (
@@ -87,6 +94,18 @@ my %aliases = (
"mode_t" => "uint32",
);
+my %format_specifiers = (
+ "char" => "c",
+ "int8_t", => "\"PRId8\"",
+ "int16_t", => "\"PRId16\"",
+ "int32_t", => "\"PRId32\"",
+ "int64_t", => "\"PRId64\"",
+ "uint8_t", => "\"PRIu8\"",
+ "uint16_t", => "\"PRIu16\"",
+ "uint32_t", => "\"PRIu32\"",
+ "uint64_t", => "\"PRIu64\""
+);
+
sub expandAlias($)
{
my $name = shift;
@@ -119,8 +138,18 @@ sub resolveType($)
my ($ctype) = @_;
if (not hasType($ctype)) {
- # assume struct typedef
- return { TYPE => "TYPEDEF", NAME => $ctype, DATA => { TYPE => "STRUCT" } };
+ if (! ref $ctype) {
+ # it looks like a name.
+ # assume struct typedef
+ return { TYPE => "TYPEDEF", NAME => $ctype, DATA => { TYPE => "STRUCT" } };
+ }
+ if ($ctype->{NAME} && ($ctype->{TYPE} eq "STRUCT")) {
+ return {
+ TYPE => "TYPEDEF",
+ NAME => $ctype->{NAME},
+ DATA => $ctype
+ };
+ }
} else {
return getType($ctype);
}
@@ -158,7 +187,7 @@ sub hasType($)
my $t = shift;
if (ref($t) eq "HASH") {
return 1 if (not defined($t->{NAME}));
- return 1 if (defined($types{$t->{NAME}}) and
+ return 1 if (defined($types{$t->{NAME}}) and
$types{$t->{NAME}}->{TYPE} eq $t->{TYPE});
return 0;
}
@@ -184,13 +213,13 @@ sub is_scalar($)
sub is_scalar($);
my $type = shift;
- return 1 if (ref($type) eq "HASH" and
- ($type->{TYPE} eq "SCALAR" or $type->{TYPE} eq "ENUM" or
+ return 1 if (ref($type) eq "HASH" and
+ ($type->{TYPE} eq "SCALAR" or $type->{TYPE} eq "ENUM" or
$type->{TYPE} eq "BITMAP"));
if (my $dt = getType($type)) {
return is_scalar($dt->{DATA}) if ($dt->{TYPE} eq "TYPEDEF");
- return 1 if ($dt->{TYPE} eq "SCALAR" or $dt->{TYPE} eq "ENUM" or
+ return 1 if ($dt->{TYPE} eq "SCALAR" or $dt->{TYPE} eq "ENUM" or
$dt->{TYPE} eq "BITMAP");
}
@@ -214,6 +243,13 @@ sub scalar_is_reference($)
return 0;
}
+sub is_string_type
+{
+ my ($t) = @_;
+
+ return ($t eq "string" or $t eq "u16string");
+}
+
sub RegisterScalars()
{
foreach (keys %scalars) {
@@ -314,6 +350,14 @@ sub mapTypeName($)
}
+sub mapTypeSpecifier($)
+{
+ my $t = shift;
+ return undef unless defined($t);
+
+ return $format_specifiers{$t};
+}
+
sub LoadIdl($;$)
{
my $idl = shift;
diff --git a/tools/pidl/lib/Parse/Pidl/Util.pm b/tools/pidl/lib/Parse/Pidl/Util.pm
index 83e23937..7a6039ba 100644
--- a/tools/pidl/lib/Parse/Pidl/Util.pm
+++ b/tools/pidl/lib/Parse/Pidl/Util.pm
@@ -6,11 +6,12 @@ package Parse::Pidl::Util;
require Exporter;
@ISA = qw(Exporter);
-@EXPORT = qw(has_property property_matches ParseExpr ParseExprExt is_constant make_str unmake_str print_uuid MyDumper genpad);
+@EXPORT = qw(has_property property_matches ParseExpr ParseExprExt is_constant make_str unmake_str print_uuid MyDumper genpad parse_int parse_range);
use vars qw($VERSION);
$VERSION = '0.01';
use strict;
+use warnings;
use Parse::Pidl::Expr;
use Parse::Pidl qw(error);
@@ -190,6 +191,41 @@ sub genpad($)
return "\t"x($nt)." "x($ns);
}
+=item B<parse_int>
+
+Try to convert hex and octal strings to numbers. If a string doesn't
+look hexish or octish it will be left as is. If the unconverted string
+is actually a decimal number, Perl is likely to handle it correctly.
+
+=cut
+
+sub parse_int {
+ my $s = shift;
+ if ($s =~ /^0[xX][0-9A-Fa-f]+$/) {
+ return hex $s;
+ }
+ if ($s =~ /^0[0-7]+$/) {
+ return oct $s;
+ }
+ return $s;
+}
+
+=item B<parse_range>
+
+Read a range specification that might contain hex or octal numbers,
+and work out what those numbers are.
+
+=cut
+
+sub parse_range {
+ my $range = shift;
+ my ($low, $high) = split(/,/, $range, 2);
+ $low = parse_int($low);
+ $high = parse_int($high);
+ return ($low, $high);
+}
+
+
=back
=cut
diff --git a/tools/pidl/lib/Parse/Pidl/Wireshark/Conformance.pm b/tools/pidl/lib/Parse/Pidl/Wireshark/Conformance.pm
index 01a8c473..7f7ef184 100644
--- a/tools/pidl/lib/Parse/Pidl/Wireshark/Conformance.pm
+++ b/tools/pidl/lib/Parse/Pidl/Wireshark/Conformance.pm
@@ -115,6 +115,7 @@ $VERSION = '0.01';
@EXPORT_OK = qw(ReadConformance ReadConformanceFH valid_ft_type valid_base_type);
use strict;
+use warnings;
use Parse::Pidl qw(fatal warning error);
use Parse::Pidl::Util qw(has_property);
diff --git a/tools/pidl/lib/Parse/Pidl/Wireshark/NDR.pm b/tools/pidl/lib/Parse/Pidl/Wireshark/NDR.pm
index ada8dd66..6f672330 100644
--- a/tools/pidl/lib/Parse/Pidl/Wireshark/NDR.pm
+++ b/tools/pidl/lib/Parse/Pidl/Wireshark/NDR.pm
@@ -21,8 +21,9 @@ use Exporter;
@EXPORT_OK = qw(field2name %res PrintIdl StripPrefixes RegisterInterfaceHandoff register_hf_field CheckUsed ProcessImport ProcessInclude find_type DumpEttList DumpEttDeclaration DumpHfList DumpHfDeclaration DumpFunctionTable register_type register_ett);
use strict;
+use warnings;
use Parse::Pidl qw(error warning);
-use Parse::Pidl::Typelist qw(getType);
+use Parse::Pidl::Typelist qw(getType mapScalarType);
use Parse::Pidl::Util qw(has_property property_matches make_str);
use Parse::Pidl::NDR qw(ContainsString GetNextLevel);
use Parse::Pidl::Dump qw(DumpType DumpFunction);
@@ -41,6 +42,26 @@ my %ptrtype_mappings = (
"ptr" => "NDR_POINTER_PTR"
);
+my %variable_scalars = (
+ "int1632" => "int32_t",
+ "uint1632" => "uint32_t",
+ "int3264" => "int64_t",
+ "uint3264" => "uint64_t",
+);
+
+# map from an IDL type to a C header type, using the on-the-wire length.
+# Produces different results than mapScalarType in Parse::Pidl::Typelist
+# for the types that have different wire lengths in NDR and NDR64 (i.e.,
+# includes the padding for uint1632 and uint3264, unlike that function.)
+sub mapWireScalarType($)
+{
+ my ($name) = shift;
+
+ return $variable_scalars{$name} if defined($variable_scalars{$name});
+
+ return mapScalarType($name);
+}
+
sub StripPrefixes($$)
{
my ($s, $prefixes) = @_;
@@ -151,7 +172,7 @@ sub Enum($$$$)
}
$self->pidl_hdr("extern const value_string $valsstring\[];");
- $self->pidl_hdr("int $dissectorname(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, int hf_index _U_, g$e->{BASE_TYPE} *param _U_);");
+ $self->pidl_hdr("int $dissectorname(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, int hf_index _U_, " . mapWireScalarType($e->{BASE_TYPE}) ." *param _U_);");
$self->pidl_def("const value_string ".$valsstring."[] = {");
foreach (@{$e->{ELEMENTS}}) {
@@ -164,10 +185,10 @@ sub Enum($$$$)
$self->pidl_fn_start($dissectorname);
$self->pidl_code("int");
- $self->pidl_code("$dissectorname(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, int hf_index _U_, g$e->{BASE_TYPE} *param _U_)");
+ $self->pidl_code("$dissectorname(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, int hf_index _U_, " . mapWireScalarType($e->{BASE_TYPE}) . " *param _U_)");
$self->pidl_code("{");
$self->indent;
- $self->pidl_code("g$e->{BASE_TYPE} parameter=0;");
+ $self->pidl_code(mapWireScalarType($e->{BASE_TYPE}) . " parameter=0;");
$self->pidl_code("if (param) {");
$self->indent;
$self->pidl_code("parameter = *param;");
@@ -186,7 +207,9 @@ sub Enum($$$$)
my $enum_size = $e->{BASE_TYPE};
$enum_size =~ s/uint//g;
- $self->register_type($name, "offset = $dissectorname(tvb, offset, pinfo, tree, di, drep, \@HF\@, \@PARAM\@);", "FT_UINT$enum_size", "BASE_DEC", "0", "VALS($valsstring)", $enum_size / 8);
+ my $ws_base = "BASE_DEC";
+ $ws_base = "BASE_HEX" if (property_matches($e, "flag", ".*LIBNDR_PRINT_ARRAY_HEX.*"));
+ $self->register_type($name, "offset = $dissectorname(tvb, offset, pinfo, tree, di, drep, \@HF\@, \@PARAM\@);", "FT_UINT$enum_size", $ws_base, "0", "VALS($valsstring)", $enum_size / 8);
}
sub Pipe($$$$)
@@ -205,11 +228,11 @@ sub Bitmap($$$$)
$self->register_ett("ett_$ifname\_$name");
- $self->pidl_hdr("int $dissectorname(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, int hf_index _U_, guint32 param _U_);");
+ $self->pidl_hdr("int $dissectorname(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, int hf_index _U_, uint32_t param _U_);");
$self->pidl_fn_start($dissectorname);
$self->pidl_code("int");
- $self->pidl_code("$dissectorname(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, int hf_index _U_, guint32 param _U_)");
+ $self->pidl_code("$dissectorname(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, int hf_index _U_, uint32_t param _U_)");
$self->pidl_code("{");
$self->indent;
foreach (@{$e->{ELEMENTS}}) {
@@ -236,7 +259,7 @@ sub Bitmap($$$$)
$self->pidl_code("};");
}
- $self->pidl_code("g$e->{BASE_TYPE} flags;");
+ $self->pidl_code(mapWireScalarType($e->{BASE_TYPE}) . " flags;");
if ($e->{ALIGN} > 1) {
$self->pidl_code("ALIGN_TO_$e->{ALIGN}_BYTES;");
}
@@ -335,9 +358,10 @@ sub ElementLevel($$$$$$$$)
$self->pidl_code("offset = dissect_ndr_u" . $type . "array(tvb, offset, pinfo, tree, di, drep, $myname\_);");
} else {
my $nl = GetNextLevel($e,$l);
+ my $nl_ctype = mapScalarType($nl->{DATA_TYPE});
$self->pidl_code("char *data;");
$self->pidl_code("");
- $self->pidl_code("offset = dissect_ndr_$type" . "string(tvb, offset, pinfo, tree, di, drep, sizeof(g$nl->{DATA_TYPE}), $hf, FALSE, &data);");
+ $self->pidl_code("offset = dissect_ndr_$type" . "string(tvb, offset, pinfo, tree, di, drep, sizeof($nl_ctype), $hf, false, &data);");
$self->pidl_code("proto_item_append_text(tree, \": %s\", data);");
}
}
@@ -350,10 +374,10 @@ sub ElementLevel($$$$$$$$)
if (property_matches($e, "flag", ".*LIBNDR_FLAG_STR_SIZE4.*") and property_matches($e, "flag", ".*LIBNDR_FLAG_STR_LEN4.*")) {
$self->pidl_code("char *data;\n");
- $self->pidl_code("offset = dissect_ndr_cvstring(tvb, offset, pinfo, tree, di, drep, $bs, $hf, FALSE, &data);");
+ $self->pidl_code("offset = dissect_ndr_cvstring(tvb, offset, pinfo, tree, di, drep, $bs, $hf, false, &data);");
$self->pidl_code("proto_item_append_text(tree, \": %s\", data);");
} elsif (property_matches($e, "flag", ".*LIBNDR_FLAG_STR_SIZE4.*")) {
- $self->pidl_code("offset = dissect_ndr_vstring(tvb, offset, pinfo, tree, di, drep, $bs, $hf, FALSE, NULL);");
+ $self->pidl_code("offset = dissect_ndr_vstring(tvb, offset, pinfo, tree, di, drep, $bs, $hf, false, NULL);");
} elsif (property_matches($e, "flag", ".*STR_NULLTERM.*")) {
if ($bs == 2) {
$self->pidl_code("offset = dissect_null_term_wstring(tvb, offset, pinfo, tree, drep, $hf , 0);")
@@ -405,7 +429,7 @@ sub ElementLevel($$$$$$$$)
my $hf2 = $self->register_hf_field($hf."_", "Subcontext length", "$ifname.$pn.$_->{NAME}subcontext", "FT_UINT$num_bits", "BASE_HEX", "NULL", 0, "");
$num_bits = 3264 if ($num_bits == 32);
$self->{hf_used}->{$hf2} = 1;
- $self->pidl_code("guint$num_bits size;");
+ $self->pidl_code("uint${num_bits}_t size;");
$self->pidl_code("int conformant = di->conformant_run;");
$self->pidl_code("tvbuff_t *subtvb;");
$self->pidl_code("");
@@ -413,14 +437,14 @@ sub ElementLevel($$$$$$$$)
# and conformant run skips the dissections of scalars ...
$self->pidl_code("if (!conformant) {");
$self->indent;
- $self->pidl_code("guint32 saved_flags = di->call_data->flags;");
+ $self->pidl_code("uint32_t saved_flags = di->call_data->flags;");
$self->pidl_code("offset = dissect_ndr_uint$num_bits(tvb, offset, pinfo, tree, di, drep, $hf2, &size);");
# This is a subcontext, there is normally no such thing as
# 64 bit NDR is subcontext so we clear the flag so that we can
# continue to dissect handmarshalled stuff with pidl
$self->pidl_code("di->call_data->flags &= ~DCERPC_IS_NDR64;");
- $self->pidl_code("subtvb = tvb_new_subset_length_caplen(tvb, offset, (const gint)size, -1);");
+ $self->pidl_code("subtvb = tvb_new_subset_length_caplen(tvb, offset, (const int)size, -1);");
if ($param ne 0) {
$self->pidl_code("$myname\_(subtvb, 0, pinfo, tree, di, drep, $param);");
} else {
@@ -477,7 +501,7 @@ sub Element($$$$$$)
if (not defined($switch_raw_type)) {
die("Unknown type[$type]\n");
}
- my $switch_type = "g${switch_raw_type}";
+ my $switch_type = mapWireScalarType(${switch_raw_type});
if ($name ne "") {
$moreparam = ", $switch_type *".$name;
@@ -552,10 +576,10 @@ sub Element($$$$$$)
}
next if ($_->{TYPE} eq "SWITCH");
next if (defined($self->{conformance}->{noemit}->{"$dissectorname$add"}));
- $self->pidl_def("static int $dissectorname$add(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_$moreparam);");
+ $self->pidl_def("static int $dissectorname$add(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_$moreparam);");
$self->pidl_fn_start("$dissectorname$add");
$self->pidl_code("static int");
- $self->pidl_code("$dissectorname$add(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_$moreparam)");
+ $self->pidl_code("$dissectorname$add(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_$moreparam)");
$self->pidl_code("{");
$self->indent;
@@ -583,7 +607,7 @@ sub Function($$$)
my %dissectornames;
foreach (@{$fn->{ELEMENTS}}) {
- $dissectornames{$_->{NAME}} = $self->Element($_, $fn->{NAME}, $ifname, undef, undef) if not defined($dissectornames{$_->{NAME}});
+ $dissectornames{$_->{NAME}} = $self->Element($_, $fn->{NAME}, $ifname, undef, ()) if not defined($dissectornames{$_->{NAME}});
}
my $fn_name = $_->{NAME};
@@ -592,18 +616,18 @@ sub Function($$$)
$self->PrintIdl(DumpFunction($fn->{ORIGINAL}));
$self->pidl_fn_start("$ifname\_dissect\_$fn_name\_response");
$self->pidl_code("static int");
- $self->pidl_code("$ifname\_dissect\_${fn_name}_response(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_)");
+ $self->pidl_code("$ifname\_dissect\_${fn_name}_response(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_)");
$self->pidl_code("{");
$self->indent;
if ( not defined($fn->{RETURN_TYPE})) {
} elsif ($fn->{RETURN_TYPE} eq "NTSTATUS" or $fn->{RETURN_TYPE} eq "WERROR" or $fn->{RETURN_TYPE} eq "HRESULT")
{
- $self->pidl_code("guint32 status;\n");
+ $self->pidl_code("uint32_t status;\n");
} elsif (my $type = getType($fn->{RETURN_TYPE})) {
if ($type->{DATA}->{TYPE} eq "ENUM") {
- $self->pidl_code("g".Parse::Pidl::Typelist::enum_type_fn($type->{DATA}) . " status;\n");
+ $self->pidl_code(Parse::Pidl::Typelist::enum_type_fn($type->{DATA}) . "_t status;\n");
} elsif ($type->{DATA}->{TYPE} eq "SCALAR") {
- $self->pidl_code("g$fn->{RETURN_TYPE} status;\n");
+ $self->pidl_code(mapWireScalarType($fn->{RETURN_TYPE}) . " status;\n");
} else {
error($fn, "return type `$fn->{RETURN_TYPE}' not yet supported");
}
@@ -624,22 +648,21 @@ sub Function($$$)
} elsif ($fn->{RETURN_TYPE} eq "NTSTATUS") {
$self->pidl_code("offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep, hf\_$ifname\_status, &status);\n");
$self->pidl_code("if (status != 0)");
- $self->pidl_code("\tcol_append_fstr(pinfo->cinfo, COL_INFO, \", Error: %s\", val_to_str(status, NT_errors, \"Unknown NT status 0x%08x\"));\n");
+ $self->pidl_code("\tcol_append_fstr(pinfo->cinfo, COL_INFO, \", Error: %s\", val_to_str_ext(status, &NT_errors_ext, \"Unknown NT status 0x%08x\"));\n");
$return_types{$ifname}->{"status"} = ["NTSTATUS", "NT Error"];
} elsif ($fn->{RETURN_TYPE} eq "WERROR") {
$self->pidl_code("offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep, hf\_$ifname\_werror, &status);\n");
$self->pidl_code("if (status != 0)");
- $self->pidl_code("\tcol_append_fstr(pinfo->cinfo, COL_INFO, \", Error: %s\", val_to_str(status, WERR_errors, \"Unknown DOS error 0x%08x\"));\n");
+ $self->pidl_code("\tcol_append_fstr(pinfo->cinfo, COL_INFO, \", Error: %s\", val_to_str_ext(status, &WERR_errors_ext, \"Unknown DOS error 0x%08x\"));\n");
$return_types{$ifname}->{"werror"} = ["WERROR", "Windows Error"];
} elsif ($fn->{RETURN_TYPE} eq "HRESULT") {
$self->pidl_code("offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep, hf\_$ifname\_hresult, &status);\n");
$self->pidl_code("if (status != 0)");
- $self->pidl_code("\tcol_append_fstr(pinfo->cinfo, COL_INFO, \", Error: %s\", val_to_str(status, HRES_errors, \"Unknown HRES error 0x%08x\"));\n");
+ $self->pidl_code("\tcol_append_fstr(pinfo->cinfo, COL_INFO, \", Error: %s\", val_to_str_ext(status, &HRES_errors_ext, \"Unknown HRES error 0x%08x\"));\n");
$return_types{$ifname}->{"hresult"} = ["HRESULT", "HRES Windows Error"];
} elsif (my $type = getType($fn->{RETURN_TYPE})) {
if ($type->{DATA}->{TYPE} eq "ENUM") {
- my $return_type = "g".Parse::Pidl::Typelist::enum_type_fn($type->{DATA});
my $return_dissect = "dissect_ndr_" .Parse::Pidl::Typelist::enum_type_fn($type->{DATA});
$self->pidl_code("offset = $return_dissect(tvb, offset, pinfo, tree, di, drep, hf\_$ifname\_$fn->{RETURN_TYPE}_status, &status);");
@@ -661,7 +684,7 @@ sub Function($$$)
$self->pidl_fn_start("$ifname\_dissect\_$fn_name\_request");
$self->pidl_code("static int");
- $self->pidl_code("$ifname\_dissect\_${fn_name}_request(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, guint8 *drep _U_)");
+ $self->pidl_code("$ifname\_dissect\_${fn_name}_request(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_)");
$self->pidl_code("{");
$self->indent;
$self->pidl_code("di->dcerpc_procedure_name=\"${fn_name}\";");
@@ -709,7 +732,7 @@ sub Struct($$$$)
if (not defined($switch_raw_type)) {
die("Unknown type[$_->{TYPE}]\n");
}
- my $switch_type = "g${switch_raw_type}";
+ my $switch_type = mapWireScalarType(${switch_raw_type});
if ($switch_type ne "") {
push @$vars, "$switch_type $v = 0;";
@@ -733,11 +756,11 @@ sub Struct($$$$)
$doalign = 0;
}
- $self->pidl_hdr("int $dissectorname(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, int hf_index _U_, guint32 param _U_);");
+ $self->pidl_hdr("int $dissectorname(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, int hf_index _U_, uint32_t param _U_);");
$self->pidl_fn_start($dissectorname);
$self->pidl_code("int");
- $self->pidl_code("$dissectorname(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, int hf_index _U_, guint32 param _U_)");
+ $self->pidl_code("$dissectorname(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, int hf_index _U_, uint32_t param _U_)");
$self->pidl_code("{");
$self->indent;
$self->pidl_code($_) foreach (@$vars);
@@ -746,7 +769,7 @@ sub Struct($$$$)
$self->pidl_code("proto_tree *tree = NULL;");
}
if (defined($doalign) and $doalign == 0) {
- $self->pidl_code("gboolean oldalign = di->no_align;");
+ $self->pidl_code("bool oldalign = di->no_align;");
}
$self->pidl_code("int old_offset;");
$self->pidl_code("");
@@ -756,7 +779,7 @@ sub Struct($$$$)
$self->pidl_code("ALIGN_TO_$e->{ALIGN}_BYTES;");
}
if ($doalign == 0) {
- $self->pidl_code("di->no_align = TRUE;");
+ $self->pidl_code("di->no_align = true;");
}
$self->pidl_code("");
}
@@ -813,7 +836,7 @@ sub Union($$$$)
foreach (@{$e->{ELEMENTS}}) {
$res.="\n\t\t$_->{CASE}:\n";
if ($_->{TYPE} ne "EMPTY") {
- $res.="\t\t\t".$self->Element($_, $name, $ifname, undef, undef)."\n";
+ $res.="\t\t\t".$self->Element($_, $name, $ifname, undef, ())."\n";
}
$res.="\t\tbreak;\n";
}
@@ -822,20 +845,20 @@ sub Union($$$$)
my $switch_dissect = undef;
my $switch_raw_type = SwitchType($e, $e->{SWITCH_TYPE});
if (defined($switch_raw_type)) {
- $switch_type = "g${switch_raw_type}";
+ $switch_type = mapWireScalarType(${switch_raw_type});
$switch_dissect = "dissect_ndr_${switch_raw_type}";
}
$self->pidl_fn_start($dissectorname);
$self->pidl_code("static int");
- $self->pidl_code("$dissectorname(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* di _U_, guint8 *drep _U_, int hf_index _U_, guint32 param _U_)");
+ $self->pidl_code("$dissectorname(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *parent_tree _U_, dcerpc_info* di _U_, uint8_t *drep _U_, int hf_index _U_, uint32_t param _U_)");
$self->pidl_code("{");
$self->indent;
$self->pidl_code("proto_item *item = NULL;");
$self->pidl_code("proto_tree *tree = NULL;");
$self->pidl_code("int old_offset;");
if (!defined $switch_type) {
- $self->pidl_code("guint32 level = param;");
+ $self->pidl_code("uint32_t level = param;");
} else {
$self->pidl_code("$switch_type level;");
}
@@ -1009,7 +1032,7 @@ sub ProcessInterface($$)
$self->pidl_hdr("#define $define");
$self->pidl_hdr("");
- $self->pidl_def("static gint proto_dcerpc_$x->{NAME} = -1;");
+ $self->pidl_def("static int proto_dcerpc_$x->{NAME};");
$self->register_ett("ett_dcerpc_$x->{NAME}");
$self->register_hf_field("hf_$x->{NAME}_opnum", "Operation", "$x->{NAME}.opnum", "FT_UINT16", "BASE_DEC", "NULL", 0, "");
@@ -1034,7 +1057,7 @@ sub ProcessInterface($$)
my $maj = 0x0000FFFF & $x->{VERSION};
$maj =~ s/\.(.*)$//g;
- $self->pidl_def("static guint16 ver_dcerpc_$x->{NAME} = $maj;");
+ $self->pidl_def("static uint16_t ver_dcerpc_$x->{NAME} = $maj;");
$self->pidl_def("");
}
@@ -1047,7 +1070,7 @@ sub ProcessInterface($$)
my ($type, $desc) = @{$return_types{$x->{NAME}}->{$_}};
my $dt = $self->find_type($type);
$dt or die("Unable to find information about return type `$type'");
- $self->register_hf_field("hf_$x->{NAME}_$_", $desc, "$x->{NAME}.$_", $dt->{FT_TYPE}, "BASE_HEX", $dt->{VALSSTRING}, 0, "");
+ $self->register_hf_field("hf_$x->{NAME}_$_", $desc, "$x->{NAME}.$_", $dt->{FT_TYPE}, $dt->{BASE_TYPE}, $dt->{VALSSTRING}, 0, "");
$self->{hf_used}->{"hf_$x->{NAME}_$_"} = 1;
}
@@ -1105,6 +1128,7 @@ sub Initialize($$)
$self->register_type("uint3264", "offset = dissect_ndr_uint3264(tvb, offset, pinfo, tree, di, drep, \@HF\@, NULL);", "FT_UINT32", "BASE_DEC", 0, "NULL", 8);
$self->register_type("hyper", "offset = dissect_ndr_uint64(tvb, offset, pinfo, tree, di, drep, \@HF\@, NULL);", "FT_UINT64", "BASE_DEC", 0, "NULL", 8);
+ $self->register_type("int64", "offset = dissect_ndr_uint64(tvb, offset, pinfo, tree, di, drep, \@HF\@, NULL);", "FT_INT64", "BASE_DEC", 0, "NULL", 8);
$self->register_type("udlong", "offset = dissect_ndr_duint32(tvb, offset, pinfo, tree, di, drep, \@HF\@, NULL);", "FT_UINT64", "BASE_DEC", 0, "NULL", 4);
$self->register_type("bool8", "offset = PIDL_dissect_uint8(tvb, offset, pinfo, tree, di, drep, \@HF\@, \@PARAM\@);","FT_INT8", "BASE_DEC", 0, "NULL", 1);
$self->register_type("char", "offset = PIDL_dissect_uint8(tvb, offset, pinfo, tree, di, drep, \@HF\@, \@PARAM\@);","FT_INT8", "BASE_DEC", 0, "NULL", 1);
@@ -1113,19 +1137,19 @@ sub Initialize($$)
$self->register_type("GUID", "offset = dissect_ndr_uuid_t(tvb, offset, pinfo, tree, di, drep, \@HF\@, NULL);","FT_GUID", "BASE_NONE", 0, "NULL", 4);
$self->register_type("policy_handle", "offset = PIDL_dissect_policy_hnd(tvb, offset, pinfo, tree, di, drep, \@HF\@, \@PARAM\@);","FT_BYTES", "BASE_NONE", 0, "NULL", 4);
$self->register_type("NTTIME", "offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep, \@HF\@);","FT_ABSOLUTE_TIME", "ABSOLUTE_TIME_LOCAL", 0, "NULL", 4);
- $self->register_type("NTTIME_hyper", "offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep, \@HF\@);","FT_ABSOLUTE_TIME", "ABSOLUTE_TIME_LOCAL", 0, "NULL", 4);
+ $self->register_type("NTTIME_hyper", "offset = dissect_ndr_nt_NTTIME_hyper(tvb, offset, pinfo, tree, di, drep, \@HF\@);","FT_ABSOLUTE_TIME", "ABSOLUTE_TIME_LOCAL", 0, "NULL", 4);
$self->register_type("time_t", "offset = dissect_ndr_time_t(tvb, offset, pinfo,tree, di, drep, \@HF\@, NULL);","FT_ABSOLUTE_TIME", "ABSOLUTE_TIME_LOCAL", 0, "NULL", 4);
- $self->register_type("NTTIME_1sec", "offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, di, drep, \@HF\@);", "FT_ABSOLUTE_TIME", "ABSOLUTE_TIME_LOCAL", 0, "NULL", 4);
+ $self->register_type("NTTIME_1sec", "offset = dissect_ndr_nt_NTTIME_1sec(tvb, offset, pinfo, tree, di, drep, \@HF\@);", "FT_ABSOLUTE_TIME", "ABSOLUTE_TIME_LOCAL", 0, "NULL", 4);
$self->register_type("dom_sid28",
"offset = dissect_ndr_nt_SID28(tvb, offset, pinfo, tree, di, drep, \@HF\@);", "FT_STRING", "BASE_NONE", 0, "NULL", 4);
$self->register_type("SID",
"offset = dissect_ndr_nt_SID_with_options(tvb, offset, pinfo, tree, di, drep, param, \@HF\@);","FT_STRING", "BASE_NONE", 0, "NULL", 4);
$self->register_type("WERROR",
- "offset = PIDL_dissect_uint32(tvb, offset, pinfo, tree, di, drep, \@HF\@, \@PARAM\@);","FT_UINT32", "BASE_DEC", 0, "VALS(WERR_errors)", 4);
+ "offset = PIDL_dissect_uint32(tvb, offset, pinfo, tree, di, drep, \@HF\@, \@PARAM\@);","FT_UINT32", "BASE_HEX|BASE_EXT_STRING", 0, "&WERR_errors_ext", 4);
$self->register_type("NTSTATUS",
- "offset = PIDL_dissect_uint32(tvb, offset, pinfo, tree, di, drep, \@HF\@, \@PARAM\@);","FT_UINT32", "BASE_DEC", 0, "VALS(NT_errors)", 4);
+ "offset = PIDL_dissect_uint32(tvb, offset, pinfo, tree, di, drep, \@HF\@, \@PARAM\@);","FT_UINT32", "BASE_HEX|BASE_EXT_STRING", 0, "&NT_errors_ext", 4);
$self->register_type("HRESULT",
- "offset = PIDL_dissect_uint32(tvb, offset, pinfo, tree, di, drep, \@HF\@, \@PARAM\@);","FT_UINT32", "BASE_DEC", 0, "VALS(HRES_errors)", 4);
+ "offset = PIDL_dissect_uint32(tvb, offset, pinfo, tree, di, drep, \@HF\@, \@PARAM\@);","FT_UINT32", "BASE_HEX|BASE_EXT_STRING", 0, "&HRES_errors_ext", 4);
$self->register_type("ipv6address", "proto_tree_add_item(tree, \@HF\@, tvb, offset, 16, ENC_NA); offset += 16;", "FT_IPv6", "BASE_NONE", 0, "NULL", 16);
$self->register_type("ipv4address", "proto_tree_add_item(tree, \@HF\@, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4;", "FT_IPv4", "BASE_NONE", 0, "NULL", 4);
@@ -1149,7 +1173,7 @@ sub Parse($$$$$)
Pidl is a perl based IDL compiler for DCE/RPC idl files.
It is maintained by the Samba team, not the Wireshark team.
Instructions on how to download and install Pidl can be
- found at https://gitlab.com/wireshark/wireshark/-/wikis/Pidl
+ found at https://wiki.wireshark.org/Pidl
*/
";
@@ -1157,9 +1181,10 @@ sub Parse($$$$$)
$self->{res}->{headers} = "\n";
$self->{res}->{headers} .= "#include \"config.h\"\n";
- $self->{res}->{headers} .= "#include <glib.h>\n";
$self->{res}->{headers} .= "#include <string.h>\n";
- $self->{res}->{headers} .= "#include <epan/packet.h>\n\n";
+ $self->{res}->{headers} .= "#include <wsutil/array.h>\n";
+ $self->{res}->{headers} .= "#include <epan/packet.h>\n";
+ $self->{res}->{headers} .= "#include <epan/tfs.h>\n\n";
$self->{res}->{headers} .= "#include \"packet-dcerpc.h\"\n";
$self->{res}->{headers} .= "#include \"packet-dcerpc-nt.h\"\n";
@@ -1217,7 +1242,7 @@ sub register_ett($$)
sub DumpEttList
{
my ($ett) = @_;
- my $res = "\tstatic gint *ett[] = {\n";
+ my $res = "\tstatic int *ett[] = {\n";
foreach (@$ett) {
$res .= "\t\t&$_,\n";
}
@@ -1230,7 +1255,7 @@ sub DumpEttDeclaration
my ($ett) = @_;
my $res = "\n/* Ett declarations */\n";
foreach (@$ett) {
- $res .= "static gint $_ = -1;\n";
+ $res .= "static int $_;\n";
}
return "$res\n";
@@ -1296,7 +1321,7 @@ sub DumpHfDeclaration($)
foreach (sort(keys %{$self->{conformance}->{header_fields}}))
{
- $res .= "static gint $_ = -1;\n";
+ $res .= "static int $_;\n";
}
return "$res\n";
@@ -1339,7 +1364,7 @@ sub DumpFunctionTable($)
{
my $if = shift;
- my $res = "static dcerpc_sub_dissector $if->{NAME}\_dissectors[] = {\n";
+ my $res = "static const dcerpc_sub_dissector $if->{NAME}\_dissectors[] = {\n";
foreach (@{$if->{FUNCTIONS}}) {
my $fn_name = $_->{NAME};
$fn_name =~ s/^$if->{NAME}_//;
diff --git a/tools/pidl/lib/Parse/Yapp/Driver.pm b/tools/pidl/lib/Parse/Yapp/Driver.pm
deleted file mode 100644
index 3652be06..00000000
--- a/tools/pidl/lib/Parse/Yapp/Driver.pm
+++ /dev/null
@@ -1,471 +0,0 @@
-#
-# Module Parse::Yapp::Driver
-#
-# This module is part of the Parse::Yapp package available on your
-# nearest CPAN
-#
-# Any use of this module in a standalone parser make the included
-# text under the same copyright as the Parse::Yapp module itself.
-#
-# This notice should remain unchanged.
-#
-# (c) Copyright 1998-2001 Francois Desarmenien, all rights reserved.
-# (see the pod text in Parse::Yapp module for use and distribution rights)
-#
-
-package Parse::Yapp::Driver;
-
-require 5.004;
-
-use strict;
-
-use vars qw ( $VERSION $COMPATIBLE $FILENAME );
-
-$VERSION = '1.05';
-$COMPATIBLE = '0.07';
-$FILENAME=__FILE__;
-
-use Carp;
-
-#Known parameters, all starting with YY (leading YY will be discarded)
-my(%params)=(YYLEX => 'CODE', 'YYERROR' => 'CODE', YYVERSION => '',
- YYRULES => 'ARRAY', YYSTATES => 'ARRAY', YYDEBUG => '');
-#Mandatory parameters
-my(@params)=('LEX','RULES','STATES');
-
-sub new {
- my($class)=shift;
- my($errst,$nberr,$token,$value,$check,$dotpos);
- my($self)={ ERROR => \&_Error,
- ERRST => \$errst,
- NBERR => \$nberr,
- TOKEN => \$token,
- VALUE => \$value,
- DOTPOS => \$dotpos,
- STACK => [],
- DEBUG => 0,
- CHECK => \$check };
-
- _CheckParams( [], \%params, \@_, $self );
-
- exists($$self{VERSION})
- and $$self{VERSION} < $COMPATIBLE
- and croak "Yapp driver version $VERSION ".
- "incompatible with version $$self{VERSION}:\n".
- "Please recompile parser module.";
-
- ref($class)
- and $class=ref($class);
-
- bless($self,$class);
-}
-
-sub YYParse {
- my($self)=shift;
- my($retval);
-
- _CheckParams( \@params, \%params, \@_, $self );
-
- if($$self{DEBUG}) {
- _DBLoad();
- $retval = eval '$self->_DBParse()';#Do not create stab entry on compile
- $@ and die $@;
- }
- else {
- $retval = $self->_Parse();
- }
- $retval
-}
-
-sub YYData {
- my($self)=shift;
-
- exists($$self{USER})
- or $$self{USER}={};
-
- $$self{USER};
-
-}
-
-sub YYErrok {
- my($self)=shift;
-
- ${$$self{ERRST}}=0;
- undef;
-}
-
-sub YYNberr {
- my($self)=shift;
-
- ${$$self{NBERR}};
-}
-
-sub YYRecovering {
- my($self)=shift;
-
- ${$$self{ERRST}} != 0;
-}
-
-sub YYAbort {
- my($self)=shift;
-
- ${$$self{CHECK}}='ABORT';
- undef;
-}
-
-sub YYAccept {
- my($self)=shift;
-
- ${$$self{CHECK}}='ACCEPT';
- undef;
-}
-
-sub YYError {
- my($self)=shift;
-
- ${$$self{CHECK}}='ERROR';
- undef;
-}
-
-sub YYSemval {
- my($self)=shift;
- my($index)= $_[0] - ${$$self{DOTPOS}} - 1;
-
- $index < 0
- and -$index <= @{$$self{STACK}}
- and return $$self{STACK}[$index][1];
-
- undef; #Invalid index
-}
-
-sub YYCurtok {
- my($self)=shift;
-
- @_
- and ${$$self{TOKEN}}=$_[0];
- ${$$self{TOKEN}};
-}
-
-sub YYCurval {
- my($self)=shift;
-
- @_
- and ${$$self{VALUE}}=$_[0];
- ${$$self{VALUE}};
-}
-
-sub YYExpect {
- my($self)=shift;
-
- keys %{$self->{STATES}[$self->{STACK}[-1][0]]{ACTIONS}}
-}
-
-sub YYLexer {
- my($self)=shift;
-
- $$self{LEX};
-}
-
-
-#################
-# Private stuff #
-#################
-
-
-sub _CheckParams {
- my($mandatory,$checklist,$inarray,$outhash)=@_;
- my($prm,$value);
- my($prmlst)={};
-
- while(($prm,$value)=splice(@$inarray,0,2)) {
- $prm=uc($prm);
- exists($$checklist{$prm})
- or croak("Unknown parameter '$prm'");
- ref($value) eq $$checklist{$prm}
- or croak("Invalid value for parameter '$prm'");
- $prm=unpack('@2A*',$prm);
- $$outhash{$prm}=$value;
- }
- for (@$mandatory) {
- exists($$outhash{$_})
- or croak("Missing mandatory parameter '".lc($_)."'");
- }
-}
-
-sub _Error {
- print "Parse error.\n";
-}
-
-sub _DBLoad {
- {
- no strict 'refs';
-
- exists(${__PACKAGE__.'::'}{_DBParse})#Already loaded ?
- and return;
- }
- my($fname)=__FILE__;
- my(@drv);
- open(DRV,"<$fname") or die "Report this as a BUG: Cannot open $fname";
- while(<DRV>) {
- /^\s*sub\s+_Parse\s*{\s*$/ .. /^\s*}\s*#\s*_Parse\s*$/
- and do {
- s/^#DBG>//;
- push(@drv,$_);
- }
- }
- close(DRV);
-
- $drv[0]=~s/_P/_DBP/;
- eval join('',@drv);
-}
-
-#Note that for loading debugging version of the driver,
-#this file will be parsed from 'sub _Parse' up to '}#_Parse' inclusive.
-#So, DO NOT remove comment at end of sub !!!
-sub _Parse {
- my($self)=shift;
-
- my($rules,$states,$lex,$error)
- = @$self{ 'RULES', 'STATES', 'LEX', 'ERROR' };
- my($errstatus,$nberror,$token,$value,$stack,$check,$dotpos)
- = @$self{ 'ERRST', 'NBERR', 'TOKEN', 'VALUE', 'STACK', 'CHECK', 'DOTPOS' };
-
-#DBG> my($debug)=$$self{DEBUG};
-#DBG> my($dbgerror)=0;
-
-#DBG> my($ShowCurToken) = sub {
-#DBG> my($tok)='>';
-#DBG> for (split('',$$token)) {
-#DBG> $tok.= (ord($_) < 32 or ord($_) > 126)
-#DBG> ? sprintf('<%02X>',ord($_))
-#DBG> : $_;
-#DBG> }
-#DBG> $tok.='<';
-#DBG> };
-
- $$errstatus=0;
- $$nberror=0;
- ($$token,$$value)=(undef,undef);
- @$stack=( [ 0, undef ] );
- $$check='';
-
- while(1) {
- my($actions,$act,$stateno);
-
- $stateno=$$stack[-1][0];
- $actions=$$states[$stateno];
-
-#DBG> print STDERR ('-' x 40),"\n";
-#DBG> $debug & 0x2
-#DBG> and print STDERR "In state $stateno:\n";
-#DBG> $debug & 0x08
-#DBG> and print STDERR "Stack:[".
-#DBG> join(',',map { $$_[0] } @$stack).
-#DBG> "]\n";
-
-
- if (exists($$actions{ACTIONS})) {
-
- defined($$token)
- or do {
- ($$token,$$value)=&$lex($self);
-#DBG> $debug & 0x01
-#DBG> and print STDERR "Need token. Got ".&$ShowCurToken."\n";
- };
-
- $act= exists($$actions{ACTIONS}{$$token})
- ? $$actions{ACTIONS}{$$token}
- : exists($$actions{DEFAULT})
- ? $$actions{DEFAULT}
- : undef;
- }
- else {
- $act=$$actions{DEFAULT};
-#DBG> $debug & 0x01
-#DBG> and print STDERR "Don't need token.\n";
- }
-
- defined($act)
- and do {
-
- $act > 0
- and do { #shift
-
-#DBG> $debug & 0x04
-#DBG> and print STDERR "Shift and go to state $act.\n";
-
- $$errstatus
- and do {
- --$$errstatus;
-
-#DBG> $debug & 0x10
-#DBG> and $dbgerror
-#DBG> and $$errstatus == 0
-#DBG> and do {
-#DBG> print STDERR "**End of Error recovery.\n";
-#DBG> $dbgerror=0;
-#DBG> };
- };
-
-
- push(@$stack,[ $act, $$value ]);
-
- $$token ne '' #Don't eat the eof
- and $$token=$$value=undef;
- next;
- };
-
- #reduce
- my($lhs,$len,$code,@sempar,$semval);
- ($lhs,$len,$code)=@{$$rules[-$act]};
-
-#DBG> $debug & 0x04
-#DBG> and $act
-#DBG> and print STDERR "Reduce using rule ".-$act." ($lhs,$len): ";
-
- $act
- or $self->YYAccept();
-
- $$dotpos=$len;
-
- unpack('A1',$lhs) eq '@' #In line rule
- and do {
- $lhs =~ /^\@[0-9]+\-([0-9]+)$/
- or die "In line rule name '$lhs' ill formed: ".
- "report it as a BUG.\n";
- $$dotpos = $1;
- };
-
- @sempar = $$dotpos
- ? map { $$_[1] } @$stack[ -$$dotpos .. -1 ]
- : ();
-
- $semval = $code ? &$code( $self, @sempar )
- : @sempar ? $sempar[0] : undef;
-
- splice(@$stack,-$len,$len);
-
- $$check eq 'ACCEPT'
- and do {
-
-#DBG> $debug & 0x04
-#DBG> and print STDERR "Accept.\n";
-
- return($semval);
- };
-
- $$check eq 'ABORT'
- and do {
-
-#DBG> $debug & 0x04
-#DBG> and print STDERR "Abort.\n";
-
- return(undef);
-
- };
-
-#DBG> $debug & 0x04
-#DBG> and print STDERR "Back to state $$stack[-1][0], then ";
-
- $$check eq 'ERROR'
- or do {
-#DBG> $debug & 0x04
-#DBG> and print STDERR
-#DBG> "go to state $$states[$$stack[-1][0]]{GOTOS}{$lhs}.\n";
-
-#DBG> $debug & 0x10
-#DBG> and $dbgerror
-#DBG> and $$errstatus == 0
-#DBG> and do {
-#DBG> print STDERR "**End of Error recovery.\n";
-#DBG> $dbgerror=0;
-#DBG> };
-
- push(@$stack,
- [ $$states[$$stack[-1][0]]{GOTOS}{$lhs}, $semval ]);
- $$check='';
- next;
- };
-
-#DBG> $debug & 0x04
-#DBG> and print STDERR "Forced Error recovery.\n";
-
- $$check='';
-
- };
-
- #Error
- $$errstatus
- or do {
-
- $$errstatus = 1;
- &$error($self);
- $$errstatus # if 0, then YYErrok has been called
- or next; # so continue parsing
-
-#DBG> $debug & 0x10
-#DBG> and do {
-#DBG> print STDERR "**Entering Error recovery.\n";
-#DBG> ++$dbgerror;
-#DBG> };
-
- ++$$nberror;
-
- };
-
- $$errstatus == 3 #The next token is not valid: discard it
- and do {
- $$token eq '' # End of input: no hope
- and do {
-#DBG> $debug & 0x10
-#DBG> and print STDERR "**At eof: aborting.\n";
- return(undef);
- };
-
-#DBG> $debug & 0x10
-#DBG> and print STDERR "**Dicard invalid token ".&$ShowCurToken.".\n";
-
- $$token=$$value=undef;
- };
-
- $$errstatus=3;
-
- while( @$stack
- and ( not exists($$states[$$stack[-1][0]]{ACTIONS})
- or not exists($$states[$$stack[-1][0]]{ACTIONS}{error})
- or $$states[$$stack[-1][0]]{ACTIONS}{error} <= 0)) {
-
-#DBG> $debug & 0x10
-#DBG> and print STDERR "**Pop state $$stack[-1][0].\n";
-
- pop(@$stack);
- }
-
- @$stack
- or do {
-
-#DBG> $debug & 0x10
-#DBG> and print STDERR "**No state left on stack: aborting.\n";
-
- return(undef);
- };
-
- #shift the error token
-
-#DBG> $debug & 0x10
-#DBG> and print STDERR "**Shift \$error token and go to state ".
-#DBG> $$states[$$stack[-1][0]]{ACTIONS}{error}.
-#DBG> ".\n";
-
- push(@$stack, [ $$states[$$stack[-1][0]]{ACTIONS}{error}, undef ]);
-
- }
-
- #never reached
- croak("Error in driver logic. Please, report it as a BUG");
-
-}#_Parse
-#DO NOT remove comment
-
-1;
-