Skip to content

Commit

Permalink
Fix REPL thinking returned stuff is a thrown exception
Browse files Browse the repository at this point in the history
With the current versionb, it's possible to trick REPL into
thinking an exception was thrown when it really wasn't with code like:

say "hi"; use nqp; my $x = REPL.new(nqp::getcomp("perl6"), %).repl-eval(q|die "meow"|);

Not a big deal, but we can eliminate that case by tossing the
marker role and using a different variable to handle exceptions.

Fixes (for real this time) RT#130876:
https://rt.perl.org/Ticket/Display.html?id=130876#ticket-history
  • Loading branch information
zoffixznet committed Feb 28, 2017
1 parent b4118a7 commit 7f9235c
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 10 deletions.
22 changes: 12 additions & 10 deletions src/core/REPL.pm
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,6 @@ do {
class REPL {
also does Completions;

my role Rakudo::Internals::REPL::CaughtError {}

has Mu $.compiler;
has Bool $!multi-line-enabled;
has IO::Path $!history-file;
Expand Down Expand Up @@ -277,7 +275,7 @@ do {
self.?teardown-line-editor;
}

method repl-eval($code, *%adverbs) {
method repl-eval($code, \exception, *%adverbs) {

CATCH {
when X::Syntax::Missing {
Expand All @@ -297,8 +295,8 @@ do {
}

default {
# Use the exception as the result of the eval, to be printed
return $_ but Rakudo::Internals::REPL::CaughtError
exception = $_;
return;
}
}

Expand Down Expand Up @@ -346,6 +344,7 @@ do {

my Mu $output is default(Nil) = self.repl-eval(
$code,
my $exception,
:outer_ctx($!save_ctx),
|%adverbs);

Expand All @@ -368,12 +367,15 @@ do {

# Print the result if:
# - there wasn't some other output
# - the result is a *thrown* Exception
# - the result is an *unhandled* Failure
self.repl-print($output)
if $initial_out_position == $*OUT.tell
or $output ~~ Rakudo::Internals::REPL::CaughtError
or $output ~~ Failure and not $output.handled;
# - print an exception if one had occured
if $exception.DEFINITE {
self.repl-print($exception);
}
elsif $initial_out_position == $*OUT.tell
or $output ~~ Failure and not $output.handled {
self.repl-print($output);
}

# Why doesn't the catch-default in repl-eval catch all?
CATCH {
Expand Down
7 changes: 7 additions & 0 deletions t/02-rakudo/repl.t
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,13 @@ my @input-lines;
$out = feed_repl_with ['say "hi"; try +"a"; $!'];
ok $out.contains('meows').not,
'previous output does not prevent output of unthrown exceptions';

$out = feed_repl_with([
say "hi"; use nqp; my $x = REPL.new(nqp::getcomp("perl6"), %)
~ .repl-eval(q|die "meows"|, $);
]);
ok $out.contains('meows').not,
can't trick REPL into thinking an exception was thrown (RT#130876);
}

done-testing;

0 comments on commit 7f9235c

Please sign in to comment.