Основываясь на идее GhostDog, вот код, который будет на самом деле делать то, что вы хотите (исходный код, он отправил фактически не прочитать содержимое файла в):
//basename protects against directory traversal
//ideally we should also do a is_writable() check
$file = basename($_REQUEST['para'].".sql");
$text = file_get_contents($file);
$text = str_replace('NULL', '\\N', $text); //no need for a regex
file_put_contents($file, $text);
Следует признать, однако, если этот файл превышает несколько мегабайт, это нецелесообразно, так как весь файл будет считаться в памяти. Вы можете прочитать его на куски, но что бы получить немного сложнее:
$file = basename($_REQUEST['para'].".sql");
$tmpFile = tempnam("/tmp", "FOO");
$in = fopen($file, 'r');
$tmp = fopen($tmpFile, 'w');
while($line = fgets($in)) {
$line = str_replace('NULL', '\\N', $line);
fputs($tmp, $line);
}
fclose($tmp);
fclose($in);
rename($tmpFile, $file);
Если файл 100+ мег, честно, называя СЕПГ непосредственно, как вы будете быстрее. Когда дело доходит до больших файлов, накладные расходы на попытку воспроизведения такого инструмента, как sed/grep с его эквивалентом PHP, не стоит. Тем не менее, вы должны по крайней мере, предпринять некоторые шаги, чтобы защитить себя, если вы собираетесь сделать так:
Принимая некоторые основные шаги, чтобы обеспечить код amnom в:
$file = basename($_REQUEST['para'].".sql");
if(!is_writable($file))
throw new Exception('bad filename');
exec("sed -i 's/NULL/\\\\N/g' ".escapeshellarg($file));
- Первое, мы называем базовое имя, которые полосы любой путь из нашего файла (например, если злоумышленник представил строку «/ и т.д./пароль», мы, по крайней мере теперь ограничивая их файл «ПАРОЛЬ» в текущем рабочем каталоге
- Далее мы гарантируем, что файл находится в факте, доступен для записи. Если нет, мы не должны .
- Наконец, escapeshellarg() в файле. Несоблюдение этого условия позволяет выполнить произвольное выполнение команды. например, если атакующий отправил строку
/etc/passwd; rm -rf /; #
, вы получите команду sed 's/blah/blah/' /etc/passwd; rm -rf /; #.sql
. Должно быть ясно, что, хотя эта точная команда может не работать, найти ту, которая на самом деле была бы тривиальной.
Это не то же самое, если это то, что вы имеете в виду. После NULL второй имеет две косые черты. –
Бог поможет вам, если вы поместите '$ _REQUEST ['para']' в 'exec()' call! –
Похоже, что у вас может быть уязвимость в командной оболочке. –