كيف يمكنني استخدام File::Find::Rule في وضع العيب؟

StackOverflow https://stackoverflow.com/questions/434149

  •  10-07-2019
  •  | 
  •  

سؤال

أحاول الحصول على قائمة بالأدلة الفرعية في دليل معين باستخدام شيء مثل ما يلي:

#!/usr/bin/perl -wT
use strict;
use warnings;

use File::Find::Rule;
use Data::Dumper;

my @subdirs = File::Find::Rule->maxdepth(1)->directory->relative->in('mydir');

print Dumper(@subdirs);

ومع ذلك، تشغيل هذا يعطي النتيجة:

Insecure dependency in chdir while running with -T switch

انا افهم ذلك File::Find لديه خيارات للتعامل مع الوضع الملوث، ولكن لا يبدو أنني أجد ما يعادله في File::Find::Rule.هل من الممكن القيام بما سبق؟هل يجب علي استخدام طريقة بديلة لإدراج الدلائل الفرعية؟هل أسيء فهم شيء واضح يجب أن أفهمه حقًا بشأن وضع العيب؟

هل كانت مفيدة؟

المحلول

(يحرر!) حسنًا، قد يشير المنطق إلى أن إضافة ما يلي سينجح:

->extras( {untaint => 1, untaint_pattern => $untaint_pattern, untaint_skip => 1} )

يتيح لك هذا استخدام ميزات الوضع الملوث في File::Find عن طريق تمرير الوسائط مباشرة إلى وحدة تلك الوحدة find() وظيفة.بالمناسبة، يشير File::Find إلى أنه يجب تعيينه $untaint_pattern باستخدام qr// المشغل أو العامل.على سبيل المثال، القيمة الافتراضية هي

$untaint_pattern = qr|^([-+@\w./]+)$|

لكن, ، هذا لا يعمل!في الواقع، مشكلتك هي خطأ معروف في File::Find::Rule.(على سبيل المثال، هنا CPAN و ديبيان تقارير الأخطاء.) إذا كنت ترغب في إصلاح الأخطاء، فإن كلا تقريري الأخطاء هذين يحتويان على تصحيحات.

إذا كنت في بيئة محظورة، فإن الشيء الوحيد الذي يمكنك القيام به هو تنفيذ التصحيح بنفسك في التعليمات البرمجية الخاصة بك.على سبيل المثال، إذا كنت تريد الاحتفاظ بكل شيء في ملف واحد، فيمكنك إضافة كتلة التعليمات البرمجية الكبيرة أدناه بعد ذلك use File::Find::Rule.لاحظ أن هذا حل سريع جدًا وقد يكون دون المستوى الأمثل.إذا لم ينجح الأمر معك (على سبيل المثال، نظرًا لوجود مسافات في أسماء الملفات الخاصة بك)، فقم بتغيير النمط qr|^([-+@\w./]+)$| الذي يتم استخدامه.

لاحظ أخيرًا أنه إذا كنت تريد أن يكون تنظيم التعليمات البرمجية الخاص بك أفضل قليلاً، فقد ترغب في تفريغ هذا في حزمة منفصلة، ​​ربما تسمى MyFileFindRuleFix أو شيء من هذا القبيل، والذي تستخدمه دائمًا use بعد File::Find::Rule بحد ذاتها.

package File::Find::Rule;
no warnings qw(redefine);
sub in {
    my $self = _force_object shift;

    my @found;
    my $fragment = $self->_compile( $self->{subs} );
    my @subs = @{ $self->{subs} };

    warn "relative mode handed multiple paths - that's a bit silly\n"
      if $self->{relative} && @_ > 1;

    my $topdir;
    my $code = 'sub {
        (my $path = $File::Find::name)  =~ s#^(?:\./+)+##;
        $path = "." if ($path eq ""); # See Debian bug #329377
        my @args = ($_, $File::Find::dir, $path);
        my $maxdepth = $self->{maxdepth};
        my $mindepth = $self->{mindepth};
        my $relative = $self->{relative};

        # figure out the relative path and depth
        my $relpath = $File::Find::name;
        $relpath =~ s{^\Q$topdir\E/?}{};
        my $depth = scalar File::Spec->splitdir($relpath);
        #print "name: \'$File::Find::name\' ";
        #print "relpath: \'$relpath\' depth: $depth relative: $relative\n";

        defined $maxdepth && $depth >= $maxdepth
           and $File::Find::prune = 1;

        defined $mindepth && $depth < $mindepth
           and return;

        #print "Testing \'$_\'\n";

        my $discarded;
        return unless ' . $fragment . ';
        return if $discarded;
        if ($relative) {
            push @found, $relpath if $relpath ne "";
        }
        else {
            push @found, $path;
        }
    }';

    #use Data::Dumper;
    #print Dumper \@subs;
    #warn "Compiled sub: '$code'\n";

    my $sub = eval "$code" or die "compile error '$code' $@";
    my $cwd = getcwd;
    # Untaint it
    if ( $cwd =~ qr|^([-+@\w./]+)$| ) {
        $cwd = $1;
    } else {
        die "Couldn't untaint \$cwd: [$cwd]";
    }
    for my $path (@_) {
        # $topdir is used for relative and maxdepth
        $topdir = $path;
        # slice off the trailing slash if there is one (the
        # maxdepth/mindepth code is fussy)
        $topdir =~ s{/?$}{}
          unless $topdir eq '/';
        $self->_call_find( { %{ $self->{extras} }, wanted => $sub }, $path );
    }
    chdir $cwd;

    return @found;
}
use warnings;
package main;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top