Обход областей видимости или неожиданное поведение функции EACH

в 10:27, , рубрики: each, php, private, ошибки, уязвимости, метки: , , , ,

Никогда не понимал зачем в PHP функция each. Ведь есть foreach…
Но сегодня у меня «сломался» один участок кода, который жил шесть лет.
Там была конструкция с использованием each.
ошибка была исправлена секунд за 30 — давно думал исправить это все на foreach, но оставлял в качестве напоминания о том, какой индокод у меня был в свое время. Но просто исправить и пройти мимо я не мог.
Итак each против ООП:
1 — each игнорирует области видимости и спокойно выводит private свойства.
2 — each работает в обход стандартных интерфейсов вроде Iterator или ArrayAccess — классы реализующие эти интерфейсы всё равно обрабатываются данной функцией неправильно.
3 — Казенный класс ArrayObject воспринимается ею правильно.
4 — Классы наследующие от ArrayObject также работают верно.

5 — Формат возвращаемых данных тоже специфичен.
5.1 — имена свойств возвращаются в виде «имя_класса».«имя_свойства» (где точка это конкатенация)
5.2 — цикл while (list($key, $value) = each($data)) возвращает хоть сколько-то ожидаемый результат
5.3 — Но реально она возвращает нам ЧЕТЫРЕ значения.

class my {
    private $love = 'girl';
}
$obj = new my;
while ($line = each($obj)) {
    var_dump($line);
}

Возвращает:

array(4) {
[1]=>
string(4) "girl"
["value"]=>
string(4) "girl"
[0]=>
string(8) "

Если у вас как и у меня появились вопросы почему при таком порядке записей в ответе LIST работает «правильно», то перечитайте внимательно описание к LIST. Как оказалось я неправильно понимал логику работы LIST, и она работает вовсе не по порядку, а по индексам. Об этом подробно уже было написано, не буду останавливаться.

Есть гипотеза, что такое поведение связано с тем, что функция получает на входе ССЫЛКУ на массив.
Возможно таким образом интерпретируется структура объекта как массива…
Стоит поэкспериментировать с наследованим и переопределением свойств, доступом к родительским и т.п., но пока не вижу во всем этом практического применения. Вернее интуитивно подозреваю что это может привести к более серьезной уязвимости чем доступ к приватным свойствам, но пока не знаю что с этим делать дальше…

Автор: Mendel

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js