diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2017-12-14 17:33:48 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2017-12-14 17:33:48 +0200 |
commit | 8da9e46a4cafdc3e6a5314aaf72bc1f152706ca9 (patch) | |
tree | 88f0cda9745943a2a57f2534575ccd26204c5857 /lib/Apache/Config/Preproc | |
parent | 0cd260b3bb8134587cb7b0124a511182dd377c95 (diff) | |
download | acpp-8da9e46a4cafdc3e6a5314aaf72bc1f152706ca9.tar.gz acpp-8da9e46a4cafdc3e6a5314aaf72bc1f152706ca9.tar.bz2 |
Fix cyclic include detection.
* lib/Apache/Config/Preproc/include.pm: Use stack of contexts to
detect inclusion loops. Inject temporary directives to maintain
the stack.
Diffstat (limited to 'lib/Apache/Config/Preproc')
-rw-r--r-- | lib/Apache/Config/Preproc/include.pm | 43 |
1 files changed, 35 insertions, 8 deletions
diff --git a/lib/Apache/Config/Preproc/include.pm b/lib/Apache/Config/Preproc/include.pm index f77436e..658ab8c 100644 --- a/lib/Apache/Config/Preproc/include.pm +++ b/lib/Apache/Config/Preproc/include.pm @@ -13,7 +13,7 @@ our $VERSION = '1.01'; sub new { my $class = shift; my $conf = shift; - my $self = bless { included => {}, conf => $conf }, $class; + my $self = bless { context => [], conf => $conf }, $class; local %_ = @_; $self->{server_root} = delete $_{server_root}; if (my $v = delete $_{probe}) { @@ -40,6 +40,23 @@ sub server_root { return $self->{server_root}; } +sub context_string { + my ($self, $file) = @_; + my ($dev,$ino) = stat($file); + $file = abs_path($file); + return "\"$file\" $dev $ino"; +} + +sub context_push { + my ($self,$file,$dev,$ino) = @_; + push @{$self->{context}}, { file => $file, dev => $dev, ino => $ino }; +} + +sub context_pop { + my $self = shift; + pop @{$self->{context}}; +} + sub expand { my ($self, $d, $repl) = @_; @@ -64,6 +81,12 @@ sub expand { } if (my $inc = new Apache::Admin::Config($file, @{$self->conf->options})) { + $inc->add('directive', + '$PUSH$' => $self->context_string($file), + '-ontop'); + $inc->add('directive', + '$POP$' => 0, + '-onbottom'); # NOTE: make sure each item is cloned push @$repl, map { $_->clone } $inc->select; } else { @@ -72,6 +95,14 @@ sub expand { } } return 1; + } elsif ($d->name eq '$PUSH$') { + if ($d->value =~ /^\"(.+)\" (\d+) (\d+)$/) { + $self->context_push($1, $2, $3); + } + return 1; + } elsif ($d->name eq '$POP$') { + $self->context_pop; + return 1; } } @@ -116,18 +147,14 @@ sub check_included { sub _check_included_stat { my ($self, $file) = @_; my ($dev,$ino) = stat($file) or return 0; - return 1 if $self->{included}{$dev}{$ino}; - $self->{included}{$dev}{$ino} = 1; - return 0; + return grep { $_->{dev} == $dev && $_->{ino} == $ino } @{$self->{context}}; } -# Path-bases file table, for defective OSes (MSWin32) +# Path-based file table, for defective OSes (MSWin32) sub _check_included_path { my ($self, $file) = @_; my $path = abs_path($file); - return 1 if $self->{included}{$path}; - $self->{included}{$path} = 1; - return 0; + return grep { $_->{file} eq $path } @{$self->{context}}; } 1; |