From: Peter Rabbitson Date: Sat, 16 Jul 2016 11:29:40 +0000 (+0200) Subject: Work around the FIXME in the previous commit X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=5f0174dc9a33d03e4333fdf60e765dce325bf80a;p=dbsrgits%2FDBIx-Class.git Work around the FIXME in the previous commit Based on @haarg's excellent detective work: https://is.gd/perl_mro_taint_wtf --- diff --git a/lib/DBIx/Class/_Util.pm b/lib/DBIx/Class/_Util.pm index a8785c0..6a93f65 100644 --- a/lib/DBIx/Class/_Util.pm +++ b/lib/DBIx/Class/_Util.pm @@ -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 @@ -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?! @@ -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; diff --git a/xt/dist/strictures.t b/xt/dist/strictures.t index 8d15f12..5d8cb4e 100644 --- a/xt/dist/strictures.t +++ b/xt/dist/strictures.t @@ -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($_) } diff --git a/xt/extra/internals/describe_class_methods.t b/xt/extra/internals/describe_class_methods.t index 5a187cc..5d7217b 100644 --- a/xt/extra/internals/describe_class_methods.t +++ b/xt/extra/internals/describe_class_methods.t @@ -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 ... diff --git a/xt/extra/internals/namespaces_cleaned.t b/xt/extra/internals/namespaces_cleaned.t index 700a908..2230957 100644 --- a/xt/extra/internals/namespaces_cleaned.t +++ b/xt/extra/internals/namespaces_cleaned.t @@ -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 { @@ -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, }, (