OberonCore https://forum.oberoncore.ru/ |
|
Доступ через Meta к полям неэкспортированных объектов https://forum.oberoncore.ru/viewtopic.php?f=2&t=227 |
Страница 1 из 1 |
Автор: | Илья Ермаков [ Суббота, 03 Июнь, 2006 00:26 ] |
Заголовок сообщения: | Доступ через Meta к полям неэкспортированных объектов |
Обнаружил нюанас в метапрограммировании в ББ. Предыстория: технически в ББ можно добраться до любого поля любой переменной/типа, будь он экспортированный, неэскпортированный либо локально объявленный - для этого нужно обращаться к Kernel, чего, естественно, из прикладных модулей делать не следует. А контроль на доступность объекта по его метке экспорта проверяется уже на уровне модуля Meta - если объект неэкспортированный, то возвращается пустой Item. Однако синтаксически компилятор КП (по крайней мере, в BlackBox) допускает постановку метки экспорта для поля неэкспортированного типа. Я раньше думал, что просто для удобства программиста - чтобы для скрытия/открытия типа не приходилось перемечать все его поля. Однако обнаружилась интересная вещь - поля неэспортированных объектов, помеченные *, становятся доступны через Meta. Можно провести эксперимент: Код: MODULE TempMetaTarget;
IMPORT Meta; VAR rec: POINTER TO RECORD a: INTEGER END; PROCEDURE Do* ; VAR item, field: Meta.Item; BEGIN NEW(rec); Meta.GetItem(rec, item); ASSERT(item.Valid(), 20); item.Lookup("a", field); ASSERT(field.Valid(), 21) END Do; END TempMetaTarget. Запустим процедуру Do - получим TRAP 21. Все правильно. Item по указателю получить можно, работать с неэкспортированными полями нельзя. Поставим после a звездочку - код будет работать, доступ к полю получен. В принципе, такое поведение ничего плохого не несет и даже логично. Это позволяет, например, не открывать на полное обозрение какие-либо типы, но в то же время работать с ними через SqlDB и т.п. Однако возникает вопрос: Ominc сделали это намеренно или случайно? Как это согласуется со стандартом языка? Таким образом, при развитии BlackBox следует ли это а) сохранить и задокументировать б) сохранить, но не документировать и использование не поощрять в) посчитать ошибкой, "нарушением безопасности" и исправить Meta ? Я лично склоняюсь к варианту а). Прошу высказывать мнения и предложения... |
Автор: | Сергей Оборотов [ Суббота, 03 Июнь, 2006 06:46 ] |
Заголовок сообщения: | |
Только если править то не Meta, а то место где видимость устанавливается в компиляторе. Что предпочтительнее, по-моему. Если поля всё-таки нужны - то можно пользоваться экспортированными типами или Kernel напрямую. Какие с ними проблемы? |
Автор: | Илья Ермаков [ Суббота, 03 Июнь, 2006 15:42 ] |
Заголовок сообщения: | |
Цитата: а то место где видимость устанавливается в компиляторе. Править компилятор - последнее дело... Как я уже сказал, "отрезания" доступа к закрытым полям ЦЕЛИКОМ делается на уровне Meta. Цитата: Если поля всё-таки нужны - то можно пользоваться экспортированными типами или Kernel напрямую. Какие с ними проблемы?
В том-то и дело, что Kernel использовать нежелательно, если можно обойтись без него. |
Автор: | Сергей Оборотов [ Воскресенье, 04 Июнь, 2006 06:31 ] |
Заголовок сообщения: | |
Илья Ермаков писал(а): Цитата: а то место где видимость устанавливается в компиляторе. Править компилятор - последнее дело... Как я уже сказал, "отрезания" доступа к закрытым полям ЦЕЛИКОМ делается на уровне Meta. В том-то и дело, что Kernel использовать нежелательно, если можно обойтись без него. P.S. В крайнем случае компромисный вариант б вполне устроит тех, кто ничего об этом не знал. |
Автор: | Илья Ермаков [ Воскресенье, 04 Июнь, 2006 10:48 ] |
Заголовок сообщения: | |
Цитата: А почему экспортированный тип не использовать? Илья, Вы так и не сказали. Тогда можно и без Meta обойтись, насколько я понимаю.
Я уже привел пример. У меня есть модуль, работающий с базой данных. Я не знал про обсуждаемый нюанс и был вынужден открывать все типы, которые я читаю/пишу из базы через SqlDB, т.к. SqlDB работает именно через Meta (и правильно сделано, это не системный модуль. Если Stores "позволительно" работать через Kernel, то прикладным подсистемам уже нежелательно к нему привязываться). Мне нравится вариант не открывать целиком типы, а открыть только некоторые поля, которые должны считываться из базы. В принципе, такое поведение Meta/компилятора логично - каждый элемент имеет свою метку доступа. Если поле имеет метку доступа, а тип в целом не имеет, то служебные операции могут быть выполнены на полях, но не могут - на типе в целом. Брешей в безопасности это не создает. Я сделаю проще - спишусь с Ominc и проясню ситуацию - было ли это сделано случайно или намеренно. |
Автор: | Сергей Оборотов [ Понедельник, 05 Июнь, 2006 05:19 ] |
Заголовок сообщения: | |
Хорошо, а какие бреши в безопасности создает открытый тип? Если мне это будет понятно - то я, пожалуй, и соглашусь, что не стоит его открывать. |
Автор: | Илья Ермаков [ Понедельник, 05 Июнь, 2006 11:39 ] |
Заголовок сообщения: | |
Проблема не в безопасности, а в том, что нет необходимости засорять интерфейс модуля типами, которые используются только внутри самого модуля. |
Автор: | Сергей Оборотов [ Понедельник, 05 Июнь, 2006 16:02 ] |
Заголовок сообщения: | |
А почему не используется? Хотелось бы именно его и использовать. Тогда не придется Meta импортировать. Быстрее будет работать. |
Автор: | Илья Ермаков [ Понедельник, 05 Июнь, 2006 17:26 ] |
Заголовок сообщения: | |
Вы, видимо, слабо понимаете механизм метапрограммирования. Meta предназначен для того, чтобы ваш код мог работать с теми типами, о которых он вообще ничего не знает на этапе выполнения. SqlDB.Table.Read(row: INTEGER; rec: ANYREC) ничего не знает и знать не может про ваши конкретные типы. Через Meta происходит разбор структуры записи и заполнение ее данными из таблицы. Только в данный момент для того, чтобы работать со своим типом через SqlDB и аналогичные сервисы, приходится обязательно его экспортировать. Иначе SqlDB не найдет в нем ни одного поля и данные туда не занесет по понятным причинам. У меня, например, в библиотеке есть процедура ZeroRec, которая инициализирует нулями и "" любую запись, но она также работает только с экспортированными записями. Я могу, конечно, переписать через Kernel, но пока мне это не нужно. Модулю Stores как сердцу Framework'a, позволительно привязываться к Kernel, пользовательским модулям - нежелательно. В любом случае ждем ответа от Ominc - если текущее поведение Meta является не ошибкой, а сознательным решением, то тут и обсуждать нечего... |
Автор: | Сергей Оборотов [ Понедельник, 05 Июнь, 2006 21:32 ] |
Заголовок сообщения: | |
Я лишь высказал пожелание использовать открытые типы там, где Meta не нужен, не сужая тему противоположным случаем. Я себе представлял, что и Вы не только метапрограммирование имели в виду. Извините, если это было не так. Если речь вести о вещах не связанных с метапрограммированием, считаете ли Вы полезным иметь возможность доступа к полям не экспортируемого объекта? |
Автор: | Илья Ермаков [ Понедельник, 05 Июнь, 2006 22:02 ] |
Заголовок сообщения: | |
GUEST писал(а): Если речь вести о вещах не связанных с метапрограммированием, считаете ли Вы полезным иметь возможность доступа к полям не экспортируемого объекта?
Так такой доступ и есть только через метапрограммирование... На этапе компиляции сам тип недоступен, никакие действия с ним недоступны. |
Автор: | Сергей Оборотов [ Вторник, 06 Июнь, 2006 04:21 ] |
Заголовок сообщения: | |
Хотя вопрос предполагал два ответа, Вы, Илья, нашли третий. |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |