use of com.jetbrains.php.lang.psi.elements.Variable in project phpinspectionsea by kalessil.
the class ExplodeMissUseInspector method buildVisitor.
@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new BasePhpElementVisitor() {
@Override
public void visitPhpFunctionCall(@NotNull FunctionReference reference) {
/* general structure expectations */
final String functionName = reference.getName();
if (functionName == null || !semanticMapping.containsKey(functionName)) {
return;
}
final PsiElement[] arguments = reference.getParameters();
if (arguments.length != 1) {
return;
}
/* discover possible values */
final Set<PsiElement> values = PossibleValuesDiscoveryUtil.discover(arguments[0]);
/* do not analyze invariants */
if (1 == values.size()) {
final PsiElement value = values.iterator().next();
values.clear();
if (OpenapiTypesUtil.isFunctionReference(value)) {
/* inner call must be explode() */
final FunctionReference innerCall = (FunctionReference) value;
final String innerFunctionName = innerCall.getName();
if (innerFunctionName == null || !innerFunctionName.equals("explode")) {
return;
}
final PsiElement[] innerArguments = innerCall.getParameters();
if (innerArguments.length != 2) {
return;
}
/* if the parameter is a variable, ensure it used only 2 times (write, read) */
if (arguments[0] instanceof Variable) {
final PhpScopeHolder parentScope = ExpressionSemanticUtil.getScope(reference);
if (null != parentScope) {
final PhpAccessVariableInstruction[] usages = PhpControlFlowUtil.getFollowingVariableAccessInstructions(parentScope.getControlFlow().getEntryPoint(), ((Variable) arguments[0]).getName(), false);
if (2 != usages.length) {
return;
}
}
}
final String replacement = semanticMapping.get(functionName).replace("%f%", innerArguments[0].getText()).replace("%s%", innerArguments[1].getText());
final String message = messagePattern.replace("%e%", replacement);
if (arguments[0] == value) {
holder.registerProblem(reference, message, new UseAlternativeFix(replacement));
} else {
holder.registerProblem(reference, message);
}
}
}
values.clear();
}
};
}
use of com.jetbrains.php.lang.psi.elements.Variable in project phpinspectionsea by kalessil.
the class BadExceptionsProcessingInspector method buildVisitor.
@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new BasePhpElementVisitor() {
@Override
public void visitPhpTry(@NotNull Try tryStatement) {
final GroupStatement body = ExpressionSemanticUtil.getGroupStatement(tryStatement);
final int expressionsCount = body == null ? 0 : ExpressionSemanticUtil.countExpressionsInGroup(body);
if (expressionsCount > 3) {
holder.registerProblem(tryStatement.getFirstChild(), MessagesPresentationUtil.prefixWithEa(messagePattern.replace("%c%", String.valueOf(expressionsCount))));
}
}
@Override
public void visitPhpCatch(@NotNull Catch catchStatement) {
final Variable variable = catchStatement.getException();
final GroupStatement body = ExpressionSemanticUtil.getGroupStatement(catchStatement);
if (variable != null && body != null) {
final String variableName = variable.getName();
if (!StringUtils.isEmpty(variableName)) {
/* incomplete catch statement */
boolean isVariableUsed = false;
for (final Variable usedVariable : PsiTreeUtil.findChildrenOfType(body, Variable.class)) {
if (usedVariable.getName().equals(variableName)) {
isVariableUsed = true;
break;
}
}
if (!isVariableUsed) {
if (ExpressionSemanticUtil.countExpressionsInGroup(body) == 0) {
holder.registerProblem(variable, MessagesPresentationUtil.prefixWithEa(messageFailSilently));
} else {
holder.registerProblem(variable, MessagesPresentationUtil.prefixWithEa(messageChainedException));
}
}
}
}
}
};
}
use of com.jetbrains.php.lang.psi.elements.Variable in project phpinspectionsea by kalessil.
the class UnserializeExploitsInspector method buildVisitor.
@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new BasePhpElementVisitor() {
@Override
public void visitPhpFunctionCall(@NotNull FunctionReference reference) {
final String functionName = reference.getName();
if (functionName != null && functionName.equals("unserialize")) {
final boolean supportsOptions = PhpLanguageLevel.get(holder.getProject()).atLeast(PhpLanguageLevel.PHP700);
final PsiElement[] arguments = reference.getParameters();
if (arguments.length == 1 && !this.isTestContext(reference)) {
/* pattern: use 2nd argument since PHP7 */
if (supportsOptions) {
holder.registerProblem(reference, MessagesPresentationUtil.prefixWithEa(messageUseSecondArgument));
}
/* pattern: exploitable calls */
this.inspectExploits(holder, arguments[0]);
} else if (arguments.length == 2 && !this.isTestContext(reference)) {
if (arguments[1] instanceof ArrayCreationExpression) {
final boolean hasClassesListed = arguments[1].getChildren().length > 0;
if (!hasClassesListed) {
holder.registerProblem(reference, MessagesPresentationUtil.prefixWithEa(messageUseSecondArgument));
}
} else if (PhpLanguageUtil.isTrue(arguments[1])) {
holder.registerProblem(reference, MessagesPresentationUtil.prefixWithEa(messageUseSecondArgument));
}
}
}
}
private void inspectExploits(@NotNull ProblemsHolder holder, @NotNull PsiElement argument) {
final Set<PsiElement> values = PossibleValuesDiscoveryUtil.discover(argument);
if (!values.isEmpty()) {
final List<String> reporting = new ArrayList<>();
for (PsiElement value : values) {
if (OpenapiTypesUtil.isFunctionReference(value)) {
final FunctionReference call = (FunctionReference) value;
final String functionName = call.getName();
if (functionName != null && untrustedFunctions.contains(functionName)) {
reporting.add(functionName + "(...)");
}
continue;
}
/* extract array access variable */
if (value instanceof ArrayAccessExpression) {
PsiElement container = value;
while (container instanceof ArrayAccessExpression) {
container = ((ArrayAccessExpression) container).getValue();
}
if (container instanceof Variable) {
value = container;
}
}
if (value instanceof Variable && untrustedVars.contains(((Variable) value).getName())) {
reporting.add(value.getText());
// continue
}
/* other expressions are not supported currently */
}
/* got something for reporting */
if (!reporting.isEmpty()) {
/* sort reporting list to produce testable results */
Collections.sort(reporting);
holder.registerProblem(argument, MessagesPresentationUtil.prefixWithEa(messagePattern.replace("%e%", String.join(", ", reporting))), ProblemHighlightType.GENERIC_ERROR);
reporting.clear();
}
}
values.clear();
}
};
}
use of com.jetbrains.php.lang.psi.elements.Variable in project phpinspectionsea by kalessil.
the class ShortListSyntaxCanBeUsedInspector method buildVisitor.
@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly) {
return new BasePhpElementVisitor() {
public void visitPhpMultiassignmentExpression(MultiassignmentExpression multiassignmentExpression) {
/* ensure php version is at least PHP 7.1 */
final PhpLanguageLevel phpVersion = PhpProjectConfigurationFacade.getInstance(holder.getProject()).getLanguageLevel();
if (phpVersion.compareTo(PhpLanguageLevel.PHP710) < 0) {
return;
}
/* verify if it's dedicated statement and it's the list(...) construction */
final PsiElement parent = multiassignmentExpression.getParent();
if (!OpenapiTypesUtil.isStatementImpl(parent)) {
return;
}
final PsiElement listKeyword = multiassignmentExpression.getFirstChild();
if (null != listKeyword && PhpTokenTypes.kwLIST == listKeyword.getNode().getElementType()) {
holder.registerProblem(listKeyword, messageAssign, ProblemHighlightType.WEAK_WARNING, new TheLocalFix());
}
}
public void visitPhpForeach(ForeachStatement foreach) {
/* ensure php version is at least PHP 7.1 */
final PhpLanguageLevel phpVersion = PhpProjectConfigurationFacade.getInstance(holder.getProject()).getLanguageLevel();
if (phpVersion.compareTo(PhpLanguageLevel.PHP710) < 0) {
return;
}
final List<Variable> variables = foreach.getVariables();
if (variables.size() > 0) {
PsiElement childNode = foreach.getFirstChild();
while (null != childNode) {
if (childNode.getClass() == LeafPsiElement.class && PhpTokenTypes.kwLIST == childNode.getNode().getElementType()) {
holder.registerProblem(childNode, messageForeach, ProblemHighlightType.WEAK_WARNING, new TheLocalFix());
break;
}
childNode = childNode.getNextSibling();
if (childNode instanceof GroupStatement) {
break;
}
}
}
}
};
}
use of com.jetbrains.php.lang.psi.elements.Variable in project phpinspectionsea by kalessil.
the class ArgumentUnpackingCanBeUsedInspector method buildVisitor.
@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new BasePhpElementVisitor() {
@Override
public void visitPhpFunctionCall(@NotNull FunctionReference reference) {
final PhpLanguageLevel php = PhpProjectConfigurationFacade.getInstance(holder.getProject()).getLanguageLevel();
if (php.compareTo(PhpLanguageLevel.PHP560) >= 0) {
final String functionName = reference.getName();
if (functionName != null && functionName.equals("call_user_func_array")) {
final PsiElement[] arguments = reference.getParameters();
if (arguments.length == 2) {
final boolean isContainerValid = arguments[1] instanceof Variable || arguments[1] instanceof ArrayCreationExpression || arguments[1] instanceof FunctionReference;
if (isContainerValid && arguments[0] instanceof StringLiteralExpression) {
/* do not process strings with injections */
final StringLiteralExpression targetFunction = (StringLiteralExpression) arguments[0];
if (targetFunction.getFirstPsiChild() == null) {
final String replacement = "%f%(...%a%)".replace("%a%", arguments[1].getText()).replace("%f%", targetFunction.getContents());
final String message = messagePattern.replace("%e%", replacement);
holder.registerProblem(reference, message, new UnpackFix(replacement));
}
}
}
}
}
// TODO: if (isContainerValid && params[0] instanceof ArrayCreationExpression) {
// TODO: call_user_func_array([...], ...); string method name must not contain ::
}
};
}
Aggregations