如何伪造perl模块的依赖?

时间:2011-06-29 03:51:11

标签: perl dependencies perl-module dbd

我正在使用的外部Perl库有一个我不会在我的应用程序中使用的依赖项(DBD :: mysql)(DBD :: SQLite),所以我希望系统只是假装依赖存在,即使它是“假的”。

我是否可以创建一个空的DBD :: mysql.pm模块来编译或者有更直接的方法吗?

1 个答案:

答案 0 :(得分:8)

所以我认为这里几乎没有问题。

当你说依赖时,你是说外部模块只是尝试requireuse DBD::mysql?如果是这种情况,那么你应该告诉开发人员他不应该明确地这样做,因为这违背了使用DBI的目的。应根据DSN动态选择数据库驱动程序。

假设作者只是use包名,因为他认为这是一个有用或有意义的事情,那么,你可以覆盖那个包,并且几种方法。

正如您的建议,您只需创建自己的模块DBD/mysql.pm即可定义DBD::mysql包。

如果您有兴趣,还有其他一些事情可以做。您只需要说服Perl模块已加载,而不是使用伪目录和文件乱丢您的源代码树。我们可以通过直接操作%INC来完成此操作。

package main;    # or whereever

BEGIN {
    $INC{'DBD/mysql.pm'} = "nothing to see here";
}

只需添加此哈希密钥,我们就不会搜索有问题的模块的文件系统。观察到它位于BEGIN块中。如果外部作者执行了use,那么我们必须在评估use语句之前填充此值。 use语句相当于require中包含的importBEGIN

现在让我们进一步推测外部作者试图调用包的方法。如果那些符号不存在,您将收到运行时错误。您可以利用Perl的AUTOLOAD拦截此类呼叫,并做正确的事情。什么正确的东西可以变化很大,从简单地记录消息到更精细的东西。例如,您可以使用此工具通过监视所有调用来检查作者引入的耦合深度。

package DBD::mysql;

sub AUTOLOAD {
    printf(
        "I don't wanna '%s' called from '%s'\n", $AUTOLOAD, caller(0)
      );
}

package main;    # or whereever

BEGIN {
    $INC{'DBD/mysql.pm'} = "nothing to see here";
}

DBD::mysql::blah()

现在我们还介绍一下违规作者还创建了一个类的面向对象实例,并且他的代码没有正确的帐户 为您的存根代码。我们将使用我们假设为new的构造函数来保存我们的包名称的匿名哈希。这样你就不会得到 他在实例上调用方法时出错。

package DBD::mysql;

sub AUTOLOAD {
    printf(
        "I don't wanna '%s' called from '%s'\n", $AUTOLOAD, caller(0)
    );
}

sub new {
    bless({}, __PACKAGE__)
}

package main;    # or whereever

BEGIN {
    $INC{'DBD/mysql.pm'} = "nothing to see here";
}

my $thing = new DBD::mysql;

$thing->blah()