Вернуться к исходному поведению sel getUid ()


TL; DR: Как проверить, что селектор с заданным именем был зарегистрирован, фактически не регистрируя его?

Спасибо!


Привет, у меня есть приложение Objective-C и куча NSObjects, которые экспортируются в состояние Lua через простую прокси-библиотеку, написанную в objc. Все вызовы Lua-стороны таковы:

exported_objc_object:myMethodName(...)

-- same as --
exported_objc_object.myMethodName(exported_objc_object, ...)

-- same as --
key = 'myMethodName'
exported_objc_object[key](exported_objc_object, ...)

Пересылаются так, как если бы кто-то позвонил:

[objc_object lua_myMethodName:L];

// declared as
- (int)lua_myMethodName:(lua_State *)L { ... }

На самом деле, любой код операции get на Lua-экспортированном объекте возвращает кэшированное Lua-закрытие, которое на вызов вызовет соответствующий метод Objective-C через селектор, построенный с sprintf(s, "lua_%s:", key)) && sel_getUid(s) (все чеки включены). Если произведенный селектор не реализован в терминах -[respondsToSelector:], то exported_objc_object.myMethodName просто возвращает nil.

Очевидно, что прокси-библиотека должна делать динамические запросы через sel_getUid() или sel_registerName() (я полагаю, что и @selector и NSSelectorFromString() также заканчиваются там). В руководстве говорится, что sel_getUid() был предназначен для поиска имен селекторов (в отличие от немедленной регистрации их в реестре SEL), но это современный реализация теперь делает то же самое, что и sel_registerName() из-за ошибок в чьем-то Teh codez тогда.

Я могу просто придерживаться поведения sel_registerName(), но это оставляет вектор атаки поедания памяти, так как некоторые вредоносные скрипты могут начать искать длинные случайные/недопустимые селекторы через sml object[makeRandomKey()] в цикле, таким образом, переполняя реестр SEL навсегда. Если sel_getUid() сработает по плану, прокси lib сможет проверить наличие селектора и только потом реально проверить, реагирует ли на него объект, без излишней регистрации. Но это не делает.

1 5

1 ответ:

Вот хак, который может сработать, который использует зависящий от реализации факт, что селектор является строкой C.

sel_isMapped((SEL)(void *)"lua_myMethodName:")