[ic] Controlling nested includes (includes code)

Mike Heins mike at perusion.com
Sat Jun 19 14:16:53 EDT 2004

Quoting Daniel Davenport (ddavenport at newagedigital.com):
> A catalog on our server recently had a page that, when requested, brought
> the server to a crawl.  It turns out that the problem was that the page was
> including another page, which included itself for reasons not really obvious
> to me.  :)  Luckily, the developer was sitting next to me so i could wtf
> him, kill the offending process, and get things back up and running quickly.
> I didn't think it a good thing that one page in one catalog could so easily
> mess things up for everyone, so i decided to try to fix the include tag so
> that it couldn't happen that way again.  Now, it allows an
> administrator-defined number of nested includes, after which the include is
> effectively ignored.
> (Looking back, i could have set a couple of ulimits on interch, but i'm
> getting used to working within interchange as much as possible, and fixing
> it when i can't.  :)  )
> My edited include.coretag follows.  If you want to use it, it can replace
> the contents of {interchange}/code/SystemTag/include.coretag, and consider
> adding a line to interchange.cfg that says
> Variable INCLUDE_DEPTH 10
> or the like.  An INCLUDE_DEPTH of 0 will effectively disable the include
> tag, without making it show up in the page.
> UserTag include             Order        file locale
> UserTag include             PosNumber    2
> UserTag include             Routine      <<EOR
> sub {
>     my ($file, $locale) = @_;
>     $locale = 1 unless defined $locale;
>     $::Session->{include_depth} = 0
>         unless defined $::Session->{include_depth};
>     my $maxdepth = $Variable->{INCLUDE_DEPTH};
>     $maxdepth = 10 unless defined $maxdepth;
>     if ($::Session->{include_depth} < $maxdepth) {
>         ++$::Session->{include_depth};
>         return Vend::Interpolate::interpolate_html(
>             Vend::Util::readfile($file, undef, $locale)
>         );
>         --$::Session->{include_depth};
>     }
>     return '';
> }

This is a very good idea and an important improvement to robustness
for Interchange.

I will make a change to CVS, but won't use this exact code, for I don't
think the include_depth is ever getting decremented. What I am changing:

    * Use $::Instance->{include_depth} as the counter so that a
      die during an include won't cause a bad value to remain in
      the session.

    * These days we don't use $Variable for the core; I will be
      using $Vend::Cfg->{Limit}{include_depth} instead.

    * Branching change, die before normal code is executed.

    * Log the error when it occurs.

Just tested and committed. Thank you Daniel!

Mike Heins
Perusion -- Expert Interchange Consulting    http://www.perusion.com/
phone +1.765.647.1295  tollfree 800-949-1889 <mike at perusion.com>

Any man who is under 30, and is not liberal, has not heart; and any man
who is over 30, and is not a conservative, has not brains.
 -- Winston Churchill

More information about the interchange-users mailing list