2010-01-12 4 views
1
echo "sed -i 's/NULL/\\N/g' ".$_REQUEST['para'].".sql"; 

Приведенное выше описание работает. Но это не в состоянии, когда я использую его в Exec, как это ...sed не работает с функцией PHP exec

exec("sed -i 's/NULL//\/\/\N/g' ".$_REQUEST['para'].".sql"); 
+0

Это не то же самое, если это то, что вы имеете в виду. После NULL второй имеет две косые черты. –

+7

Бог поможет вам, если вы поместите '$ _REQUEST ['para']' в 'exec()' call! –

+2

Похоже, что у вас может быть уязвимость в командной оболочке. –

ответ

5

Вы должны избежать обратной косой черты с обратной косой черты, а не с слэша, например:

exec("sed -i 's/NULL/\\\\N/g' ".$_REQUEST['para'].".sql"); 

EDIT Я написал ответ не глядя на то, что на самом деле делает код. Не делайте этого, потому что $_REQUEST['para'] может быть любым, чего хочет пользователь, который может использоваться для code injection. Используйте другие функции PHP, как предлагает другой ответ.

+0

Слова, содержащие NULL в нем, заменяются. Для. например TNULLL стал TNL Как добавить границы слов? – shantanuo

3

Хотя это полностью зависит от вас, но мой совет заключается в том, чтобы не требовать системных команд без необходимости. В PHP вы можете использовать preg_replace() для выполнения функций sed.

preg_replace("/NULL/","\\N",file_get_contents("$_REQUEST['para']"."sql")) 
+0

Думаю, вам не хватает цитаты. –

+1

Я думаю, что предметом замены является не имя файла, а сам файл. Но ваша идея лучше и безопаснее. – stefita

+0

@mark, thks. fixed – ghostdog74

1

Основываясь на идее 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)); 
  1. Первое, мы называем базовое имя, которые полосы любой путь из нашего файла (например, если злоумышленник представил строку «/ и т.д./пароль», мы, по крайней мере теперь ограничивая их файл «ПАРОЛЬ» в текущем рабочем каталоге
  2. Далее мы гарантируем, что файл находится в факте, доступен для записи. Если нет, мы не должны .
  3. Наконец, escapeshellarg() в файле. Несоблюдение этого условия позволяет выполнить произвольное выполнение команды. например, если атакующий отправил строку /etc/passwd; rm -rf /; #, вы получите команду sed 's/blah/blah/' /etc/passwd; rm -rf /; #.sql. Должно быть ясно, что, хотя эта точная команда может не работать, найти ту, которая на самом деле была бы тривиальной.
+0

Неустранимая ошибка: допустимый размер памяти 20971520 байт исчерпан (пытался выделить 7444267 байт) в somefile.php на строке номер 123 Я попытался увеличить выделенную память с помощью ini_set ("memory_limit", "20M"); но он по-прежнему не работает должным образом. – shantanuo

+0

Сделал серьезные изменения, чтобы охватить другие 2 пути приближения к этому. Первый подход подходит для небольших файлов; во-вторых, для файлов более нескольких мегабайт, но, вероятно, менее 100; и финал честно - самый быстрый способ для файлов размером 100 мегабайт. –

+0

Я предлагаю увеличить ограничение памяти до 32 или 64. Я должен был сделать это, чтобы запустить некоторые скрипты раньше. – JAL

Смежные вопросы