[Patch] fix IDL hang
Noel Power
nopower at suse.com
Thu Aug 7 05:22:59 MDT 2014
Hi,
issuing
./pidl/pidl --header --ndr-parser -- foo.idl
will cause pidl to hang, the attached patch prevents the recursion that
triggers that. Note: I compared the contents of
bin/default/librpc/gen_ndr before and after the patch and the contents
are identical
Noel
-------------- next part --------------
>From f524baef07c27ea4aba1a7527fcda12cfcb5f247 Mon Sep 17 00:00:00 2001
From: Noel Power <noel.power at suse.com>
Date: Wed, 6 Aug 2014 11:32:19 +0100
Subject: [PATCH] detect and prevent recursions (that cause infinite loops)
add recusrion detection logic for can_contain_deferred & align_type
functions
---
pidl/lib/Parse/Pidl/NDR.pm | 71 +++++++++++++++++++++++++++++++++++++---------
1 file changed, 58 insertions(+), 13 deletions(-)
diff --git a/pidl/lib/Parse/Pidl/NDR.pm b/pidl/lib/Parse/Pidl/NDR.pm
index 6827152..95964b0 100644
--- a/pidl/lib/Parse/Pidl/NDR.pm
+++ b/pidl/lib/Parse/Pidl/NDR.pm
@@ -402,16 +402,37 @@ sub can_contain_deferred($)
return 0 if (Parse::Pidl::Typelist::is_scalar($type));
- return can_contain_deferred($type->{DATA}) if ($type->{TYPE} eq "TYPEDEF");
+ if ( not defined($type->{INCANCONTAINDERRED})) {
+ $type->{INCANCONTAINDERRED} = 0;
+ }
+
+ my $res;
+
+ if ($type->{INCANCONTAINDERRED} == 1 ){
+ $res = 0;
+ goto out;
+ }
- return 0 unless defined($type->{ELEMENTS});
+ $type->{INCANCONTAINDERRED} = 1;
+ if ($type->{TYPE} eq "TYPEDEF") {
+ $res = can_contain_deferred($type->{DATA});
+ goto out;
+ }
+
+ if (!defined($type->{ELEMENTS})) {
+ $res = 0;
+ goto out;
+ }
foreach (@{$type->{ELEMENTS}}) {
- return 1 if ($_->{POINTERS});
- return 1 if (can_contain_deferred ($_->{TYPE}));
+ if (($_->{POINTERS}) || can_contain_deferred ($_->{TYPE})) {
+ $res = 1;
+ goto out;
+ }
}
-
- return 0;
+out:
+ $type->{INCANCONTAINDERRED} = 0;
+ return $res;
}
sub pointer_type($)
@@ -481,23 +502,47 @@ sub align_type($)
my $dt = getType($e);
+ if ( not defined($dt->{INGETALIGNTYPE})) {
+ $dt->{INGETALIGNTYPE} = 0;
+ }
+
+ my $res;
+ if ($dt->{INGETALIGNTYPE} == 1 ){
+ # reset it
+ $res = 0;
+ goto out;
+ }
+
+ $dt->{INGETALIGNTYPE} = 1;
+
if ($dt->{TYPE} eq "TYPEDEF") {
- return align_type($dt->{DATA});
+ $res = align_type($dt->{DATA});
+ goto out;
} elsif ($dt->{TYPE} eq "CONFORMANCE") {
- return $dt->{DATA}->{ALIGN};
+ $res = $dt->{DATA}->{ALIGN};
+ goto out;
} elsif ($dt->{TYPE} eq "ENUM") {
- return align_type(Parse::Pidl::Typelist::enum_type_fn($dt));
+ $res = align_type(Parse::Pidl::Typelist::enum_type_fn($dt));
+ goto out;
} elsif ($dt->{TYPE} eq "BITMAP") {
- return align_type(Parse::Pidl::Typelist::bitmap_type_fn($dt));
+ $res = align_type(Parse::Pidl::Typelist::bitmap_type_fn($dt));
+ goto out;
} 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);
+ $res = 4;
+ if (defined($dt->{ELEMENTS})) {
+ $res = find_largest_alignment($dt);
+ }
+ goto out;
} elsif (($dt->{TYPE} eq "PIPE")) {
- return 5;
+ $res = 5;
+ goto out;
}
die("Unknown data type type $dt->{TYPE}");
+out:
+ $dt->{INGETALIGNTYPE} = 0;
+ return $res;
}
sub ParseElement($$$)
--
1.8.4.5
-------------- next part --------------
A non-text attachment was scrubbed...
Name: foo.idl
Type: text/x-idl
Size: 240 bytes
Desc: not available
URL: <http://lists.samba.org/pipermail/samba-technical/attachments/20140807/c27fadc6/attachment.bin>
More information about the samba-technical
mailing list