3

LinuxでExiv2コマンドラインツールを使用して、次のように画像メタデータを編集します。

exiv2 -M"set Iptc.Application2.Caption String This is my caption....." modify IMG.jpg

ユーザーから提供されたキャプションを使用して、PHPからこれを実行したいと思います。これは、ユーザーが特殊文字を入力しない場合に機能します。

exec('/usr/local/bin/exiv2 -M"set Iptc.Application2.Caption String '.$caption.'" modify IMG.jpg');

一重引用符や二重引用符などの特殊文字をユーザーに許可する必要があります。悪意のあるデータを防ぐためにescapeshellcmd()を使用したいと思います。コマンドと引数を正しくエスケープして機能させるにはどうすればよいですか?私は多くのオプションを試しましたが、正しく理解できません。

4

3 に答える 3

5

はい、これは難しい問題です。コマンドが非標準のシェル引数を使用しているためです(独自の小さなメタ言語のように)。ImageMagickにも同じ問題があります。

二重引用符で囲まれた文字列内でescapeshellarg()を使用するだけでは、役に立たなくなります。escapeshellcmd()はすべての特殊文字をエスケープし、二重引用符で囲まれた文字列で安全に使用できます。したがって、正しく機能させるには、その周りに一重引用符をハードコーディングする必要があります。

exec('/usr/local/bin/exiv2 -M"set Iptc.Application2.Caption String \'' . escapeshellcmd($caption) . '\'" modify IMG.jpg');

単一引用符で囲まれた文字列でescapeshellarg()が機能しない理由は次のとおりです。

# for this input:
The smith's "; rm -rf *; echo "went to town

# after escapeshellarg()
'The smith\'s "; rm -rf *; echo "went to town'

# Works fine if left as a top-level argument
/usr/bin/command 'The smith\'s "; rm -rf *; echo "went to town'

# BUT if put in a double-quoted string:
/usr/bin/command "subcommand1 'The smith\'s "; rm -rf *; echo "went to town'"

# it is broken into 3 shell commands:
/usr/bin/command "something and 'The smith\'s ";
rm -rf *;
echo "went to town'"

# bad day...
于 2009-08-10T17:04:41.117 に答える
0

ヒアドキュメントの使用はどうですか?

$str = <<<'EOD'
/usr/local/bin/exiv2 -M "set Iptc.Application2.Caption String $options" modify IMG.jpg
EOD;
exec($str);

これを変更して excapeshellcmd() を使用するには:

$options = excapeshellcmd($caption);
$command = <<<'EOD'
/usr/local/bin/exiv2 -M"set Iptc.Application2.Caption String $options" modify IMG.jpg
EOD;
exec($command);
于 2009-08-10T17:15:25.247 に答える
0

Exiv2 の非標準のシェル引数のため、ユーザーが指定した引用符を正しく処理するための単純で堅牢なソリューションに到達するのは容易ではありません。わずかなパフォーマンスの低下で、はるかに信頼性が高く、保守が容易である可能性が高い別のソリューションがあります。

Exiv2 命令を filecmds.txtに書き込み、次を呼び出します。

exiv2 -m cmds.txt IMG.jpg

ファイルから指示を読み取ります。

更新: このメソッドを実装しました。ユーザーが指定したデータをエスケープする必要はありません。このデータは、Exiv2 によって読み取られるテキスト ファイルに直接書き込まれます。Exiv2 コマンド ファイル形式は非常にシンプルで、改行で終了し、値内でのエスケープは許可されていません。

于 2009-08-11T12:09:15.340 に答える