diff --git a/Changes b/Changes index 9f4444973..e27706e53 100644 --- a/Changes +++ b/Changes @@ -3,7 +3,8 @@ [ BUG FIXES ] * GH #447: Setting the apphandler now triggers the Dancer Runner configuration change, which works. (Sawyer X) - + * GH #567: Check for proper module names in loading engines. Might help + with taint mode. (Sawyer X) [ DOCUMENTATION ] * Fix doc for params(). Ported from Dancer#1025 (Stefan Hornburg) diff --git a/lib/Dancer2/Core/App.pm b/lib/Dancer2/Core/App.pm index 0f9ec2779..21da2c697 100644 --- a/lib/Dancer2/Core/App.pm +++ b/lib/Dancer2/Core/App.pm @@ -5,6 +5,7 @@ use Moo; use File::Spec; use Scalar::Util 'blessed'; use Carp 'croak'; +use Module::Runtime 'is_module_name'; use Dancer2::FileUtils 'path', 'read_file_content'; use Dancer2::Core; @@ -99,6 +100,9 @@ sub _build_logger_engine { # a runner. $value = 'console' if !defined $value; + is_module_name($value) + or croak "Cannot load logger engine '$value': illegal module name"; + my $engine_options = $self->_get_config_for_engine( logger => $value, $config ); @@ -123,6 +127,9 @@ sub _build_session_engine { $value = 'simple' if !defined $value; return $value if ref($value); + is_module_name($value) + or croak "Cannot load session engine '$value': illegal module name"; + my $engine_options = $self->_get_config_for_engine( session => $value, $config ); @@ -142,6 +149,9 @@ sub _build_template_engine { return undef if !defined $value; return $value if ref($value); + is_module_name($value) + or croak "Cannot load template engine '$value': illegal module name"; + my $engine_options = $self->_get_config_for_engine( template => $value, $config ); diff --git a/t/engine.t b/t/engine.t index 0620a5741..96d3489c7 100644 --- a/t/engine.t +++ b/t/engine.t @@ -1,6 +1,8 @@ use strict; use warnings; use Test::More; +use Test::Fatal; +use Dancer2::Core::App; use Dancer2::Template::Tiny; my $f = Dancer2::Template::Tiny->new(); @@ -8,6 +10,43 @@ isa_ok $f, 'Dancer2::Template::Tiny'; ok( $f->does('Dancer2::Core::Role::Engine') ); ok( $f->does('Dancer2::Core::Role::Template') ); -is $f->name, 'Tiny'; +is( $f->name, 'Tiny' ); + +# checks for validity of engine names + +my $app = Dancer2::Core::App->new(); +isa_ok( $app, 'Dancer2::Core::App' ); + +{ + no warnings qw; + *Dancer2::Core::Factory::create = sub { $_[1] }; +} + +foreach my $engine_type ( qw ) { + my $engine; + my $build_method = "_build_${engine_type}_engine"; + + is( + exception { + $engine = $app->$build_method( + undef, { $engine_type => 'Fake43Thing' } + ); + }, + undef, + "Built $engine_type successfully", + ); + + like( + exception { + $engine = $app->$build_method( + undef, { $engine_type => '7&&afail' } + ); + }, + qr/^Cannot load $engine_type engine '7&&afail': illegal module name/, + "Built $engine_type successfully", + ); + + is( $engine, $engine_type, 'Correct response from override' ); +} done_testing;