我在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()来防止恶意数据.我如何正确地转义命令和参数,以便其起作用?我尝试了很多选择,但我做对了.
解决方法:
是的,这是一个难题,因为该命令使用的是非标准的shell参数(例如它自己的小元语言). 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...