6

短縮版

以下のコードでは、$1が汚染されており、その理由がわかりません。

ロングバージョン

汚染チェックモードが有効になっている perl v5.14.2 のシステムで Foswiki を実行しています。-Tそのセットアップの問題をデバッグして、次の SSCCE を構築することができました。(私がこの投稿を編集したことに注意してください。最初のバージョンはより長く、より複雑でした。コメントはまだそれを参照しています。)

#!/usr/bin/perl -T
use strict;
use warnings;
use locale;
use Scalar::Util qw(tainted);
my $var = "foo.bar_baz";
$var =~ m/^(.*)[._](.*?)$/;
print(tainted($1) ? "tainted\n" : "untainted\n");

入力文字列$varは汚染されておらず、正規表現は修正されていますが、結果のキャプチャ グループ$1は汚染されています。本当に奇妙だと思います。

perlsec のマニュアルには、汚染と正規表現について次のように書かれています。

値は、ハッシュのキーとして使用することで汚染されていない可能性があります。それ以外の場合、汚染メカニズムをバイパスする唯一の方法は、正規表現の一致からサブパターンを参照することです。Perl は$1$2、 などを使用して部分文字列を参照する場合、パターンを書いたときに何をしていたかを知っていると想定します。

入力が汚染されていたとしても、出力はまだ汚染されていないと思います。逆に、汚染されていない入力からの汚染された出力は、perl の奇妙なバグのように感じられます。しかし、perlsec をもっと読むと、ユーザーは perllocale の SECURITY セクションに誘導されます。そこには次のように書かれています。

use locale が有効な場合、Perl は汚染メカニズム (perlsec を参照) を使用して、文字列の結果がロケールに依存するようになり、結果的に信頼できない可能性があることをマークします。ロケールによって影響を受ける可能性のある演算子と関数の汚染動作の概要を次に示します。

  • 比較演算子 ( ltlegegtおよびcmp) […]

  • ケースマッピング補間 ( \l\L\uまたは\U) […]

  • 一致演算子 ( m//):

    スカラーの true/false の結果が汚染されることはありません。

    use locale $1 ( but not use locale ':not_characters') が有効で、サブパターンの正規表現に\w(英数字と一致するため)、\W (英数字以外の文字)、\s(空白文字)、または\S (非空白文字)。use locale が有効で、正規表現に、、、またはが含まれている場合、matched-pattern 変数 、$&($` 一致前)、$'(一致後)、および$+(最後の一致) も汚染されます 。\w\W\s\S

  • 置換演算子 ( s///) […]

        [⋮]

これは完全なリストであるように見えます。そして、それがどのように適用されるかわかりません。私の正規表現は\w\W\sまたは\Sを使用していないため、ロケールに依存するべきではありません。

このコードが varibale を汚染する理由を誰かが説明できますか$1?

4

1 に答える 1

0

現在、質問で引用されているドキュメントと、perl 5.18.1 の実際の実装との間に矛盾があります。問題は文字クラスです。ドキュメントでは、完全なリストのように聞こえるものの中で, ,\w\s言及されていますが、実装は.\W\S[…]

適切な解決策は、おそらくその中間のどこかにあるでしょう[[:word:]]。ロケールに依存するため、 のような文字クラスは汚染する必要があります。私の固定リストはすべきではありません。文字の範囲は[a-z]照合に依存するため、私の個人的な意見では、それらも汚染する必要があります。\dロケールが数字を何と見なすかに依存するため、これまでに述べたエスケープ シーケンスのいずれでもなく、ブラケット クラスでもなくても、汚染する必要があります。

したがって、私の意見では、ドキュメントと実装の両方を修正する必要があります。Perl 開発者はこれに取り組んでいます。進捗状況については、私が提出した perl バグ レポートを参照してください。

文字の固定リストの場合、実行可能な回避策の 1 つは、論理和として定式化すること(?:\.|_)です[._]。これはより冗長ですが、現在の (私の意見ではバグがある) perl バージョンでも動作するはずです。

于 2013-12-06T01:20:29.477 に答える