From d68d40ee1ca97a747be2b74f7379be4f42a04491 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Thu, 3 Feb 2011 09:12:50 -0800 Subject: [PATCH] Correct an optimization bug involving empty/unreferenced chains --- Shorewall/Perl/Shorewall/Chains.pm | 34 ++++++++++++++++++------------ 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index d22413014..888bbcb69 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -1153,20 +1153,28 @@ sub delete_jumps ( $$ ) { my $from = $fromref->{name}; my $rules = $fromref->{rules}; my $refs = $toref->{references}{$from}; - # - # A C-style for-loop with indexing seems to work best here, given that we are - # deleting elements from the array over which we are iterating. - # - for ( my $rule = 0; $rule <= $#{$rules}; $rule++ ) { - if ( $rules->[$rule] =~ / -[gj] ${to}(\s+-m comment .*)?\s*$/ ) { - trace( $fromref, 'D', $rule + 1, $rules->[$rule] ) if $debug; - splice( @$rules, $rule, 1 ); - last unless --$refs > 0; - $rule--; - } - } - assert( ! $refs ); + # + # The 'from' chain may have had no references and has already been deleted so + # we need to check + # + if ( $fromref->{referenced} ) { + # + # + # A C-style for-loop with indexing seems to work best here, given that we are + # deleting elements from the array over which we are iterating. + # + for ( my $rule = 0; $rule <= $#{$rules}; $rule++ ) { + if ( $rules->[$rule] =~ / -[gj] ${to}(\s+-m comment .*)?\s*$/ ) { + trace( $fromref, 'D', $rule + 1, $rules->[$rule] ) if $debug; + splice( @$rules, $rule, 1 ); + last unless --$refs > 0; + $rule--; + } + } + + assert( ! $refs ); + } delete $toref->{references}{$from};