Search in sources :

Example 1 with FunctionReference

use of com.jetbrains.php.lang.psi.elements.FunctionReference in project phpinspectionsea by kalessil.

the class AssertResourceExistsStrategy method apply.

public static boolean apply(@NotNull String methodName, @NotNull MethodReference reference, @NotNull ProblemsHolder holder) {
    boolean result = false;
    if (targetMapping.containsKey(methodName)) {
        final PsiElement[] assertionArguments = reference.getParameters();
        if (assertionArguments.length > 0 && OpenapiTypesUtil.isFunctionReference(assertionArguments[0])) {
            final FunctionReference candidate = (FunctionReference) assertionArguments[0];
            final String functionName = candidate.getName();
            if (functionName != null && targetFunctions.containsKey(functionName)) {
                final PsiElement[] functionArguments = candidate.getParameters();
                if (functionArguments.length == 1) {
                    final String suggestedAssertion = String.format(targetMapping.get(methodName), targetFunctions.get(functionName));
                    final String[] suggestedArguments = new String[assertionArguments.length];
                    suggestedArguments[0] = functionArguments[0].getText();
                    if (assertionArguments.length > 1) {
                        suggestedArguments[1] = assertionArguments[1].getText();
                    }
                    holder.registerProblem(reference, String.format(messagePattern, suggestedAssertion), new PhpUnitAssertFixer(suggestedAssertion, suggestedArguments));
                    result = true;
                }
            }
        }
    }
    return result;
}
Also used : PhpUnitAssertFixer(com.kalessil.phpStorm.phpInspectionsEA.fixers.PhpUnitAssertFixer) FunctionReference(com.jetbrains.php.lang.psi.elements.FunctionReference) PsiElement(com.intellij.psi.PsiElement)

Example 2 with FunctionReference

use of com.jetbrains.php.lang.psi.elements.FunctionReference in project phpinspectionsea by kalessil.

the class NonSecureCryptUsageInspector 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("crypt")) {
                return;
            }
            final PsiElement[] arguments = reference.getParameters();
            if ((arguments.length != 1 && arguments.length != 2) || !this.isFromRootNamespace(reference)) {
                return;
            }
            /* Case 1: suggest providing blowfish as the 2nd parameter*/
            if (arguments.length == 1) {
                holder.registerProblem(reference, messageWeakSalt);
                return;
            }
            /* try resolving 2nd parameter, skip if failed, it contains injections or length is not as expected */
            final String saltValue = this.resolveSalt(arguments[1]);
            if (null == saltValue || saltValue.length() < 4) {
                return;
            }
            /* Case 2: using $2a$; use $2y$ instead - http://php.net/security/crypt_blowfish.php*/
            if (saltValue.startsWith("$2a$")) {
                holder.registerProblem(reference, messageInsecureSalt, ProblemHighlightType.GENERIC_ERROR);
                return;
            }
            /* Case 3: -> password_hash(PASSWORD_BCRYPT) in PHP 5.5+ */
            final boolean isBlowfish = saltValue.startsWith("$2y$") || saltValue.startsWith("$2x$");
            if (isBlowfish) {
                PhpLanguageLevel php = PhpProjectConfigurationFacade.getInstance(holder.getProject()).getLanguageLevel();
                if (php.compareTo(PhpLanguageLevel.PHP550) >= 0) {
                    holder.registerProblem(reference, messagePasswordHash, ProblemHighlightType.WEAK_WARNING);
                }
            }
        }

        @Nullable
        private String resolveSalt(@NotNull PsiElement expression) {
            /* collect possible value for further analysis */
            final Set<PsiElement> discovered = PossibleValuesDiscoveryUtil.discover(expression);
            if (discovered.size() != 1) {
                discovered.clear();
                return null;
            }
            /* simplify workflow by handling one expression */
            final PsiElement saltExpression = discovered.iterator().next();
            final StringBuilder resolvedSaltValue = new StringBuilder();
            discovered.clear();
            /*  resolve string literals and concatenations */
            PsiElement current = saltExpression;
            while (current instanceof ConcatenationExpression) {
                final ConcatenationExpression concat = (ConcatenationExpression) current;
                final PsiElement right = ExpressionSemanticUtil.getExpressionTroughParenthesis(concat.getRightOperand());
                final StringLiteralExpression part = ExpressionSemanticUtil.resolveAsStringLiteral(right);
                resolvedSaltValue.insert(0, part == null ? "<?>" : part.getContents());
                current = ExpressionSemanticUtil.getExpressionTroughParenthesis(concat.getLeftOperand());
            }
            /* don't forget to add the last element */
            if (null != current) {
                final StringLiteralExpression lastPart = ExpressionSemanticUtil.resolveAsStringLiteral(current);
                resolvedSaltValue.insert(0, null == lastPart ? "<?>" : lastPart.getContents());
            }
            return resolvedSaltValue.toString();
        }
    };
}
Also used : BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) StringLiteralExpression(com.jetbrains.php.lang.psi.elements.StringLiteralExpression) FunctionReference(com.jetbrains.php.lang.psi.elements.FunctionReference) ConcatenationExpression(com.jetbrains.php.lang.psi.elements.ConcatenationExpression) NotNull(org.jetbrains.annotations.NotNull) PsiElement(com.intellij.psi.PsiElement) PhpLanguageLevel(com.jetbrains.php.config.PhpLanguageLevel) NotNull(org.jetbrains.annotations.NotNull)

Example 3 with FunctionReference

use of com.jetbrains.php.lang.psi.elements.FunctionReference in project phpinspectionsea by kalessil.

the class RsaOraclePaddingAttacksInspector method buildVisitor.

@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
    return new BasePhpElementVisitor() {

        @Override
        public void visitPhpFunctionCall(@NotNull FunctionReference reference) {
            final List<BooleanSupplier> callbacks = new ArrayList<>(2);
            callbacks.add(() -> OpensslRsaOraclePaddingStrategy.apply(holder, reference));
            callbacks.add(() -> McryptRsaOraclePaddingStrategy.apply(holder, reference));
            for (final BooleanSupplier callback : callbacks) {
                if (callback.getAsBoolean()) {
                    break;
                }
            }
            callbacks.clear();
        }
    };
}
Also used : BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) ArrayList(java.util.ArrayList) FunctionReference(com.jetbrains.php.lang.psi.elements.FunctionReference) NotNull(org.jetbrains.annotations.NotNull) BooleanSupplier(java.util.function.BooleanSupplier) NotNull(org.jetbrains.annotations.NotNull)

Example 4 with FunctionReference

use of com.jetbrains.php.lang.psi.elements.FunctionReference in project phpinspectionsea by kalessil.

the class FileFunctionMissUseInspector 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("file")) {
                return;
            }
            final PsiElement[] arguments = reference.getParameters();
            if (arguments.length != 1) {
                return;
            }
            /* function can be silenced, get parent for this case; validate parent structure */
            PsiElement parent = reference.getParent();
            if (parent instanceof UnaryExpression) {
                final PsiElement operation = ((UnaryExpression) parent).getOperation();
                if (OpenapiTypesUtil.is(operation, PhpTokenTypes.opSILENCE)) {
                    parent = parent.getParent();
                }
            }
            if (!(parent instanceof ParameterList) || !OpenapiTypesUtil.isFunctionReference(parent.getParent())) {
                return;
            }
            /* validate parent functions' name (implode or join) and amount of arguments */
            final FunctionReference parentReference = (FunctionReference) parent.getParent();
            final String parentName = parentReference.getName();
            if (parentName == null || (!parentName.equals("implode") && !parentName.equals("join"))) {
                return;
            }
            final PsiElement[] parentParams = parentReference.getParameters();
            if (parentParams.length != 2) {
                return;
            }
            /* validate if glue is not empty */
            final StringLiteralExpression glue = ExpressionSemanticUtil.resolveAsStringLiteral(parentParams[0]);
            if (glue != null && !glue.getContents().isEmpty()) {
                return;
            }
            final String message = String.format(messagePattern, arguments[0].getText());
            holder.registerProblem(parentReference, message, ProblemHighlightType.GENERIC_ERROR, new TheLocalFix());
        }
    };
}
Also used : BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) StringLiteralExpression(com.jetbrains.php.lang.psi.elements.StringLiteralExpression) FunctionReference(com.jetbrains.php.lang.psi.elements.FunctionReference) ParameterList(com.jetbrains.php.lang.psi.elements.ParameterList) UnaryExpression(com.jetbrains.php.lang.psi.elements.UnaryExpression) NotNull(org.jetbrains.annotations.NotNull) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 5 with FunctionReference

use of com.jetbrains.php.lang.psi.elements.FunctionReference 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();
        }
    };
}
Also used : BasePhpElementVisitor(com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor) PhpAccessVariableInstruction(com.jetbrains.php.codeInsight.controlFlow.instructions.PhpAccessVariableInstruction) Variable(com.jetbrains.php.lang.psi.elements.Variable) PhpScopeHolder(com.jetbrains.php.codeInsight.PhpScopeHolder) FunctionReference(com.jetbrains.php.lang.psi.elements.FunctionReference) NotNull(org.jetbrains.annotations.NotNull) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

FunctionReference (com.jetbrains.php.lang.psi.elements.FunctionReference)58 PsiElement (com.intellij.psi.PsiElement)55 NotNull (org.jetbrains.annotations.NotNull)46 BasePhpElementVisitor (com.kalessil.phpStorm.phpInspectionsEA.openApi.BasePhpElementVisitor)43 BinaryExpression (com.jetbrains.php.lang.psi.elements.BinaryExpression)16 StringLiteralExpression (com.jetbrains.php.lang.psi.elements.StringLiteralExpression)15 IElementType (com.intellij.psi.tree.IElementType)11 PhpUnitAssertFixer (com.kalessil.phpStorm.phpInspectionsEA.fixers.PhpUnitAssertFixer)9 ArrayCreationExpression (com.jetbrains.php.lang.psi.elements.ArrayCreationExpression)6 UnaryExpression (com.jetbrains.php.lang.psi.elements.UnaryExpression)6 Function (com.jetbrains.php.lang.psi.elements.Function)5 MethodReference (com.jetbrains.php.lang.psi.elements.MethodReference)5 ParameterList (com.jetbrains.php.lang.psi.elements.ParameterList)5 PhpLanguageLevel (com.jetbrains.php.config.PhpLanguageLevel)4 ArrayList (java.util.ArrayList)4 Nullable (org.jetbrains.annotations.Nullable)4 ProblemsHolder (com.intellij.codeInspection.ProblemsHolder)3 PsiWhiteSpace (com.intellij.psi.PsiWhiteSpace)3 ArrayAccessExpression (com.jetbrains.php.lang.psi.elements.ArrayAccessExpression)3 HashSet (java.util.HashSet)3