swg2you 403 Опубликовано: 24 июня, 2015 (изменено) пример кода: a=1 local e={print=print, load=load, a='2'} e._G=e load( [[ print(a) load("print(a)")() ]] , '', '', e)() ожидается вывод:22а в реальности:21 Проверял и под OpenOS и в чистой среде. Это баг или фича? Изменено 25 июня, 2015 пользователем swg2you Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
1Ridav 1 049 Опубликовано: 24 июня, 2015 Такое происходит из-за биндинга, есть разница между статичным и динамичным. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
swg2you Автор вопроса 403 Опубликовано: 24 июня, 2015 (изменено) Такое происходит из-за биндинга, есть разница между статичным и динамичным. Не понял. load("print(a)") вызванный с параметрами "по умолчанию", должен компилировать блок "print(a)" в среде _G Поскольку для load("print(a)") глобальной средой является e, то ожидается что именно e будет средой для "print(a)" Но, почему-то, load берет среду из места в которое не должен иметь доступа. Изменено 24 июня, 2015 пользователем swg2you Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Krutoy 1 169 Опубликовано: 25 июня, 2015 а в реальности: 2 1 Да, действительно, выдает не то, что подразумевается. Но не 2,1 а 2, nil. Почему так происходит не в курсе, нужно видимо у самого Сангара спрашивать, либо копаться в реализации этого load() на гитхабе. Такое происходит из-за биндинга Какой еще биндинг, Рид? Мониторов что ли? =)) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
swg2you Автор вопроса 403 Опубликовано: 25 июня, 2015 Да, действительно, выдает не то, что подразумевается. Но не 2,1 а 2, nil. Почему так происходит не в курсе, нужно видимо у самого Сангара спрашивать, либо копаться в реализации этого load() на гитхабе. nil - это я первую строчку в примере потерял. поправил пример. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Zer0Galaxy 2 187 Опубликовано: 25 июня, 2015 Месье знает толк в извращениях 5 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Totoro 3 563 Опубликовано: 25 июня, 2015 (изменено) Это баг или фича? В для первого load() ты указываешь переменную окружения, насколько я понял. Для второго - нет (используется "глобальное окружение"). Поэтому, у них разные переменные а. Строка из документации: When loading a chunk, the top-level function gets a new _ENV upvalue, and any nested functions inside it can see it. You can pretend that when loading works something like this: local _ENV = _Greturn function (...) -- this function is what's returned from load -- code you passed to load goes here, with all global variable names replaced with _ENV lookups -- so, for example "a = b" becomes "_ENV.a = _ENV.b" if neither a nor b were declared local end Т.е. загруженный чанк получает новую переменную окружения, и при этом LVM выдает ей "внешний" _G. Изменено 25 июня, 2015 пользователем Totoro 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
swg2you Автор вопроса 403 Опубликовано: 25 июня, 2015 (изменено) В для первого load() ты указываешь переменную окружения, насколько я понял. Для второго - нет (используется "глобальное окружение"). Поэтому, у них разные переменные а. Да, но блок [[ print(a) load("print(a)")() ]] скомпилирован в среде e. Для этого блока глобальной средой является содержимое таблицы e. Т.е. все что находится в этом блоке не может видеть ничего кроме переданных функций print, load, заданной a и замыкающей _G. Получается что load() игнорируя принципы Lua и собственную среду выполнения - получает доступ к рутовому глобалу, мало того, дает этот доступ компилируемому блоку. На мой взгляд, это серьезный баг реализации, нарушающий общую концепцию изоляции сред в Lua. Либо я неверно понимаю эту концепцию. upd: если у кого-то установлен чистый Lua без майнкрафтов и прочих крафтов, прошу проверить, проявляется ли такой эффект там. Изменено 25 июня, 2015 пользователем swg2you Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Zer0Galaxy 2 187 Опубликовано: 25 июня, 2015 (изменено) Я давно подозревал, что функция serialization.unserialize - дыра для хакера Хотя, нет. Что бы дыра стала дырой в окружении должна быть разрешена функция load. А в serialization.unserialize - только math.huge Изменено 25 июня, 2015 пользователем Zer0Galaxy Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Zer0Galaxy 2 187 Опубликовано: 25 июня, 2015 (изменено) если у кого-то установлен чистый Lua без майнкрафтов и прочих крафтов, прошу проверить, проявляется ли такой эффект там. a=1 load(" print(a) load('print(a)')()",nil,nil,{print=print, load=load, a=2})() Результат: 2 1 Вывод: не хочешь давать доступ к руту - не разрешай в среде функцию load Изменено 25 июня, 2015 пользователем Zer0Galaxy Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
swg2you Автор вопроса 403 Опубликовано: 25 июня, 2015 (изменено) a=1 load(" print(a) load('print(a)')()",nil,nil,{print=print, load=load, a=2})() Результат: 2 1 Вывод: не хочешь давать доступ к руту - не разрешай в среде функцию load Если это результат выполнения на одной из чистых реализаций, то этот баг вполне можно считать фичей. Убрать load - не вариант. Придется учитывать эту особенность и исправлять поведение кода на более каноничное. upd: задал тот-же вопрос на стаковерфлоу, отвечают что если не указать среду лоад берет, цитирую: "very global environment" ) будем глушить. OpenOs то надо в окошке запустить. Изменено 26 июня, 2015 пользователем swg2you Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Zer0Galaxy 2 187 Опубликовано: 26 июня, 2015 Да, это выполнялось в самом чистом Луа, который мне удалось найти. А что если сделать как-то так: a=1 e={print=print, a=2} e.load=function(str) return load(str,nil,nil,e) end load(" print(a) load('print(a)')()",nil,nil,e)() Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
SergOmarov 34 Опубликовано: 26 июня, 2015 Месье знает толк в извращениях Это вы писали эту статью?http://habrahabr.ru/post/182018/ 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Zer0Galaxy 2 187 Опубликовано: 26 июня, 2015 Это вы писали эту статью?http://habrahabr.ru/post/182018/ Нет. Проблема избавления от двоеточий передо мной остро не стоит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
swg2you Автор вопроса 403 Опубликовано: 26 июня, 2015 Да, это выполнялось в самом чистом Луа, который мне удалось найти. А что если сделать как-то так: a=1 e={print=print, a=2} e.load=function(str) return load(str,nil,nil,e) end load(" print(a) load('print(a)')()",nil,nil,e)() именно так. но чуть менее грубо. e.load=function(c,s,m,g) return load(c,s,m,g or e) end чтобы все параметры обрабатывались, а среда по умолчанию бралась из среды выполнения. там еще вроде с _ENV можно сыграть, но я в нем пока не разобрался. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
пример кода:
ожидается вывод:
Изменено пользователем swg2you2
2
а в реальности:
2
1
Проверял и под OpenOS и в чистой среде.
Это баг или фича?
Поделиться сообщением
Ссылка на сообщение
Поделиться на других сайтах