# errors in $errlist should all have as their first element tags that
# were found in $HTML.
#
# Each error's final element (the "leaf") is associated with a tag that
# tried to load an invalid file. Each leaf will always be the complete
# set of errors for that tag (i.e. it has no children, since it couldn't
# load the file).
#
# If the file can be validly loaded, then we may have 0 or multiple errors
# associated with this file/tag (and returned from this routine). Each
# file's $errlist is an accumulation of all of its children's $errlist's.
#
# Errors that come from loading a child are associated with the child's
# $HTML and tags. Before adding them to the parent's (current) $errlist,
# they must have the CHILD's path/tag unshifted onto the front of the
# include chain; all errors are then added to the current $errlist.
# This ensures that:
# a) The errors are now all associated with the tag that loaded the child.
# b) The errors in the current $errlist are always associated with tags
# from the current $HTML.
#
sub read_expanded_file {
my($fname, $URL, $parents)= @_ ;
my($HTML, $errlist, $iscgi) ;
my($isshtml) ;
$parents->{$fname}= 1 ;
$HTML= &read_file($fname) ;
return(undef) unless defined($HTML) ;
foreach (@SHTML_EXTENSIONS) {
$isshtml= 1, last if ($fname=~ /\Q$_\E$/i) ;
}
if ($isshtml) {
$errlist= [] ;
$iscgi= ($HTML=~ /<!--#exec\b/i) ;
$HTML=~ s{(<!--#include\b.*?>)} {
do {
my($childfname, $childURL) ;
my($childHTML, $childerrlist, $childiscgi) ;
my($tagst) = $1 ;
my($tag)= &parse_tag($tagst) ;
GET_CHILD: {
if (length($tag->{'attrib'}{'virtual'})) {
$URL= &filename_to_url($fname) unless length($URL) ;
$childURL=
&absolute_url($tag->{'attrib'}{'virtual'}, $URL) ;
($childfname)= &url_to_filename($childURL) ;
# If it's a CGI, don't follow it, but no error either
if (&is_cgi($childfname, $childURL)) {
$iscgi= 1 ;
last GET_CHILD ;
}
} elsif (length($tag->{'attrib'}{'file'})) {
$childfname= $tag->{'attrib'}{'file'} ;
if ($childfname=~ m#^(/|~)#) {
push(@$errlist, [ {'path' => $childfname,
'tag' => $tagst, 'errmsg' =>
'Absolute paths are not allowed in '
. '<!--#include file="..." -->.'}]);
last GET_CHILD ;
}
if ($childfname=~ m#\.\.(/|$)#) {
push(@$errlist, [ {'path' => $childfname,
'tag' => $tagst, 'errmsg' =>
'Paths can not contain "../" in '
. '<!--#include file="..." -->.'}]);
last GET_CHILD ;
}
$childfname= ($fname=~ m#(.*/)#)[0] . $childfname ;
} else {
push(@$errlist, [ {'path' => '',
'tag' => $tagst, 'errmsg' =>
'Tag must contain either the "file" or '
. '"virtual" attribute.'}]);
last GET_CHILD ;
}
# canonicalize filename for %$parents
1 while $childfname=~ s#/\.(/|$)#/# ;
1 while $childfname=~ s#/(?!\.\./)[^/]+/\.\.(/|$)#/# ;
# Guarantee that file exists, is regular, and is readable
unless (-e $childfname) {
push(@$errlist, [{'path' => $childfname, 'tag' => $tagst,
'errmsg' => 'File not found'} ] ) ;
last GET_CHILD ;
}
unless (-f $childfname) {
push(@$errlist, [{'path' => $childfname, 'tag' => $tagst,
'errmsg' => 'File is not a regular'
. ' file.' } ] ) ;
=9= |