"PHP" / Говнокод #13438 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
if (!class_exists($module, false))
{
// Get content from php file
$filepath = _PS_MODULE_DIR_.$module.'/'.$module.'.php';
$file = trim(file_get_contents(_PS_MODULE_DIR_.$module.'/'.$module.'.php'));
if (substr($file, 0, 5) == '<?php')
	$file = substr($file, 5);
if (substr($file, -2) == '?>')
	$file = substr($file, 0, -2);

// If (false) is a trick to not load the class with "eval".
// This way require_once will works correctly
if (eval('if (false){	'.$file.' }') !== false)
	require_once( _PS_MODULE_DIR_.$module.'/'.$module.'.php' );
else
	$errors[] = sprintf(Tools::displayError('%1$s (parse error in %2$s)'), $module, substr($filepath, strlen(_PS_ROOT_DIR_)));
}

Это оригинал кода из знаменитого Prestashop ...
Попросили написать модуль. Долго мучался, почему валидный код не работает. Потом нашел.
Смысл логики в строках 13-17 : мы не хотим принимать файлы модулей с eval функцией.
Поэтому мы сначала проверяем, есть ли eval в файле.
Как проверяем?
А давайте его просто выполним!
Если выполнится - тогда - require_once
В общем я О....ЕЛ! Других слов просто нет.
Мало того, так еще нужно следить, чтобы ваш файл модуля был валидным для eval функции.
Иначе - Parse error: syntax error ...

Запостил: corner578 corner578, (Updated )

Комментарии (6) RSS

  • Лет ми спик фром май харт, бат ин май хамбл апиньен зе транслейшн оф камментс из щитти. И с выводами публикатор торопится, не изучив логику работы: http://ideone.com/WHHiiR

    if (false)” используется, чтобы конструкция скомпилировалась, но не выполнилась: «... is a trick to not load...» А переводить а английского нужно с конца: «the class with "eval"» — исходная информация, а «to not load» — новая.

    Да, мы пытаемся скомпилировать файл модуля, не выполняя его, а после попытки eval вернёт false, если не компилируется. Проверка выполняется оператором !==, чтобы отличить его от NULL, который eval вернёт в случае успешной компиляции.

    В итоге require_once выполнится, только если включаемый файл валидный с точки зрения eval (для того и сравнение !== false). Наличие же eval во включаемом модуле не проверяется, поэтому смело можете закладывать в модуль бомбу.
    Ответить
    • И зачем все это? Ради двойной загрузки? Про наличие eval (проверка на наличие) - я тестировал, это действительно так. Объясните, в чем смысл проверки? Дважды файл грузить? Или обеспечить электростанции работой?
      Ответить
      • Последний шанс реабилитации автора: проверка сделана для того, чтобы код не валился в случайном месте. В случае синтаксической ошибки во внешнем модуле он не будет подключен и код попытается отработать без него, выведя нормальную страницу, пусть и с отсутствующими элементами.

        Однако, я бы понял автора, если бы результат проверки кэшировался (записывался бы в конфиг), но грузить каждый раз модуль дважды — лишняя работа. Поэтому нет автору прощения, придётся признать Вашу правоту.
        Ответить

Добавить комментарий

Где здесь C++, guest?!

    А не использовать ли нам bbcode?


    8