Skip to content

Commit

Permalink
Work around the FIXME in the previous commit
Browse files Browse the repository at this point in the history
Based on @haarg's excellent detective work: https://is.gd/perl_mro_taint_wtf
  • Loading branch information
ribasushi committed Jul 16, 2016
1 parent b090048 commit 5f0174d
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 38 deletions.
14 changes: 13 additions & 1 deletion lib/DBIx/Class/_Util.pm
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ BEGIN {

HAS_ITHREADS => $Config{useithreads} ? 1 : 0,

TAINT_MODE => 0 + ${^TAINT}, # tri-state: 0, 1, -1

UNSTABLE_DOLLARAT => ( PERL_VERSION < 5.013002 ) ? 1 : 0,

( map
Expand Down Expand Up @@ -757,6 +759,16 @@ sub modver_gt_or_eq_and_lt ($$$) {
croak "Expecting a class name either as the sole argument or a 'class' option"
if not defined $class or $class !~ $module_name_rx;

croak(
"The supplied 'class' argument is tainted: this is *extremely* "
. 'dangerous, fix your code ASAP!!! ( for more details read through '
. 'https://is.gd/perl_mro_taint_wtf )'
) if (
DBIx::Class::_ENV_::TAINT_MODE
and
Scalar::Util::tainted($class)
);

$requested_mro ||= mro::get_mro($class);

# mro::set_mro() does not bump pkg_gen - WHAT THE FUCK?!
Expand Down Expand Up @@ -899,7 +911,7 @@ sub modver_gt_or_eq_and_lt ($$$) {
if (
! DBIx::Class::_ENV_::OLD_MRO
and
${^TAINT}
DBIx::Class::_ENV_::TAINT_MODE
) {

$slot->{cumulative_gen} = 0;
Expand Down
4 changes: 2 additions & 2 deletions xt/dist/strictures.t
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ my $missing_groupdeps_present = grep
# don't test syntax when RT#106935 is triggered (mainly CI)
# FIXME - remove when RT is resolved
my $tainted_relpath = (
length $ENV{PATH}
DBIx::Class::_ENV_::TAINT_MODE
and
${^TAINT}
length $ENV{PATH}
and
grep
{ ! File::Spec->file_name_is_absolute($_) }
Expand Down
2 changes: 1 addition & 1 deletion xt/extra/internals/describe_class_methods.t
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ sub add_more_attrs {
unless(
! DBIx::Class::_ENV_::OLD_MRO
and
${^TAINT}
DBIx::Class::_ENV_::TAINT_MODE
) {
#local $TODO = "On 5.10+ -T combined with stash peeking invalidates the pkg_gen (wtf)" if ...

Expand Down
38 changes: 4 additions & 34 deletions xt/extra/internals/namespaces_cleaned.t
Original file line number Diff line number Diff line change
Expand Up @@ -39,45 +39,14 @@ use Test::More;

use DBICTest;
use File::Find;
use File::Spec;
use DBIx::Class::_Util qw( get_subname describe_class_methods );

# makes sure we can load at least something
use DBIx::Class;
use DBIx::Class::Carp;

my @modules = map {
# FIXME: AS THIS IS CLEARLY A LACK OF DEFENSE IN describe_class_methods :FIXME
# FIXME !!! without this detaint I get the test into an infloop on 5.16.x
# (maybe other versions): https://travis-ci.org/ribasushi/dbix-class/jobs/144738784#L26762
#
# or locally like:
#
# ~$ ulimit -v $(( 1024 * 256 )); perl -d:Confess -Ilib -Tl xt/extra/internals/namespaces_cleaned.t
# ...
# DBIx::Class::MethodAttributes::_attr_cache("DBIx::Class::Storage::DBI::ODBC::Firebird") called at lib/DBIx/Class/MethodAttributes.pm line 166
# DBIx::Class::MethodAttributes::_attr_cache("DBIx::Class::Storage::DBI::ODBC::Firebird") called at lib/DBIx/Class/MethodAttributes.pm line 166
# DBIx::Class::MethodAttributes::_attr_cache("DBIx::Class::Storage::DBI::ODBC::Firebird") called at lib/DBIx/Class/MethodAttributes.pm line 166
# DBIx::Class::MethodAttributes::_attr_cache("DBIx::Class::Storage::DBI::ODBC::Firebird") called at lib/DBIx/Class/MethodAttributes.pm line 154
# DBIx::Class::MethodAttributes::FETCH_CODE_ATTRIBUTES("DBIx::Class::Storage::DBI::ODBC::Firebird", CODE(0x42ac2b0)) called at /home/rabbit/perl5/perlbrew/perls/5.16.2/lib/5.16.2/x86_64-linux-thread-multi-ld/attributes.pm line 101
# attributes::get(CODE(0x42ac2b0)) called at lib/DBIx/Class/_Util.pm line 885
# eval {...} called at lib/DBIx/Class/_Util.pm line 885
# DBIx::Class::_Util::describe_class_methods("DBIx::Class::Storage::DBI::ODBC::Firebird") called at xt/extra/internals/namespaces_cleaned.t line 129
# Out of memory!
# Out of memory!
# Out of memory!
# ...
# Segmentation fault
#
# FIXME: AS THIS IS CLEARLY A LACK OF DEFENSE IN describe_class_methods :FIXME
# Sweeping it under the rug for now as this is an xt/ test,
# but someone *must* find what is going on eventually
# FIXME: AS THIS IS CLEARLY A LACK OF DEFENSE IN describe_class_methods :FIXME

( $_ =~ /(.+)/ )

} grep {
my ($mod) = $_ =~ /(.+)/;
my @modules = grep {
my $mod = $_;

# not all modules are loadable at all times
do {
Expand Down Expand Up @@ -218,7 +187,8 @@ sub find_modules {
$_ =~ m|lib/DBIx/Class/_TempExtlib| and return;
s/\.pm$// or return;
s/^ (?: lib | blib . (?:lib|arch) ) . //x;
push @modules, join ('::', File::Spec->splitdir($_));
s/[\/\\]/::/g;
push @modules, ( $_ =~ /(.+)/ );
},
no_chdir => 1,
}, (
Expand Down

0 comments on commit 5f0174d

Please sign in to comment.