Издательский дом ООО "Гейм Лэнд"СПЕЦВЫПУСК ЖУРНАЛА ХАКЕР #71, ОКТЯБРЬ 2006 г.

дублер каскадера

АЛЕКСАНДР ГЛАДЫШ

Спецвыпуск: Хакер, номер #071, стр. 071-068-4


Как же получить загруженные данные? Можно реализовать функции – ключевые слова нашего DDL - таким образом, чтобы они изменяли некую глобальную сущность. Однако это повышает связанность кода и уменьшает его гибкость.

Язык Lua позволяет явным образом возвращать значение (или даже несколько значений) при загрузке файла. Для этого достаточно в его конце написать выражение, использующее ключевое слово return так же, как если бы это была обычная функция. Удобно реализовывать корневую функцию иерархии (в нашем случае gui_layout) так, чтобы она возвращала собранные в процессе выполнения остального кода данные (либо сгенерированную функцию, выполняющую некие действия на основе этих данных).

Тогда, если дописать в начало листинга 1 ключевое слово return, можно будет добраться до загруженных данных, используя примерно такую конструкцию:

local data = assert(loadfile(“myguilayout.lua”))()

В переменную data будет помещено значение, возвращенное корневой функцией gui_layout. Для большей изящности ключевое слово return можно «подклеивать» автоматически перед загрузкой данных. В этом случае вместо load-file удобнее использовать loadstring.

Очевидно, помимо реализации необходимого набора ключевых слов мы должны ограничить пользователя в написании кода на Lua в файлах с данными только этим набором. Без дополнительного разбора текста описания данных невозможно запретить использование в нем произвольного кода, но это и не обязательно. Главное – не дать такому коду доступ к окружающему миру, как говорится, выполнять его в «песочнице» (sandbox). Тогда «лишний» код может быть как минимум бесполезен (но не вреден), но как максимум его можно использовать во благо – например, для генерации данных на лету. Строго говоря, еще нужно учитывать возможность подвесить загрузку данных, написав в файле с данными бесконечный цикл. Если требуется стопроцентная гарантия от вредоносного кода, необходимо контролировать процесс загрузки, например при помощи установки хуков на исполнение кода в функции debug.sethook, либо при помощи установки «вотчдога» в отдельном потоке.

К счастью, язык Lua предоставляет эффективное средство для создания такой «песочницы» – возможность явного задания таблицы глобального окружения (environment table) для функций при помощи стандартной функции setfenv. При загрузке данных в глобальное окружение необходимо поместить только функции – ключевые слова нашего DDL.

Функция loadfile возвращает функцию, содержащую весь код загружаемого файла. Глобальное окружение используется по умолчанию для всего этого кода. Заменив это окружение до вызова функции, можно заменить окружение, которое будет назначено коду в файле. Можно написать следующую функцию для загрузки файлов с данными:

load_ddl_file = function(name, ddl_keywords)

local loader = assert(loadfile(name))

Назад на стр. 071-068-3  Содержание  Вперед на стр. 071-068-5