Как эффективно найти запросы без конструкции РАЗРЕШЕННЫЕ в коде 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При автоматизации проверок безопасности подсистем 1С часто возникает задача: убедиться, что все запросы либо используют конструкцию РАЗРЕШЕННЫЕ, либо выполняются в привилегированном режиме. Попытки решить эту задачу с помощью регулярных выражений (RegExp) часто приводят к трудностям из-за сложности синтаксиса языка запросов. Давайте разберем, почему этот путь может быть ошибочным и как правильно подойти к задаче.

Почему регулярные выражения — это «две проблемы» в 1С?

Первая проблема — вы пытаетесь решить задачу с помощью регулярных выражений. Вторая проблема — у вас уже две проблемы. В контексте анализа запросов 1С это высказывание актуально как никогда по нескольким причинам:

  1. Ограниченность движка: Объект VBScript.RegExp, используемый в 1С, не поддерживает полноценные «lookbehind» (просмотр назад), что затрудняет проверку условий типа «выбрать, если перед этим нет того-то».
  2. Комментарии и кавычки: Запрос может содержать комментарии, строковые константы или быть разбит на части. Регулярка, которая видит слово ВЫБРАТЬ, может ошибочно принять его за часть текстовой строки или комментария.
  3. Сложность синтаксиса: В языке запросов 1С порядок ключевых слов после ВЫБРАТЬ (например, ПЕРВЫЕ, РАЗЛИЧНЫЕ, РАЗРЕШЕННЫЕ) может быть произвольным, что делает паттерн поиска крайне громоздким и ненадежным.

Решение через объектную модель: СхемаЗапроса

Вместо того чтобы вручную «парсить» текст регулярками, воспользуемся штатным инструментом платформы — СхемаЗапроса. Этот объект специально создан для разбора структуры запроса. Он понимает пакетные запросы, объединения и вложенные подзапросы, автоматически игнорируя комментарии и строковые литералы.

Рассмотрим, как реализовать этот подход по шагам:

  1. Получение текста запроса: Если вы анализируете исходники (например, выгрузку в формате EDT), сначала найдите строковые константы, содержащие слово ВЫБРАТЬ.
  2. Использование СхемаЗапроса: Передайте найденный текст в конструктор СхемаЗапроса.
  3. Анализ свойства: Объект СхемаЗапроса имеет свойство Разрешенные (булево), которое прямо указывает на наличие конструкции РАЗРЕШЕННЫЕ в запросе.

Пример программного разбора:


// Предположим, у нас есть строка с текстом запроса
ТекстЗапроса = "ВЫБРАТЬ РАЗРЕШЕННЫЕ Ссылка ИЗ Справочник.Номенклатура";
Схема = Новый СхемаЗапроса;
Схема.УстановитьТекстЗапроса(ТекстЗапроса);

// Проверяем наличие РАЗРЕШЕННЫЕ
Если Не Схема.Разрешенные Тогда
    // Запрос не содержит РАЗРЕШЕННЫЕ, нужно проверить наличие привилегированного режима
    Сообщить("Нарушение безопасности: запрос без РАЗРЕШЕННЫЕ");
КонецЕсли;

Как эффективно обрабатывать большие объемы кода?

Многие программисты опасаются, что СхемаЗапроса работает слишком медленно для обработки всей конфигурации. Однако на практике общее время анализа даже большой конфигурации увеличивается на считанные секунды, что вполне допустимо для автоматических тестов или инструментов статического анализа.

Чтобы ускорить процесс, мы рекомендуем использовать двухуровневый подход:

Полезные советы для автоматизации

Если вам нужно выводить пользователю номер строки, в которой найдено нарушение, не обязательно усложнять алгоритм. Можно воспользоваться простой функцией для расчета:


Позиция = Найти(ТекстМодуля, "ВЫБРАТЬ");
НомерСтроки = СтрЧислоСтрок(Лев(ТекстМодуля, Позиция));

Важно помнить:

Если ваш тест выдает ошибку, но вы уверены в безопасности запроса (например, он исполняется в процедуре с установленным привилегированным режимом), используйте специальные комментарии-теги (например, // @ignore:AccessCheck) для игнорирования таких участков кода. Это позволит избежать ложных срабатываний и поддерживать тест в чистоте.

В заключение, использование специализированных объектов платформы — это профессиональный подход. Не пытайтесь изобрести собственный парсер языка запросов на регулярных выражениях, так как СхемаЗапроса дает гораздо более надежный и предсказуемый результат при минимальных затратах времени на разработку.

← На главную