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;
}
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();
}
};
}
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();
}
};
}
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());
}
};
}
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();
}
};
}
Aggregations