Имя: Пароль:
1C
1С v8
RegExp: 'ВЫБРАТЬ' без 'РАЗРЕШЕННЫЕ', но не .ВЫБРАТЬ
0 Zhuravlik
 
17.04.21
20:42
Добрый день. Пишу тест для проверки подсистемы "управление доступом", суть такая: все запросы системы либо должны иметь конструкцию "РАЗРЕШЕННЫЕ", либо исполняться привилегированно.
Понятно, что на 100% покрытия не обеспечить, но многие проблемы можно предусмотреть.
Контекст теста - тексты выгрузки в формате EDT. Попал в капкан поговорки "Если вы решаете проблему с помощью регулярных выражений, то у вас уже две проблемы".
Первый этап теста - выбрать все вхождения в модулях конструкции "ВЫБРАТЬ", но не "ВЫБРАТЬ РАЗРЕШЕННЫЕ".
Бьюсь весь день, пришел к вот такому паттерну:
^(?!\/\/)(.*)ВЫБРАТЬ\s*(?!\s*РАЗРЕШЕННЫЕ)

Примеры см. https://regex101.com/r/paqT99/1
Но он не учитывает что перед "Выбрать" может быть точка. Т.е. в результаты попадают "РезультатЗапроса.Выбрать" и т.п.
Я понимаю что виной тому (.*) - любой символ от начала строки до выбрать.
Подскажите пожалуйста, как ему объяснить, что в начале строки Выбрать не должно быть точки?
1 Кирпич
 
17.04.21
20:47
Чо тут биться. В википедии всё написано
Ну вот так например
[^.]ВЫБРАТЬ
2 Вафель
 
17.04.21
20:48
Если у тебя есть тексты запросов то их можно прогнать через объектную модель
3 Zhuravlik
 
17.04.21
20:49
(1) Спасибо! Блин, я тут с лук-бехайндами воюю и прочей нечистью, а ответ очевиден.. Загнался. Опыта в регулярках маловато.
4 Zhuravlik
 
17.04.21
20:56
(2) Думаю о объектной модели чтобы разбирать пакеты, но опыт подсказывает что слишком долго будет. Парсинг частично через регулярки, частично ручной. Конкретно этот - для отбора первичных данных, которые далее уже будут разбираться более придирчиво. Схему запроса попробую, но кажется быстрее вручную распарсить блок "ИЗ", чтобы выбрать таблицы к которым идет обращение и проверить что они участвуют в подсистеме. Либо "Продолжить", если в блоке ИЗ нет ни физ. таблиц ни ВТ.
5 Ненавижу 1С
 
гуру
17.04.21
21:46
(4) как ты там будешь парсить вложенные строковые константы типа? про комментарии не забыли?

ВЫБРАТЬ // ВЫБРАТЬ РАЗРЕШЕННЫЕ
РАЗРЕШЕННЫЕ
    "ВЫБРАТЬ РАЗРЕШЕННЫЕ" КАК ВЫБРАТЬ // ВЫБРАТЬ РАЗРЕШЕННЫЕ

мне кажется лучше все таки объектная модель
6 ДедМорроз
 
17.04.21
22:45
Вы ещё вспомните,что текст запроса может собираться из строк.
А так,нужно понимать,что слово Выбрать идёт в кавычках вначале запроса или после точки с запятой.
М только после него нужно искать слово Разрешенные.
7 Ненавижу 1С
 
гуру
17.04.21
23:03
(6) то что собирать не так важно - обрабатываем в самом конце перед выполнением
а вот найти правильно слово не просто , ведь "или после точки с запятой" оно может идти в комментарии к запросу или в строковой константе
и тому подобные варианты
в общем я за схему запроса
8 Конструктор1С
 
18.04.21
05:34
(0) используй СхемаЗапроса и будет тебе щасте. Там есть булево свойство, отвечающее за "РАЗРЕШЕННЫЕ"
9 Конструктор1С
 
18.04.21
05:35
(4) ты заблуждаешься. Через объектную модель гораздо проще и элегантнее разбирать запрос, чем через строковые функции
10 Конструктор1С
 
18.04.21
05:36
(6) первый же комментарий в запросе, перед выбрать, сломает эту стратегию
11 TormozIT
 
гуру
18.04.21
17:17
Схема запроса будет конечно медленнее в разы, т.к. она очень много всего анализирует.
Если не требуется максимального нахождения целей, то регулярные выражения часто более выгодны, т.к. писать кода в разы меньше и работать будет обычно быстрее.
Я написал кучу парсеров через регулярные выражения используя свой конструктор регулярных выражений
http://devtool1c.ucoz.ru/index/konstruktor_reguljarnogo_vyrazhenija/0-60
Правда я его использовал в паре с платной утилитой RegexBuddy - лучший отладчик регулярок. Купил ее.

(10) Да. Поэтому надо залить комментарии и строковые литералы. В ИР есть универсальная функция для этого
Обработка.ирКлсПолеТекстаПрограммы.ЗалитьКомментарииИСтроковыеЛитералы()
12 TormozIT
 
гуру
18.04.21
17:21
В грамматике языка запросов порядок слов ряда после ВЫБРАТЬ является нестрогим.

ВЫБРАТЬ
- ПЕРВЫЕ Х
- РАЗРЕШЕННЫЕ
- РАЗЛИЧНЫЕ

Все эти слова могут относительно друг друга следовать в произвольном порядке и все являются необязательными.
13 TormozIT
 
гуру
18.04.21
17:22
(12) "слов ряда" -> "ряда слов"
14 Кирпич
 
18.04.21
21:39
посчитал ради интересу в бухии запросы

12212 без РАЗРЕШЕННЫЕ
1397 с РАЗРЕШЕННЫЕ
15 Zhuravlik
 
21.04.21
15:13
Добрый день, спасибо всем за комментарии.
(5) считаем что в обычных "черных" запросах комменатариев нет. Если на такое попаду, буду думать, однако навряд ли. В схемах есть, но с ними отдельно надо разбираться.
(9) я понимаю прекрасно, что с ней проще. Однако до того момента надо еще выцепить сам текст запроса)) А пока я это сделаю, там уже будет неплохой его анализ, и думается после того как текст запроса на руках можно:
-- найти блок секции из как тело между |ИЗ и "|;" для элемента пакетного запроса, либо |ИЗ и "";" для простого запроса (пока о запросах СКД речь не идет, там будет немного по другому)
-- через регулярку найти имена таблиц, по паттерну типа такого [A-Яа-я]+\.[A-Яа-я]+, и если таковые будут - убедиться что они входят в управление доступом
Схема запроса довольно тормозной инструмент, и я не хотел бы тест, работающий дольше 2-3 минут.. Так что ее только в безвыходной ситуации буду юзать.
(11) Спасибо! Я копался в ИР, там больно все сложно, перестал на время рвать себе мозг. Этот метод заценю.
(12) Это держу в голове, в процессе подумаю как решить. На уровне когда получаю тексты запросов из модуля уже не пользуюсь регулярками, как-нибудь решу..

Хотел создать новую тему, но раз есть внимание к этой задаче, задам здесь вопрос, по регуляркам. Я не могу использовать RegEx В теле модуля, т.к. метод Execute не возвращает номер строки, в которой он нашел соответствие, а лишь позицию.
Просчитывать все символы от начала модуля до этой позиции чтобы узнать номер строки - больно тормозной алгоритм... Может есть все-таки возможность именно номер строки из RegEx получать?
16 acht
 
21.04.21
15:21
(15) >  больно тормозной алгоритм
СтрЧислоСтрок(Лев(Текст, Позиция))
17 Zhuravlik
 
21.04.21
15:25
(16) Точно.. Спасибо! Почему-то очевидные решения на ум не приходят)
18 Кирпич
 
21.04.21
15:31
(15) Чота ты перемудрил наверное. Я просто выгрузил конфу в файлы. Прошелся по всем модулям и регуляркой отобрал строковые константы. Потом прошел по всем этим константам и поискал в них слово ВЫБРАТЬ. Вот тебе и все запросы.
Если надо запросы анализировать, то там одними регулярками не обойдешься. Нужен полноценный парсер языка запросов. А об это уже можно мозг сломать.
19 Zhuravlik
 
21.04.21
15:39
(18) Нет, тут все проще. Есть препоны типа тех, что текст запроса может быть получен функцией. Но более сложные ситуации анализироваться не будут.
Как-то ж надо сопровождать это хозяйство.. Если бы речь шла о разовых правках, я бы скорее всего так и сделал. Мне и выгружать ничего не надо - все в EDT. Но здесь именно тест нужен. Хотя бы с покрытием простых случаев типа
Запрос = Новый Запрос("....");
Или
Запрос = Новый Запрос
Запрос.Текст = "...";
Или
Запрос.Текст = ТекстЗапроса_ТакойТо();

Все, что кроме будет пропускаться. Или тег пропуска придумаю для таких случаев.
20 Кирпич
 
21.04.21
16:17
(19) Непонятно чем отличается разовая правка от тест нужен. Всё равно нужно искать в модулях запросы. Все равно нужно искать строковые константы со словом ВЫБРАТЬ или строковые константы после Запрос.Текст =
так например 'Запрос.Текст\s*=\s*"(?:""|[^"])*"'
Я про то, что не надо париться и изобретать трёхэтажные регулярки. Хватит одной простой. А потом уже анализировать то, что нашла эта простая регулярка.
21 Жан Пердежон
 
21.04.21
16:34
(0) это уже не тест, а стат.анализ и надо смотреть в сторону АПК, SONARQUBE 1C и т.д.
Да и самим сабжем не всё так однозначно
https://its.1c.ru/db/v8std#content:415:hdoc
22 Zhuravlik
 
21.04.21
16:39
(21) Это понятно. После анализа текста запроса - если в нем нет РАЗРЕШЕННЫЕ, иду выше от него к объявлению, и проверяю установлен ли привилегированный режим.
Сонар - это клево, но я яву не знаю... В рабочее время ее изучать ради одного теста мне никто не даст. А в нерабочее другие заботы есть. Хорошо, что хотя бы такой тест согласовали. Иначе вообще непонятно как с этим жить: прог забыл про привилегированность или разрешенные - у пользователя сразу ошибка исполнения операции над БД.
23 Zhuravlik
 
21.04.21
16:42
(20) Я понимаю такой подход, так и стараюсь делать. Сейчас самая сложная из (0) (не такая уж и сложная..), и это для стартового отбора модулей. Хочется чтобы побыстрее тест проходил, поэтому выбираю сразу ВЫБРАТЬ без разрешенные, и от этого далее иду.
24 Zhuravlik
 
21.04.21
16:50
(21) Кстати, по АПК я не подумал.. Сейчас смотрю - действительно есть какие-то проверки прав доступа, но кажется это только проверка стандартов. Проверю конфу. Спасибо за наводку, может и не понадобится свой тест.
25 Жан Пердежон
 
21.04.21
17:26
(22) зачем джава, там уже туева хуча правил для 1С написано.
От пули денег оно правда денег стоит, но есть и свободный аналог: https://github.com/1c-syntax/sonar-bsl-plugin-community
И, кстати, если уж про тесты говорить - это было бы правильно еще и сценарным тестом покрыть - ванесса в помощь https://github.com/Pr-Mex/vanessa-automation/releases/tag/1.2.036
26 Zhuravlik
 
21.04.21
17:43
(25)  Эту туеву хучу еще разобрать надо. Покупать навряд ли кто-то что-то будет. И навряд ли там есть настраиваемый анализ внедрения подсистемы управления доступом. BSL-коннектор для EDT все никак не допилят, куда там еще что-то..
А если свое пилить - я насколько знаю, там именно через яву все делается - смотрел вебинар Грызлова, ради интереса. Сам к такому пока не готов)
За ванессу знаю, сталкивался. Однако она в текущий момент на проекте не применяется.
В АПК проверки чего-то подобного не увидел. Есть проверки запросов \ ролей на соответствие ИТС - это хорошо, но не то.
Свойский тест на xUnit в текущий момент самое простое и удобное решение.
27 Конструктор1С
 
21.04.21
19:22
(12) схема запроса позволит не париться по этому поводу. И по многим другим
28 Zhuravlik
 
01.05.21
10:14
Всем привет! Хочу подытожить.
- В итоге все-таки пришлось заюзать схему запроса, погорел на объединениях и вложенных запросах :)
-- Оказалось, схема не такой уж и тормознутый объект. Общее время алгоритма ненамного увеличилось - примерно на 15 сек, что вообще копейки.
- Кроме того, с удивлением узнал про то, что более опытные коллеги назовут "баяном" - объект VBScript.RegExp не умеет обратный поиск, и от способа поиска запросов описанном в сабже также пришлось отказаться, т.к. результат не удалось сделать контроллируемым.
Несмотря на эти трудности, у меня все получилось) Уже выявил и поправил ~400 запросов в системе. Всем спасибо за поддержку!
29 breezee
 
01.05.21
15:56
А едт такое может? Можно все текста выгрузить и поменять за раз?
30 ДедМорроз
 
01.05.21
19:57
Если взять типовую бухгалтерию,то там тексты запросов - это шаблон,и в нем потом делается замена.
Хотя,1с сохраняет "исполняемость" запроса,то есть не использует в шаблоне неправильные конструкции,но ведь не факт,что потом не будет что-то типа
ВЫБРАТЬ #ПараметрыВыбора