use of com.jetbrains.php.lang.psi.elements.ArrayCreationExpression in project yii2support by nvlad.
the class ObjectFactoryReference method resolve.
@Nullable
@Override
public PsiElement resolve() {
PsiElement possibleArrayCreation = myElement.getParent().getParent().getParent();
if (possibleArrayCreation instanceof ArrayCreationExpression) {
ArrayCreationExpression arrayCreation = (ArrayCreationExpression) possibleArrayCreation;
PsiDirectory dir = myElement.getContainingFile().getContainingDirectory();
PhpClass phpClass = ObjectFactoryUtils.findClassByArrayCreation(arrayCreation, dir);
if (phpClass != null) {
PsiElement field = ClassUtils.findWritableField(phpClass, myElement.getText());
return field;
}
}
return null;
}
use of com.jetbrains.php.lang.psi.elements.ArrayCreationExpression in project phpinspectionsea by kalessil.
the class TypeUnsafeArraySearchInspector 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 && targetFunctions.contains(functionName)) {
final PsiElement[] arguments = reference.getParameters();
if (arguments.length == 2) {
/* false-positives: array of string literals */
if (arguments[1] instanceof ArrayCreationExpression) {
final PsiElement[] elements = arguments[1].getChildren();
if (elements.length > 0) {
final long validElementsCount = Arrays.stream(elements).filter(element -> OpenapiTypesUtil.is(element, PhpElementTypes.ARRAY_VALUE)).map(PsiElement::getFirstChild).filter(element -> element instanceof StringLiteralExpression).map(literal -> ((StringLiteralExpression) literal).getContents().trim()).filter(content -> !content.isEmpty() && !content.matches("^\\d+$")).count();
if (validElementsCount == elements.length) {
return;
}
}
}
/* false-positives: array and item types are complimentary */
if (arguments[0] instanceof PhpTypedElement && arguments[1] instanceof PhpTypedElement) {
final Project project = holder.getProject();
final PhpType arrayType = OpenapiResolveUtil.resolveType((PhpTypedElement) arguments[1], project);
final Set<String> arrayTypes = arrayType == null ? null : arrayType.filterUnknown().getTypes();
if (arrayTypes != null && arrayTypes.size() == 1) {
final PhpType itemType = OpenapiResolveUtil.resolveType((PhpTypedElement) arguments[0], project);
final Set<String> itemTypes = itemType == null ? null : itemType.filterUnknown().getTypes();
if (itemTypes != null && itemTypes.size() == 1) {
final boolean matching = this.areTypesMatching(itemTypes.iterator().next(), arrayTypes.iterator().next());
if (matching) {
return;
}
}
}
}
/* general case: we need the third argument */
final String replacement = String.format("%s%s(%s, %s, true)", reference.getImmediateNamespaceName(), functionName, arguments[0].getText(), arguments[1].getText());
holder.registerProblem(reference, MessagesPresentationUtil.prefixWithEa(message), new MakeSearchTypeSensitiveFix(replacement));
}
}
}
private boolean areTypesMatching(@NotNull String itemType, @NotNull String arrayType) {
boolean result = false;
if (!itemType.isEmpty()) {
result = arrayType.equals((itemType.charAt(0) == '\\' ? itemType : '\\' + itemType) + "[]");
}
return result;
}
};
}
use of com.jetbrains.php.lang.psi.elements.ArrayCreationExpression in project phpinspectionsea by kalessil.
the class PackedHashtableOptimizationInspector method buildVisitor.
@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new BasePhpElementVisitor() {
/* TODO: docs, http://blog.jpauli.tech/2016/04/08/hashtables.html#packed-hashtable-optimization */
@Override
public void visitPhpArrayCreationExpression(@NotNull ArrayCreationExpression expression) {
/* requires PHP7 */
if (PhpLanguageLevel.get(holder.getProject()).below(PhpLanguageLevel.PHP700)) {
return;
}
/* requires at least 3 children - let array to grow enough */
final PsiElement[] children = expression.getChildren();
if (children.length < 3) {
return;
}
/* false-positives: test classes */
if (this.isTestContext(expression)) {
return;
}
/* step 1: collect indexes and verify array structure */
final List<PhpPsiElement> indexes = new ArrayList<>();
for (final PsiElement pairCandidate : children) {
if (pairCandidate instanceof ArrayHashElement) {
final PhpPsiElement key = ((ArrayHashElement) pairCandidate).getKey();
if ((key instanceof StringLiteralExpression && key.getFirstPsiChild() == null) || OpenapiTypesUtil.isNumber(key)) {
indexes.add(key);
continue;
}
}
break;
}
if (indexes.size() != children.length) {
indexes.clear();
return;
}
/* step 2: analyze collected indexes */
// if string literal is not numeric => stop
boolean hasStringIndexes = false;
boolean hasIncreasingIndexes = true;
int lastIndex = Integer.MIN_VALUE;
for (PhpPsiElement index : indexes) {
final String numericIndex;
final int integerIndex;
/* extract text representation of the index */
if (index instanceof StringLiteralExpression) {
hasStringIndexes = true;
numericIndex = ((StringLiteralExpression) index).getContents();
/* '01' and etc cases can not be converted */
if (numericIndex.length() > 1 && '0' == numericIndex.charAt(0)) {
indexes.clear();
return;
}
} else {
numericIndex = index.getText().replaceAll("\\s+", "");
}
/* try converting into integer */
try {
integerIndex = Integer.parseInt(numericIndex);
} catch (NumberFormatException error) {
indexes.clear();
return;
}
if (integerIndex < lastIndex) {
hasIncreasingIndexes = false;
}
lastIndex = integerIndex;
}
/* report if criteria are met */
if (!hasIncreasingIndexes) {
holder.registerProblem(expression.getFirstChild(), MessagesPresentationUtil.prefixWithEa(messageReorder));
}
if (hasIncreasingIndexes && hasStringIndexes) {
holder.registerProblem(expression.getFirstChild(), MessagesPresentationUtil.prefixWithEa(messageUseNumericKeys));
}
}
};
}
use of com.jetbrains.php.lang.psi.elements.ArrayCreationExpression in project phpinspectionsea by kalessil.
the class DuplicateArrayKeysInspector method buildVisitor.
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new PhpElementVisitor() {
@Override
public void visitPhpArrayCreationExpression(@NotNull ArrayCreationExpression expression) {
final Map<String, PsiElement> processed = new HashMap<>();
for (final ArrayHashElement pair : expression.getHashElements()) {
final PhpPsiElement key = pair.getKey();
if (key instanceof StringLiteralExpression && key.getFirstPsiChild() == null) {
final PsiElement value = pair.getValue();
if (value != null) {
final String literal = ((StringLiteralExpression) key).getContents();
if (processed.containsKey(literal)) {
final boolean isPairDuplicated = !(value instanceof ArrayCreationExpression) && OpenapiEquivalenceUtil.areEqual(value, processed.get(literal));
if (isPairDuplicated) {
holder.registerProblem(pair, MessagesPresentationUtil.prefixWithEa(messageDuplicatePair), ProblemHighlightType.LIKE_UNUSED_SYMBOL);
} else {
holder.registerProblem(key, MessagesPresentationUtil.prefixWithEa(messageDuplicateKey));
}
}
processed.put(literal, value);
}
}
}
processed.clear();
}
};
}
use of com.jetbrains.php.lang.psi.elements.ArrayCreationExpression 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();
}
};
}
Aggregations