--- loncom/xml/run.pm 2004/07/19 16:53:46 1.48 +++ loncom/xml/run.pm 2020/03/12 20:20:13 1.66 @@ -1,6 +1,6 @@ package Apache::run; # -# $Id: run.pm,v 1.48 2004/07/19 16:53:46 albertel Exp $ +# $Id: run.pm,v 1.66 2020/03/12 20:20:13 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -26,6 +26,7 @@ package Apache::run; # use HTML::Entities; +use Apache::lonlocal; $Apache::run::EVALUATE_STRING=<<'ENDEVALUATE'; my %_LONCAPA_INTERNAL_oldexpressions=(); @@ -40,7 +41,7 @@ while (!$_LONCAPA_INTERNAL_oldexpression # or hash dereferences {} # the ^$ and ^& is because we do this iteratively # $a[$c] becomes $a[3] which then evaluates - ([\[\{][^\$\&\]\}]+[\]\}])*? + ((?:[\[\{][^\$\&\]\}]+[\]\}])+|) # $3 is the list of arguments (\([^\$\&\)]+\))*? # only match the above if there is not { [ ( coming up @@ -48,23 +49,24 @@ while (!$_LONCAPA_INTERNAL_oldexpression (?=[^\[\{\(]|$)/ my ($__LC__a,$__LC__b,$__LC__c)=($1,$2,$3); my $__LC__prefix; - my $result; + my $__LC__result; while (1) { + if ($__LC__a =~ m-^&(theta|pi|rho)$-) { last; } { use strict; no strict "vars"; if (eval(defined(eval($__LC__a.$__LC__b)))) { - $result= $__LC__prefix.eval($__LC__a.$__LC__b.$__LC__c); + $__LC__result= $__LC__prefix.eval($__LC__a.$__LC__b.$__LC__c); last; } } $__LC__prefix.=substr($__LC__a,0,1,""); if ($__LC__a!~m-^(\$|&|\#)-) { last; } } - if (!defined($result)) { - $result=$__LC__prefix.$__LC__a.$__LC__b.$__LC__c; + if (!defined($__LC__result)) { + $__LC__result=$__LC__prefix.$__LC__a.$__LC__b.$__LC__c; } - $result; + $__LC__result; /sexg; if (scalar(values(%_LONCAPA_INTERNAL_oldexpressions))>10) {last;} } @@ -77,37 +79,37 @@ sub evaluate { my $result = ''; $@=''; $Apache::run::timeout=0; - $main::SIG{'ALRM'} = sub { + local $main::SIG{'ALRM'} = sub { $Apache::run::timeout=1; die("timeout"); }; my $innererror; eval { - alarm($Apache::lonnet::perlvar{'lonScriptTimeout'}); + &Apache::lonxml::start_alarm(); $safeeval->reval('{'.$decls.';$_=<<\'EXPRESSION\';'."\n".$expression. "\n".'EXPRESSION'."\n".$EVALUATE_STRING.'}'); $innererror=$@; - alarm(0); + &Apache::lonxml::end_alarm(); }; - my $error=$@; + my $error=$@; if ($error eq '' && $innererror eq '' && !$Apache::run::timeout) { $result = $safeeval->reval('return $_;'); chomp $result; } else { - if ($Apache::run::timeout) { - $error = 'Code ran too long. It ran for more than '. - $Apache::lonnet::perlvar{'lonScriptTimeout'}.' seconds'; - } - &Apache::lonxml::error('substitution on
'. - &HTML::Entities::encode($expression,'<>&"'). - 'with
'. - &HTML::Entities::encode($decls,'<>&"'). - 'caused
'. - &HTML::Entities::encode($error,'<>&"').' '. - &HTML::Entities::encode($innererror,'<>&"'). - ''); + if ($Apache::run::timeout) { + $error = + &mt('Code ran too long. It ran for more than [_1] seconds.', + $Apache::lonnet::perlvar{'lonScriptTimeout'}); + } + &Apache::lonxml::error( + &mt('Substitution on [_1] with [_2] caused:', + '
'. &HTML::Entities::encode($expression,'<>&"').'', + '
'.&HTML::Entities::encode($decls,'<>&"').'') + .'
'.&HTML::Entities::encode($error,'<>&"').' ' + .&HTML::Entities::encode($innererror,'<>&"').''); } - return $result + return $result; } sub run { @@ -115,35 +117,40 @@ sub run { my @result; $@=''; $Apache::run::timeout=0; - $main::SIG{'ALRM'} = sub { + local $main::SIG{'ALRM'} = sub { $Apache::run::timeout=1; die("timeout"); }; my $innererror; eval { - alarm($Apache::lonnet::perlvar{'lonScriptTimeout'}); + &Apache::lonxml::start_alarm(); @result=$safeeval->reval($code); $innererror=$@; - alarm(0); + &Apache::lonxml::end_alarm(); }; my $error=$@; if (($Apache::run::timeout || $error ne '' || $innererror ne '') && !$hideerrors) { - if ($Apache::run::timeout) { - $error = 'Code ran too long. It ran for more than '. - $Apache::lonnet::perlvar{'lonScriptTimeout'}.' seconds'; - } - my $errormsg='
'.&HTML::Entities::encode($error,'<>&"').' '. - &HTML::Entities::encode($innererror,'<>&"'). - 'occured while running
'; - $code=&HTML::Entities::encode($code,'<>&"'); - if ($innererror=~/line (\d+)/) { - my $linenumber=$1; - my @code=split("\n",$code); - $code[$linenumber-1]=''. - $code[$linenumber-1].''; - $code=join("\n",@code); - } - &Apache::lonxml::error($errormsg.$code.''); + if ($Apache::run::timeout) { + $error = &mt('Code ran too long. It ran for more than [_1] seconds.', + $Apache::lonnet::perlvar{'lonScriptTimeout'}); + } + $code=&HTML::Entities::encode($code,'<>&"'); + if ($innererror=~/line (\d+)/) { + my $linenumber=$1; + my @code=split("\n",$code); + if ($linenumber < scalar(@code)) { + $code[$linenumber-1]= + ''. + $code[$linenumber-1].''; + } + $code=join("\n",@code); + } + &Apache::lonxml::error( + '
'.&HTML::Entities::encode($error,'<>&"').' '. + &HTML::Entities::encode($innererror,'<>&"'). + '' + .&mt('This occurred while running: [_1]', + '
'.$code.'')); } if ( $#result < '1') { return $result[0]; @@ -156,23 +163,30 @@ sub run { sub dump { my ($target,$safeeval)=@_; my $dump=''; - foreach my $symname (sort keys %{$safeeval->varglob('main::')}) { - if (($symname!~/^\_/) && ($symname!~/\:$/)) { + foreach my $symname (sort(keys(%{$safeeval->varglob('main::')}))) { + if (($symname!~ /^(INC|SIG)/) && ($symname!~/\027/) && ($symname!~/\022/) && + ($symname!~/^\_/) && ($symname!~/\:$/) && ($symname ne '!')) { my $line; if ($safeeval->reval('defined($'.$symname.')')) { - $line='$'.$symname.'='.$safeeval->reval('$'.$symname); + if ($symname =~ /^\w/) { + $line.='$'.$symname.'='.$safeeval->reval('$'.$symname)."\n"; + } } - if ($safeeval->reval('defined(@'.$symname.')')) { - $line='@'.$symname.'=('. - $safeeval->reval('join(",",@'.$symname.')').")"; + if ($safeeval->reval('@'.$symname)) { + $line.='@'.$symname.'=('. + $safeeval->reval('join(",",@'.$symname.')').")"."\n"; } - if ($safeeval->reval('defined(%'.$symname.')')) { - $line='%'.$symname.'=('; + if ($safeeval->reval('%'.$symname)) { + $line.='%'.$symname.'=('; $line.=$safeeval->reval('join(",",map { $_."=>".$'. - $symname.'{$_} } sort keys %'. - $symname.')').")" - } - if ($line ne '') {$dump.=&HTML::Entities::encode($line,'<>&"')."