diff --git a/Shorewall/Perl/Shorewall/Config.pm b/Shorewall/Perl/Shorewall/Config.pm index 691d43f13..14ec041dd 100644 --- a/Shorewall/Perl/Shorewall/Config.pm +++ b/Shorewall/Perl/Shorewall/Config.pm @@ -105,6 +105,7 @@ our %EXPORT_TAGS = ( internal => [ qw( create_temp_script find_file split_list split_list1 + split_list2 split_line split_line1 first_entry @@ -1688,6 +1689,59 @@ sub split_list1( $$ ) { @list2; } +sub split_list2( $$ ) { + my ($list, $type ) = @_; + + fatal_error "Invalid $type ($list)" if $list =~ /^:|::/; + + my @list1 = split /:/, $list; + my @list2; + my $element = ''; + my $opencount = 0; + + + for ( @list1 ) { + my $count; + + if ( ( $count = tr/(/(/ ) > 0 ) { + $opencount += $count; + if ( $element eq '' ) { + $element = $_; + } else { + $element = join( ':', $element, $_ ); + } + + if ( ( $count = tr/)/)/ ) > 0 ) { + if ( ! ( $opencount -= $count ) ) { + push @list2 , $element; + $element = ''; + } else { + fatal_error "Invalid $type ($list)" if $opencount < 0; + } + } + } elsif ( ( $count = tr/)/)/ ) > 0 ) { + fatal_error "Invalid $type ($list)" unless $element ne ''; + $element = join (':', $element, $_ ); + if ( ! ( $opencount -= $count ) ) { + push @list2 , $element; + $element = ''; + } else { + fatal_error "Invalid $type ($list)" if $opencount < 0; + } + } elsif ( $element eq '' ) { + push @list2 , $_; + } else { + $element = join ':', $element , $_; + } + } + + unless ( $opencount == 0 ) { + fatal_error "Invalid $type ($list)"; + } + + @list2; +} + # # Determine if a value has been supplied # diff --git a/Shorewall/Perl/Shorewall/Rules.pm b/Shorewall/Perl/Shorewall/Rules.pm index a6e31e9fa..4d83c46e8 100644 --- a/Shorewall/Perl/Shorewall/Rules.pm +++ b/Shorewall/Perl/Shorewall/Rules.pm @@ -916,26 +916,11 @@ sub finish_section ( $ ) { sub split_action ( $ ) { my $action = $_[0]; - my $target = ''; - my $max = 3; - # - # The following rather grim RE, when matched, breaks the action into two parts: - # - # basicaction(param) - # logging part (may be empty) - # - # The param may contain one or more ':' characters - # - if ( $action =~ /^([^(:]+\(.*?\))(:(.*))?$/ ) { - $target = $1; - $action = $2 ? $3 : ''; - $max = 2; - } + my @list = split_list2( $action, 'ACTION' ); - my @a = split( /:/ , $action, 4 ); - fatal_error "Invalid ACTION ($action)" if ( $action =~ /::/ ) || ( @a > $max ); - $target = shift @a unless $target; - ( $target, join ":", @a ); + fatal_error "Invalid ACTION ($action)" if @list > 3; + + ( shift @list, join( ':', @list ) ); } #