1
0
mirror of https://github.com/1C-Company/v8-code-style.git synced 2025-07-17 05:02:20 +02:00

#639 Отсутствует включение безопасного режима перед вызовом метода Выполнить или Вычислить (#1026)

This commit is contained in:
mgalios
2022-07-29 19:54:53 +07:00
committed by GitHub
parent a92bd6e00e
commit 1642ee75be
30 changed files with 1003 additions and 2 deletions

View File

@ -29,7 +29,6 @@
#### Код модулей
- 3 проверки на избыточное обращение внутри модуля через его имя или псевдоним ЭтотОбъект (к методу, свойству или реквизиту)
- Проверка использования устаревшего "ЭтаФорма" в модуле формы
- Проверка нарушения схемы работы с транзакциями связанной с фиксацией транзакции:
@ -46,6 +45,8 @@
1. Mежду "НачатьТранзакцию()" и "Попытка" есть исполняемый код, который может вызвать исключение
2. Не найден оператор "Попытка" после вызова "НачатьТранзакцию()"
- Отсутствует удаление временного файла после использования.
- Отсутствует включение безопасного режима перед вызовом метода "Выполнить" или "Вычислить"
#### Запросы
- В качестве правого операнда операции сравнения "ПОДОБНО" указано поле таблицы
@ -56,7 +57,6 @@
### Новые быстрые исправления (Quick-fix)
- 3 исправления исправления для удаления избыточного обращения внутри модуля к самому себе
- Замена в модуле формы устаревшего свойства "ЭтаФорма" на "ЭтотОбъект"
- Конвертация функции в процедуру

View File

@ -364,6 +364,9 @@
<fix
class="com.e1c.v8codestyle.internal.bsl.ui.ExecutableExtensionFactory:com.e1c.v8codestyle.bsl.ui.qfix.ConvertFunctionToProcedureFix">
</fix>
<fix
class="com.e1c.v8codestyle.internal.bsl.ui.ExecutableExtensionFactory:com.e1c.v8codestyle.bsl.ui.qfix.ServerExecutionSafeModeFix">
</fix>
</extension>
</plugin>

View File

@ -48,6 +48,10 @@ final class Messages
public static String SelfReferenceFix_details;
public static String ServerExecutionSafeModeFix_description;
public static String ServerExecutionSafeModeFix_details;
public static String UndefinedMethodFix_func_title;
public static String UndefinedMethodFix_func_desc;
public static String UndefinedMethodFix_proc_title;

View File

@ -0,0 +1,76 @@
/*******************************************************************************
* Copyright (C) 2022, 1C-Soft LLC and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* 1C-Soft LLC - initial API and implementation
*******************************************************************************/
package com.e1c.v8codestyle.bsl.ui.qfix;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.text.edits.InsertEdit;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.xtext.EcoreUtil2;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
import org.eclipse.xtext.resource.XtextResource;
import com._1c.g5.v8.dt.bsl.model.ExecuteStatement;
import com._1c.g5.v8.dt.bsl.model.Statement;
import com._1c.g5.v8.dt.bsl.model.StaticFeatureAccess;
import com._1c.g5.v8.dt.common.StringUtils;
import com._1c.g5.v8.dt.metadata.mdclass.ScriptVariant;
import com.e1c.g5.v8.dt.bsl.check.qfix.IXtextBslModuleFixModel;
import com.e1c.g5.v8.dt.bsl.check.qfix.IXtextInteractiveBslModuleFixModel;
import com.e1c.g5.v8.dt.bsl.check.qfix.SingleVariantXtextBslModuleFix;
import com.e1c.g5.v8.dt.check.qfix.components.QuickFix;
/**
* Quick fix for check com.e1c.v8codestyle.bsl.check:server-execution-safe-mode
*
* @author Maxim Galios
*
*/
@QuickFix(checkId = "server-execution-safe-mode", supplierId = "com.e1c.v8codestyle.bsl")
public class ServerExecutionSafeModeFix
extends SingleVariantXtextBslModuleFix
{
private static final String SAFE_MODE_INVOCATION = "SetSafeMode(True);"; //$NON-NLS-1$
private static final String SAFE_MODE_INVOCATION_RU = "УстановитьБезопасныйРежим(Истина);"; //$NON-NLS-1$
@Override
protected void configureFix(FixConfigurer configurer)
{
configurer.interactive(true)
.description(Messages.ServerExecutionSafeModeFix_description)
.details(Messages.ServerExecutionSafeModeFix_details);
}
@Override
protected TextEdit fixIssue(XtextResource state, IXtextBslModuleFixModel model) throws BadLocationException
{
EObject element = model.getElement();
if (!(element instanceof StaticFeatureAccess) && !(element instanceof ExecuteStatement))
{
return null;
}
String safeModeStatement =
model.getScriptVariant() == ScriptVariant.RUSSIAN ? SAFE_MODE_INVOCATION_RU : SAFE_MODE_INVOCATION;
INode node = NodeModelUtils.findActualNodeFor(
element instanceof StaticFeatureAccess ? EcoreUtil2.getContainerOfType(element, Statement.class) : element);
IXtextInteractiveBslModuleFixModel interactiveModel = (IXtextInteractiveBslModuleFixModel)model;
String indent = interactiveModel.getFormatString(element).orElse(StringUtils.EMPTY);
String codeToInsert = safeModeStatement + model.getLineSeparator() + indent;
return new InsertEdit(node.getOffset(), codeToInsert);
}
}

View File

@ -25,6 +25,8 @@ OpenBslDocCommentViewFix_Details=Open documentation comment data structure view
OpenBslDocCommentViewFix_Description=Open documentation comment structure view
SelfReferenceFix_description=Remove excessive self reference
SelfReferenceFix_details=Remove excessive self reference
ServerExecutionSafeModeFix_description = Enable safe mode
ServerExecutionSafeModeFix_details = Insert safe mode enable statement before "Execute" or "Eval" method call
UndefinedMethodFix_func_title=Create function
UndefinedMethodFix_func_desc=Create a new function in the module
UndefinedMethodFix_proc_title=Create procedure

View File

@ -33,6 +33,10 @@ SelfReferenceFix_description=Удалить избыточное обращен
SelfReferenceFix_details=Удалить избыточное обращение внутри модуля через псевдоним "ЭтотОбъект"
ServerExecutionSafeModeFix_description = Включить безопасный режим
ServerExecutionSafeModeFix_details = Добавить включение безопасного режима перед вызовом метода "Выполнить" или "Вычислить"
UndefinedMethodFix_func_desc = Создать новую функцию в модуле
UndefinedMethodFix_func_title = Создать функцию

View File

@ -0,0 +1,92 @@
# Отсутствует включение безопасного режима перед вызовом метода "Выполнить" или "Вычислить"
Для исключения описанных уязвимостей, нужно в серверных процедурах и
функциях вызов методов Выполнить или Вычислить предварять включением безопасного режима.
В режиме сервиса, включение безопасного режима должно учитывать разделение данных.
## Неправильно
```bsl
Выполнить(Алгоритм);
```
```bsl
Вычислить(Алгоритм);
```
## Правильно
```bsl
УстановитьБезопасныйРежим(Истина);
Выполнить(Алгоритм);
```
```bsl
УстановитьБезопасныйРежим(Истина);
Вычислить(Алгоритм);
```
В режиме сервиса:
```bsl
УстановитьБезопасныйРежим(Истина);
Для каждого ИмяРазделителя Из РазделителиКонфигурации() Цикл
УстановитьБезопасныйРежимРазделенияДанных(ИмяРазделителя, Истина);
КонецЦикла;
Выполнить(Алгоритм);
```
```bsl
УстановитьБезопасныйРежим(Истина);
Для каждого ИмяРазделителя Из РазделителиКонфигурации() Цикл
УстановитьБезопасныйРежимРазделенияДанных(ИмяРазделителя, Истина);
КонецЦикла;
Вычислить(Алгоритм);
```
При использовании в конфигурации Библиотеки стандартных подсистем, следует использовать:
```bsl
ОбщегоНазначения.ВыполнитьВБезопасномРежиме()
```
```bsl
ОбщегоНазначения.ВычислитьВБезопасномРежиме()
```
Вместо формирования строки вызова метода модуля и передачи ее в Выполнить:
```bsl
ОбщегоНазначения.ВыполнитьМетодКонфигурации()
```
```bsl
ОбщегоНазначения.ВыполнитьМетодОбъекта()
```
При использовании в конфигурации Библиотеки стандартных подсистем версии, меньшей чем 2.4.1, следует использовать:
```bsl
РаботаВБезопасномРежиме.ВыполнитьВБезопасномРежиме()
```
```bsl
РаботаВБезопасномРежиме.ВычислитьВБезопасномРежиме()
```
Вместо формирования строки вызова метода модуля и передачи ее в Выполнить:
```bsl
РаботаВБезопасномРежиме.ВыполнитьМетодКонфигурации()
```
```bsl
РаботаВБезопасномРежиме.ВыполнитьМетодОбъекта()
```
## См.
[Ограничения на использование Выполнить и Вычислить на сервере](https://its.1c.ru/db/v8std#content:770:hdoc:2)

View File

@ -0,0 +1,93 @@
# Safe mode is not enabled before "Execute" or "Eval" call
To avoid vulnerabilities, in server procedures and functions,
enable safe mode before calling the Execute or Eval methods.
In service mode, data separation is to be considered upon
enabling safe mode.
## Noncompliant Code Example
```bsl
Execute(Algorithm);
```
```bsl
Eval(Algorithm);
```
## Compliant Solution
```bsl
SetSafeMode(True);
Execute(Algorithm);
```
```bsl
SetSafeMode(True);
Eval(Algorithm);
```
In service mode:
```bsl
SetSafeMode(True);
For each SeparatorName in ConfigurationSeparators() Do
SetDataSeparationSafeMode(SeparatorName, True);
EndDo;
Execute Algorithm;
```
```bsl
SetSafeMode(True);
For each SeparatorName in ConfigurationSeparators() Do
SetDataSeparationSafeMode(SeparatorName, True);
EndDo;
Eval(Algorithm);
```
If the Standard Subsystems Library is used in the configuration, use the following:
```bsl
Common.ExecuteInSafeMode()
```
```bsl
Common.CalculateInSafeMode()
```
Instead of generating a string calling the module method and passing it to Execute:
```bsl
Common.ExecuteConfigurationMethod()
```
```bsl
Common.ExecuteObjectMethod()
```
If the Standard Subsystems Library version is earlier than 2.4.1, use the following:
```bsl
SafeModeManager.ExecuteInSafeMode()
```
```bsl
SafeModeManager.CalculateInSafeMode()
```
Instead of generating a string calling the module method and passing it to Execute:
```bsl
SafeModeManager.ExecuteConfigurationMethod()
```
```bsl
SafeModeManager.ExecuteObjectMethod()
```
## See
[Restrictions on the use of Run and Eval on the server](https://support.1ci.com/hc/en-us/articles/360011122479-Restrictions-on-the-use-of-Run-and-Eval-on-the-server)

View File

@ -258,6 +258,10 @@
<check
category="com.e1c.v8codestyle.bsl"
class="com.e1c.v8codestyle.internal.bsl.ExecutableExtensionFactory:com.e1c.v8codestyle.bsl.check.ManagerModuleNamedSelfReferenceCheck">
</check>
<check
category="com.e1c.v8codestyle.bsl"
class="com.e1c.v8codestyle.bsl.check.ServerExecutionSafeModeCheck">
</check>
<check
category="com.e1c.v8codestyle.bsl"

View File

@ -160,6 +160,14 @@ final class Messages
public static String SelfReferenceCheck_Issue;
public static String ServerExecutionSafeModeCheck_description;
public static String ServerExecutionSafeModeCheck_eval_issue;
public static String ServerExecutionSafeModeCheck_execute_issue;
public static String ServerExecutionSafeModeCheck_title;
public static String StructureCtorTooManyKeysCheck_description;
public static String StructureCtorTooManyKeysCheck_Maximum_structure_constructor_keys;
public static String StructureCtorTooManyKeysCheck_Structure_constructor_has_more_than__0__keys;

View File

@ -0,0 +1,381 @@
/*******************************************************************************
* Copyright (C) 2022, 1C-Soft LLC and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* 1C-Soft LLC - initial API and implementation
*******************************************************************************/
package com.e1c.v8codestyle.bsl.check;
import static com._1c.g5.v8.dt.bsl.model.BslPackage.Literals.EXECUTE_STATEMENT;
import static com._1c.g5.v8.dt.bsl.model.BslPackage.Literals.INVOCATION;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.EcoreUtil2;
import com._1c.g5.v8.dt.bsl.model.Block;
import com._1c.g5.v8.dt.bsl.model.BooleanLiteral;
import com._1c.g5.v8.dt.bsl.model.Conditional;
import com._1c.g5.v8.dt.bsl.model.ExecuteStatement;
import com._1c.g5.v8.dt.bsl.model.Expression;
import com._1c.g5.v8.dt.bsl.model.IfStatement;
import com._1c.g5.v8.dt.bsl.model.Invocation;
import com._1c.g5.v8.dt.bsl.model.LoopStatement;
import com._1c.g5.v8.dt.bsl.model.SimpleStatement;
import com._1c.g5.v8.dt.bsl.model.Statement;
import com._1c.g5.v8.dt.bsl.model.TryExceptStatement;
import com._1c.g5.v8.dt.mcore.Environmental;
import com._1c.g5.v8.dt.mcore.util.Environment;
import com._1c.g5.v8.dt.mcore.util.Environments;
import com.e1c.g5.v8.dt.check.CheckComplexity;
import com.e1c.g5.v8.dt.check.ICheckParameters;
import com.e1c.g5.v8.dt.check.components.BasicCheck;
import com.e1c.g5.v8.dt.check.settings.IssueSeverity;
import com.e1c.g5.v8.dt.check.settings.IssueType;
import com.e1c.v8codestyle.check.StandardCheckExtension;
import com.e1c.v8codestyle.internal.bsl.BslPlugin;
/**
* Check if safe mode is enabled before Execute or Eval
*
* @author Maxim Galios
*
*/
public class ServerExecutionSafeModeCheck
extends BasicCheck
{
private static final String CHECK_ID = "server-execution-safe-mode"; //$NON-NLS-1$
private static final Collection<String> EVAL = Set.of("Eval", "Вычислить"); //$NON-NLS-1$ //$NON-NLS-2$
private static final Collection<String> SAFE_MODE_INVOCATIONS = Set.of("УстановитьБезопасныйРежим", "SetSafeMode"); //$NON-NLS-1$ //$NON-NLS-2$
@Override
public String getCheckId()
{
return CHECK_ID;
}
@Override
protected void configureCheck(CheckConfigurer builder)
{
builder.title(Messages.ServerExecutionSafeModeCheck_title)
.description(Messages.ServerExecutionSafeModeCheck_description)
.complexity(CheckComplexity.NORMAL)
.severity(IssueSeverity.MAJOR)
.issueType(IssueType.SECURITY)
.extension(new StandardCheckExtension(getCheckId(), BslPlugin.PLUGIN_ID))
.module()
.checkedObjectType(INVOCATION)
.checkedObjectType(EXECUTE_STATEMENT);
}
@Override
protected void check(Object object, ResultAcceptor resultAceptor, ICheckParameters parameters,
IProgressMonitor monitor)
{
EObject eObject = (EObject)object;
if (!isServerCall(eObject) || (!isExecute(eObject) && !isEval(eObject)))
{
return;
}
if (!isSafeModeEnabledBeforeExecution(eObject, monitor))
{
if (isExecute(eObject))
{
resultAceptor.addIssue(Messages.ServerExecutionSafeModeCheck_execute_issue, eObject);
}
else if (isEval(eObject))
{
resultAceptor.addIssue(Messages.ServerExecutionSafeModeCheck_eval_issue,
((Invocation)eObject).getMethodAccess());
}
}
}
private boolean isServerCall(EObject eObject)
{
Environmental environmental = EcoreUtil2.getContainerOfType(eObject, Environmental.class);
Environments environments = environmental.environments();
return environments.contains(Environment.SERVER);
}
private boolean isSafeModeEnabledBeforeExecution(EObject eObject, IProgressMonitor monitor)
{
EObject container = eObject.eContainer();
while (container != null)
{
if (monitor.isCanceled())
{
return true;
}
Optional<Boolean> isSafeModeEnabledForContainer = isSafeModeEnabledForContainer(container, eObject);
if (isSafeModeEnabledForContainer.isPresent())
{
return isSafeModeEnabledForContainer.get();
}
container = container.eContainer();
}
return false;
}
private Optional<Boolean> isSafeModeEnabledForContainer(EObject container, EObject eObject)
{
if (container instanceof IfStatement)
{
return isSafeModeEnabledForIfStatement((IfStatement)container, eObject);
}
else if (container instanceof LoopStatement)
{
return isSafeModeEnabledForLoopStatement((LoopStatement)container, eObject);
}
else if (container instanceof TryExceptStatement)
{
return isSafeModeEnabledForTryExceptStatement((TryExceptStatement)container, eObject);
}
else if (container instanceof Block)
{
return isSafeModeEnabledForBlock((Block)container, eObject);
}
return Optional.empty();
}
private Optional<Boolean> isSafeModeEnabledForIfStatement(IfStatement ifStatement, EObject eObject)
{
List<Statement> ifStatements = ifStatement.getIfPart().getStatements();
Optional<Boolean> ifStatementSafeModeEnabled = isSafeModeEnabledInStatementList(ifStatements, eObject);
if (ifStatementSafeModeEnabled.isPresent())
{
return ifStatementSafeModeEnabled;
}
List<Conditional> elseIfParts = ifStatement.getElsIfParts();
for (Conditional part : elseIfParts)
{
List<Statement> elseIfStatements = part.getStatements();
Optional<Boolean> elseIfStatementSafeModeEnabled =
isSafeModeEnabledInStatementList(elseIfStatements, eObject);
if (elseIfStatementSafeModeEnabled.isPresent())
{
return elseIfStatementSafeModeEnabled;
}
}
List<Statement> elseStatements = ifStatement.getElseStatements();
return isSafeModeEnabledInStatementList(elseStatements, eObject);
}
private Optional<Boolean> isSafeModeEnabledForLoopStatement(LoopStatement loopStatement, EObject eObject)
{
List<Statement> loopStatements = loopStatement.getStatements();
return isSafeModeEnabledInStatementList(loopStatements, eObject);
}
private Optional<Boolean> isSafeModeEnabledForTryExceptStatement(TryExceptStatement tryExceptStatement,
EObject eObject)
{
List<Statement> tryStatements = tryExceptStatement.getTryStatements();
Optional<Boolean> tryStatementSafeModeEnabled = isSafeModeEnabledInStatementList(tryStatements, eObject);
if (tryStatementSafeModeEnabled.isPresent())
{
return tryStatementSafeModeEnabled;
}
List<Statement> exceptStatements = tryExceptStatement.getExceptStatements();
return isSafeModeEnabledInStatementList(exceptStatements, eObject);
}
private Optional<Boolean> isSafeModeEnabledForBlock(Block block, EObject eObject)
{
List<Statement> statements = block.allStatements();
return isSafeModeEnabledInStatementList(statements, eObject);
}
private Optional<Boolean> isSafeModeEnabledInStatementList(List<Statement> statements, EObject eObject)
{
int executeIndex = findExecuteStatementIndex(statements, eObject);
if (executeIndex == -1)
{
return Optional.empty();
}
for (int i = executeIndex - 1; i >= 0; i--)
{
Statement statement = statements.get(i);
Optional<Boolean> safeModeEnabled = isSafeModeEnabled(statement);
if (safeModeEnabled.isPresent())
{
return safeModeEnabled;
}
}
return Optional.empty();
}
private Optional<Boolean> isSafeModeEnabled(Statement statement)
{
if (statement instanceof SimpleStatement && isSafeModeMethod(statement))
{
return Optional.of(isSafeModeEnabledStatement(statement));
}
else if (statement instanceof IfStatement)
{
List<Optional<Boolean>> safeModeStatementResults = new ArrayList<>();
IfStatement ifStatement = (IfStatement)statement;
List<Statement> ifStatements = ifStatement.getIfPart().getStatements();
safeModeStatementResults.add(safeModeStatementResult(ifStatements));
List<Conditional> elseIfParts = ifStatement.getElsIfParts();
for (Conditional part : elseIfParts)
{
List<Statement> elseIfStatements = part.getStatements();
safeModeStatementResults.add(safeModeStatementResult(elseIfStatements));
}
List<Statement> elseStatements = ifStatement.getElseStatements();
safeModeStatementResults.add(safeModeStatementResult(elseStatements));
return validateSafeModeStatements(safeModeStatementResults);
}
else if (statement instanceof LoopStatement)
{
LoopStatement loopStatement = (LoopStatement)statement;
List<Statement> loopStatements = loopStatement.getStatements();
return safeModeStatementResult(loopStatements);
}
else if (statement instanceof TryExceptStatement)
{
List<Optional<Boolean>> safeModeStatementResults = new ArrayList<>();
TryExceptStatement tryExceptStatement = (TryExceptStatement)statement;
List<Statement> tryStatements = tryExceptStatement.getTryStatements();
safeModeStatementResults.add(safeModeStatementResult(tryStatements));
List<Statement> exceptStatements = tryExceptStatement.getExceptStatements();
safeModeStatementResults.add(safeModeStatementResult(exceptStatements));
return validateSafeModeStatements(safeModeStatementResults);
}
return Optional.empty();
}
private Optional<Boolean> safeModeStatementResult(List<Statement> statements)
{
for (int i = statements.size() - 1; i >= 0; i--)
{
Statement statement = statements.get(i);
Optional<Boolean> res = isSafeModeEnabled(statement);
if (res.isPresent())
{
return res;
}
}
return Optional.empty();
}
private Optional<Boolean> validateSafeModeStatements(List<Optional<Boolean>> safeModeStatements)
{
if (safeModeStatements.stream().allMatch(Optional::isEmpty))
{
return Optional.empty();
}
if (safeModeStatements.stream().filter(Optional::isPresent).anyMatch(s -> !s.get()))
{
return Optional.of(false);
}
if (safeModeStatements.stream().allMatch(s -> s.isPresent() && s.get()))
{
return Optional.of(true);
}
return Optional.empty();
}
private boolean isSafeModeMethod(Statement statement)
{
if (!(statement instanceof SimpleStatement))
{
return false;
}
SimpleStatement simpleStatement = (SimpleStatement)statement;
Expression leftExpression = simpleStatement.getLeft();
if (!(leftExpression instanceof Invocation))
{
return false;
}
Invocation invocation = (Invocation)leftExpression;
String name = invocation.getMethodAccess().getName();
List<Expression> params = invocation.getParams();
return SAFE_MODE_INVOCATIONS.stream().anyMatch(st -> st.equalsIgnoreCase(name)) && params.size() == 1
&& params.get(0) instanceof BooleanLiteral;
}
private int findExecuteStatementIndex(List<Statement> statements, EObject eObject)
{
if (eObject instanceof ExecuteStatement)
{
int index = statements.indexOf(eObject);
if (index != -1)
{
return index;
}
}
Statement statement = EcoreUtil2.getContainerOfType(eObject, Statement.class);
while (statement != null)
{
int statementIndex = statements.indexOf(statement);
if (statementIndex != -1)
{
return statementIndex;
}
statement = EcoreUtil2.getContainerOfType(statement.eContainer(), Statement.class);
}
return -1;
}
private boolean isSafeModeEnabledStatement(Statement statement)
{
if (statement == null)
{
return false;
}
SimpleStatement simpleStatement = (SimpleStatement)statement;
Invocation invocation = (Invocation)simpleStatement.getLeft();
List<Expression> params = invocation.getParams();
return ((BooleanLiteral)params.get(0)).isIsTrue();
}
private boolean isExecute(EObject eObject)
{
return eObject instanceof ExecuteStatement;
}
private boolean isEval(EObject eObject)
{
return eObject instanceof Invocation && EVAL.stream()
.anyMatch(statement -> statement.equalsIgnoreCase(((Invocation)eObject).getMethodAccess().getName()));
}
}

View File

@ -273,6 +273,14 @@ SelfReferenceCheck_Title=Excessive self reference
SelfReferenceCheck_Issue=Excessive usage of self reference (when referencing method, property or attribute)
ServerExecutionSafeModeCheck_description = Safe mode is not enabled when calling "Execute" or "Eval'
ServerExecutionSafeModeCheck_eval_issue = Safe mode is not enabled when calling "Eval"
ServerExecutionSafeModeCheck_execute_issue = Safe mode is not enabled when calling "Execute"
ServerExecutionSafeModeCheck_title = Safe mode is not enabled when calling "Execute" or "Eval"
StructureCtorTooManyKeysCheck_Maximum_structure_constructor_keys = Maximum structure constructor keys
StructureCtorTooManyKeysCheck_Structure_constructor_has_more_than__0__keys = Structure constructor has more than {0} keys

View File

@ -278,6 +278,14 @@ SelfReferenceCheck_Title=Избыточное использование псе
SelfReferenceCheck_Issue=Избыточное обращение внутри модуля через псевдоним "ЭтотОбъект" (к методу, свойству или реквизиту)
ServerExecutionSafeModeCheck_description = Отсутствует включение безопасного режима перед вызовом метода "Выполнить" или "Вычислить"
ServerExecutionSafeModeCheck_eval_issue = Отсутствует включение безопасного режима перед вызовом метода "Вычислить"
ServerExecutionSafeModeCheck_execute_issue = Отсутствует включение безопасного режима перед вызовом метода "Выполнить"
ServerExecutionSafeModeCheck_title = Отсутствует включение безопасного режима перед вызовом метода "Выполнить" или "Вычислить"
StructureCtorTooManyKeysCheck_Maximum_structure_constructor_keys = Максимальное количество ключей структуры в конструкторе
StructureCtorTooManyKeysCheck_Structure_constructor_has_more_than__0__keys = Конструктор структуры содержит более чем {0} ключей

View File

@ -0,0 +1,118 @@
/*******************************************************************************
* Copyright (C) 2022, 1C-Soft LLC and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* 1C-Soft LLC - initial API and implementation
*******************************************************************************/
package com.e1c.v8codestyle.bsl.check.itests;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.util.List;
import java.util.stream.Collectors;
import org.eclipse.core.runtime.Path;
import org.junit.Test;
import com._1c.g5.v8.dt.validation.marker.IExtraInfoKeys;
import com._1c.g5.v8.dt.validation.marker.Marker;
import com.e1c.v8codestyle.bsl.check.ServerExecutionSafeModeCheck;
/**
* The test for class {@link ServerExecutionSafeModeCheck}.
*
* @author Maxim Galios
*
*/
public class ServerExecutionSafeModeCheckTest
extends AbstractSingleModuleTestBase
{
private static final String PROJECT_NAME = "ServerExecutionSafeModeCheck";
private static final String COMMON_MODULE_SERVER_CALL_FILE_NAME =
"/src/CommonModules/CommonModuleServerCall/Module.bsl";
private static final String COMMON_MODULE_FILE_NAME = "/src/CommonModules/CommonModule/Module.bsl";
private static final String FORM_MODULE_FILE_NAME = "/src/CommonForms/Form/Module.bsl";
public ServerExecutionSafeModeCheckTest()
{
super(ServerExecutionSafeModeCheck.class);
}
@Override
protected String getTestConfigurationName()
{
return PROJECT_NAME;
}
/**
* Test that warning is not shown without Server in Environment
*
* @throws Exception
*/
@Test
public void testCommonModule() throws Exception
{
List<Marker> markers = getMarkers(COMMON_MODULE_FILE_NAME);
assertEquals(0, markers.size());
}
/**
* Test safe mode is enabled before Execute/Выполнить and Eval/Вычислить in common module
*
* @throws Exception
*/
@Test
public void testCommonModuleServerCall() throws Exception
{
List<Marker> markers = getMarkers(COMMON_MODULE_SERVER_CALL_FILE_NAME);
assertEquals(6, markers.size());
assertEquals("4", markers.get(0).getExtraInfo().get(IExtraInfoKeys.TEXT_EXTRA_INFO_LINE_KEY));
assertEquals("5", markers.get(1).getExtraInfo().get(IExtraInfoKeys.TEXT_EXTRA_INFO_LINE_KEY));
assertEquals("11", markers.get(2).getExtraInfo().get(IExtraInfoKeys.TEXT_EXTRA_INFO_LINE_KEY));
assertEquals("26", markers.get(3).getExtraInfo().get(IExtraInfoKeys.TEXT_EXTRA_INFO_LINE_KEY));
assertEquals("29", markers.get(4).getExtraInfo().get(IExtraInfoKeys.TEXT_EXTRA_INFO_LINE_KEY));
assertEquals("30", markers.get(5).getExtraInfo().get(IExtraInfoKeys.TEXT_EXTRA_INFO_LINE_KEY));
}
/**
* Test safe mode is enabled before Execute/Выполнить and Eval/Вычислить in form module
*
* @throws Exception
*/
@Test
public void testFormModule() throws Exception
{
List<Marker> markers = getMarkers(FORM_MODULE_FILE_NAME);
assertEquals(4, markers.size());
assertEquals("4", markers.get(0).getExtraInfo().get(IExtraInfoKeys.TEXT_EXTRA_INFO_LINE_KEY));
assertEquals("5", markers.get(1).getExtraInfo().get(IExtraInfoKeys.TEXT_EXTRA_INFO_LINE_KEY));
assertEquals("14", markers.get(2).getExtraInfo().get(IExtraInfoKeys.TEXT_EXTRA_INFO_LINE_KEY));
assertEquals("15", markers.get(3).getExtraInfo().get(IExtraInfoKeys.TEXT_EXTRA_INFO_LINE_KEY));
}
private List<Marker> getMarkers(String moduleFileName)
{
String moduleId = Path.ROOT.append(getTestConfigurationName()).append(moduleFileName).toString();
List<Marker> markers = List.of(markerManager.getMarkers(getProject().getWorkspaceProject(), moduleId));
String checkId = getCheckId();
assertNotNull(checkId);
return markers.stream()
.filter(marker -> checkId.equals(getCheckIdFromMarker(marker, getProject())))
.collect(Collectors.toList());
}
}

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>ServerExecutionSafeModeCheck</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
<nature>com._1c.g5.v8.dt.core.V8ConfigurationNature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,2 @@
eclipse.preferences.version=1
topObjects=true

View File

@ -0,0 +1,3 @@
addModuleStrictTypesAnnotation=false
createModuleStructure=false
eclipse.preferences.version=1

View File

@ -0,0 +1,3 @@
commonChecks=true
eclipse.preferences.version=1
standardChecks=true

View File

@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding/<project>=UTF-8

View File

@ -0,0 +1,2 @@
Manifest-Version: 1.0
Runtime-Version: 8.3.21

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<form:Form xmlns:form="http://g5.1c.ru/v8/dt/form">
<autoCommandBar>
<name>FormCommandBar</name>
<id>-1</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<horizontalAlign>Left</horizontalAlign>
<autoFill>true</autoFill>
</autoCommandBar>
<autoTitle>true</autoTitle>
<autoUrl>true</autoUrl>
<group>Vertical</group>
<autoFillCheck>true</autoFillCheck>
<allowFormCustomize>true</allowFormCustomize>
<enabled>true</enabled>
<showTitle>true</showTitle>
<showCloseButton>true</showCloseButton>
<commandInterface>
<navigationPanel/>
<commandBar/>
</commandInterface>
</form:Form>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:CommonForm xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="cbe93e11-a3dc-4c32-a08b-75316315ad5b">
<name>Form</name>
<synonym>
<key>en</key>
<value>Form</value>
</synonym>
<usePurposes>PersonalComputer</usePurposes>
<usePurposes>MobileDevice</usePurposes>
</mdclass:CommonForm>

View File

@ -0,0 +1,19 @@
&НаСервере
Процедура Тест1()
Код = "Рез = 1 + 1";
Выполнить(Код);
а = Вычислить(Код);
УстановитьБезопасныйРежим(Истина);
Выполнить(Код);
а = Вычислить(Код);
КонецПроцедуры
&AtServer
Функция Тест2()
Код = "Рез = 1 + 1";
Execute(Код);
а = Eval(Код);
SetSafeMode(True);
Execute(Код);
а = Eval(Код);
КонецФункции

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:CommonModule xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="5fdd6bf6-c48b-4c2c-873c-a34ced51c981">
<name>CommonModule</name>
<synonym>
<key>en</key>
<value>Common module</value>
</synonym>
<externalConnection>true</externalConnection>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
</mdclass:CommonModule>

View File

@ -0,0 +1,5 @@
Функция Тест()
Код = "Рез = 1 + 1";
Выполнить(Код);
а = 1 + Вычислить(Код);
КонецФункции

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:CommonModule xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="ecac44c0-fd5a-4e2a-9d8f-1aac10a47bf2">
<name>CommonModuleServerCall</name>
<synonym>
<key>en</key>
<value>Common module</value>
</synonym>
<server>true</server>
<serverCall>true</serverCall>
</mdclass:CommonModule>

View File

@ -0,0 +1,42 @@
Функция Тест()
Код = "Рез = 1 + 1";
УстановитьБезопасныйРежим(Ложь);
Выполнить(Код);
a = Вычислить(Код);
Попытка
SetSafeMode(True);
Выполнить(Код);
Исключение
а = 1 + Вычислить(Код);
SetSafeMode(True);
КонецПопытки;
Выполнить(Код);
а = а + Вычислить(Код);
Если 1 > 0 Тогда
Для Счетчик = 1 По 5 Цикл
а = 1 + Вычислить(Код);
КонецЦикла;
ИначеЕсли 1 = 0 Тогда
Выполнить(Код);
Иначе
SetSafeMode(False);
а = 1 + Вычислить(Код);
КонецЕсли;
Выполнить(Код);
а = а + Вычислить(Код);
Если 1 > 0 Тогда
Для Счетчик = 1 По 5 Цикл
УстановитьБезопасныйРежим(Истина);
КонецЦикла;
Иначе
УстановитьБезопасныйРежим(Истина);
КонецЕсли;
Execute(Код);
а = 1 + Eval(Код);
КонецФункции

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<cmi:CommandInterface xmlns:cmi="http://g5.1c.ru/v8/dt/cmi"/>

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:Configuration xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="b9f455ca-d9f3-4535-9ad0-faa995552d29">
<name>ServerExecutionSafeModeCheck</name>
<synonym>
<key>en</key>
<value>Server execution safe mode check</value>
</synonym>
<containedObjects classId="9cd510cd-abfc-11d4-9434-004095e12fc7" objectId="08bbb3ce-d4b2-44e9-b22f-e2c40c2e07aa"/>
<containedObjects classId="9fcd25a0-4822-11d4-9414-008048da11f9" objectId="48302ff5-8260-4a7d-a602-a8c21b2549cf"/>
<containedObjects classId="e3687481-0a87-462c-a166-9f34594f9bba" objectId="cb547ae1-e7bb-4346-9643-c4cf31627927"/>
<containedObjects classId="9de14907-ec23-4a07-96f0-85521cb6b53b" objectId="b13f6220-9268-4e2c-b2e4-3d85833475d1"/>
<containedObjects classId="51f2d5d8-ea4d-4064-8892-82951750031e" objectId="d625183c-7a87-4f99-a97e-e7b912012e5f"/>
<containedObjects classId="e68182ea-4237-4383-967f-90c1e3370bc7" objectId="3015f1e2-2b0f-49c6-892a-c4b152a91c80"/>
<containedObjects classId="fb282519-d103-4dd3-bc12-cb271d631dfc" objectId="583f7785-3e76-4ed2-8a37-1f016519817e"/>
<configurationExtensionCompatibilityMode>8.3.21</configurationExtensionCompatibilityMode>
<defaultRunMode>ManagedApplication</defaultRunMode>
<usePurposes>PersonalComputer</usePurposes>
<usedMobileApplicationFunctionalities>
<functionality>
<use>true</use>
</functionality>
<functionality>
<functionality>OSBackup</functionality>
<use>true</use>
</functionality>
</usedMobileApplicationFunctionalities>
<defaultLanguage>Language.English</defaultLanguage>
<dataLockControlMode>Managed</dataLockControlMode>
<objectAutonumerationMode>NotAutoFree</objectAutonumerationMode>
<modalityUseMode>DontUse</modalityUseMode>
<synchronousPlatformExtensionAndAddInCallUseMode>DontUse</synchronousPlatformExtensionAndAddInCallUseMode>
<compatibilityMode>8.3.21</compatibilityMode>
<languages uuid="aec61191-2a87-4bff-b42a-6c57f9184a1a">
<name>English</name>
<synonym>
<key>en</key>
<value>English</value>
</synonym>
<languageCode>en</languageCode>
</languages>
<commonModules>CommonModule.CommonModule</commonModules>
<commonModules>CommonModule.CommonModuleServerCall</commonModules>
<commonForms>CommonForm.Form</commonForms>
</mdclass:Configuration>

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<cmi:CommandInterface xmlns:cmi="http://g5.1c.ru/v8/dt/cmi"/>