Search in sources :

Example 1 with MemberExpression

use of de.fraunhofer.aisec.cpg.graph.statements.expressions.MemberExpression in project cpg by Fraunhofer-AISEC.

the class StaticImportsTest method testAsteriskImport.

@Test
void testAsteriskImport() throws Exception {
    List<TranslationUnitDeclaration> result = TestUtils.analyze("java", topLevel.resolve("asterisk"), true);
    List<MethodDeclaration> methods = TestUtils.subnodesOfType(result, MethodDeclaration.class);
    MethodDeclaration main = TestUtils.findByUniqueName(methods, "main");
    List<RecordDeclaration> records = TestUtils.subnodesOfType(result, RecordDeclaration.class);
    RecordDeclaration A = TestUtils.findByUniqueName(records, "A");
    RecordDeclaration B = TestUtils.findByUniqueName(records, "B");
    for (CallExpression call : TestUtils.subnodesOfType(main, CallExpression.class)) {
        switch(call.getName()) {
            case "a":
                assertEquals(List.of(TestUtils.findByUniqueName(methods, "a")), call.getInvokes());
                assertTrue(((MethodDeclaration) call.getInvokes().get(0)).isStatic());
                break;
            case "b":
                List<MethodDeclaration> bs = methods.stream().filter(m -> m.getName().equals("b") && m.isStatic()).collect(Collectors.toList());
                assertEquals(call.getInvokes(), bs.stream().filter(b -> b.hasSignature(call.getSignature())).collect(Collectors.toList()));
                break;
            case "nonStatic":
                MethodDeclaration nonStatic = TestUtils.findByUniqueName(B.getMethods(), "nonStatic");
                assertTrue(nonStatic.isInferred());
                assertEquals(List.of(nonStatic), call.getInvokes());
        }
    }
    List<FieldDeclaration> testFields = TestUtils.subnodesOfType(A, FieldDeclaration.class);
    FieldDeclaration staticField = TestUtils.findByUniqueName(testFields, "staticField");
    FieldDeclaration nonStaticField = TestUtils.findByUniqueName(testFields, "nonStaticField");
    assertTrue(staticField.getModifiers().contains("static"));
    assertFalse(nonStaticField.getModifiers().contains("static"));
    List<MemberExpression> declaredReferences = TestUtils.subnodesOfType(main, MemberExpression.class);
    MemberExpression usage = TestUtils.findByUniqueName(declaredReferences, "staticField");
    assertEquals(staticField, usage.getRefersTo());
    MemberExpression nonStatic = TestUtils.findByUniqueName(declaredReferences, "nonStaticField");
    assertNotEquals(nonStaticField, nonStatic.getRefersTo());
    assertTrue(nonStatic.getRefersTo().isInferred());
}
Also used : TestUtils(de.fraunhofer.aisec.cpg.TestUtils) RecordDeclaration(de.fraunhofer.aisec.cpg.graph.declarations.RecordDeclaration) FieldDeclaration(de.fraunhofer.aisec.cpg.graph.declarations.FieldDeclaration) BaseTest(de.fraunhofer.aisec.cpg.BaseTest) Collectors(java.util.stream.Collectors) Test(org.junit.jupiter.api.Test) List(java.util.List) MemberExpression(de.fraunhofer.aisec.cpg.graph.statements.expressions.MemberExpression) Assertions(org.junit.jupiter.api.Assertions) TranslationUnitDeclaration(de.fraunhofer.aisec.cpg.graph.declarations.TranslationUnitDeclaration) MethodDeclaration(de.fraunhofer.aisec.cpg.graph.declarations.MethodDeclaration) Path(java.nio.file.Path) CallExpression(de.fraunhofer.aisec.cpg.graph.statements.expressions.CallExpression) RecordDeclaration(de.fraunhofer.aisec.cpg.graph.declarations.RecordDeclaration) MemberExpression(de.fraunhofer.aisec.cpg.graph.statements.expressions.MemberExpression) MethodDeclaration(de.fraunhofer.aisec.cpg.graph.declarations.MethodDeclaration) TranslationUnitDeclaration(de.fraunhofer.aisec.cpg.graph.declarations.TranslationUnitDeclaration) CallExpression(de.fraunhofer.aisec.cpg.graph.statements.expressions.CallExpression) FieldDeclaration(de.fraunhofer.aisec.cpg.graph.declarations.FieldDeclaration) BaseTest(de.fraunhofer.aisec.cpg.BaseTest) Test(org.junit.jupiter.api.Test)

Example 2 with MemberExpression

use of de.fraunhofer.aisec.cpg.graph.statements.expressions.MemberExpression in project cpg by Fraunhofer-AISEC.

the class StaticImportsTest method testSingleStaticImport.

@Test
void testSingleStaticImport() throws Exception {
    List<TranslationUnitDeclaration> result = TestUtils.analyze("java", topLevel.resolve("single"), true);
    List<MethodDeclaration> methods = TestUtils.subnodesOfType(result, MethodDeclaration.class);
    MethodDeclaration test = TestUtils.findByUniqueName(methods, "test");
    MethodDeclaration main = TestUtils.findByUniqueName(methods, "main");
    CallExpression call = TestUtils.subnodesOfType(main, CallExpression.class).get(0);
    assertEquals(List.of(test), call.getInvokes());
    List<FieldDeclaration> testFields = TestUtils.subnodesOfType(result, FieldDeclaration.class).stream().filter(f -> f.getName().equals("test")).collect(Collectors.toList());
    assertEquals(1, testFields.size());
    FieldDeclaration staticField = testFields.get(0);
    assertTrue(staticField.getModifiers().contains("static"));
    List<MemberExpression> memberExpressions = TestUtils.subnodesOfType(main, MemberExpression.class);
    MemberExpression usage = TestUtils.findByUniqueName(memberExpressions, "test");
    assertEquals(staticField, usage.getRefersTo());
}
Also used : TestUtils(de.fraunhofer.aisec.cpg.TestUtils) RecordDeclaration(de.fraunhofer.aisec.cpg.graph.declarations.RecordDeclaration) FieldDeclaration(de.fraunhofer.aisec.cpg.graph.declarations.FieldDeclaration) BaseTest(de.fraunhofer.aisec.cpg.BaseTest) Collectors(java.util.stream.Collectors) Test(org.junit.jupiter.api.Test) List(java.util.List) MemberExpression(de.fraunhofer.aisec.cpg.graph.statements.expressions.MemberExpression) Assertions(org.junit.jupiter.api.Assertions) TranslationUnitDeclaration(de.fraunhofer.aisec.cpg.graph.declarations.TranslationUnitDeclaration) MethodDeclaration(de.fraunhofer.aisec.cpg.graph.declarations.MethodDeclaration) Path(java.nio.file.Path) CallExpression(de.fraunhofer.aisec.cpg.graph.statements.expressions.CallExpression) MemberExpression(de.fraunhofer.aisec.cpg.graph.statements.expressions.MemberExpression) MethodDeclaration(de.fraunhofer.aisec.cpg.graph.declarations.MethodDeclaration) TranslationUnitDeclaration(de.fraunhofer.aisec.cpg.graph.declarations.TranslationUnitDeclaration) CallExpression(de.fraunhofer.aisec.cpg.graph.statements.expressions.CallExpression) FieldDeclaration(de.fraunhofer.aisec.cpg.graph.declarations.FieldDeclaration) BaseTest(de.fraunhofer.aisec.cpg.BaseTest) Test(org.junit.jupiter.api.Test)

Example 3 with MemberExpression

use of de.fraunhofer.aisec.cpg.graph.statements.expressions.MemberExpression in project cpg by Fraunhofer-AISEC.

the class VRUtil method assertUsageOfMemberAndBase.

/**
 * Asserts that {@code usingNode} uses/references the provided {@code usedBase} and {@code
 * usedMember}. If {@link VRUtil#ENFORCE_MEMBER_EXPRESSION} is true, {@code usingNode} must be a
 * {@link MemberExpression} where {@link MemberExpression#base} uses {@code usedBase} and {@link
 * MemberExpression#refersTo} uses {@code usedMember}. Using is checked as preformed per {@link
 * VRUtil#assertUsageOf(Node,Node)}
 *
 * @param usingNode - Node that uses some member
 * @param usedBase - The expected base that is used
 * @param usedMember - THe expected member that is used
 */
public static void assertUsageOfMemberAndBase(Node usingNode, Node usedBase, Node usedMember) {
    assertNotNull(usingNode);
    if (!(usingNode instanceof MemberExpression) && !ENFORCE_MEMBER_EXPRESSION) {
        // Assumtion here is that the target of the member portion of the expression and not the base
        // is resolved
        assertUsageOf(usingNode, usedMember);
    } else {
        assertTrue(usingNode instanceof MemberExpression);
        MemberExpression memberExpression = (MemberExpression) usingNode;
        Node base = memberExpression.getBase();
        assertUsageOf(base, usedBase);
        assertUsageOf(memberExpression.getRefersTo(), usedMember);
    }
}
Also used : MemberExpression(de.fraunhofer.aisec.cpg.graph.statements.expressions.MemberExpression) Node(de.fraunhofer.aisec.cpg.graph.Node)

Example 4 with MemberExpression

use of de.fraunhofer.aisec.cpg.graph.statements.expressions.MemberExpression in project cpg by Fraunhofer-AISEC.

the class VariableUsageResolver method resolveFieldUsages.

protected void resolveFieldUsages(Node current, RecordDeclaration curClass) {
    if (current instanceof MemberExpression) {
        MemberExpression memberExpression = (MemberExpression) current;
        Declaration baseTarget = null;
        if (memberExpression.getBase() instanceof DeclaredReferenceExpression) {
            DeclaredReferenceExpression base = (DeclaredReferenceExpression) memberExpression.getBase();
            if (lang instanceof JavaLanguageFrontend && base.getName().equals("super")) {
                if (curClass != null && !curClass.getSuperClasses().isEmpty()) {
                    var superType = curClass.getSuperClasses().get(0);
                    var superRecord = recordMap.get(superType);
                    if (superRecord == null) {
                        log.error("Could not find referring super type {} for {} in the record map. Will set the super type to java.lang.Object", superType.getTypeName(), curClass.getName());
                        base.setType(TypeParser.createFrom(Object.class.getName(), true));
                    } else {
                        baseTarget = superRecord.getThis();
                        base.setRefersTo(baseTarget);
                    }
                } else {
                    // no explicit super type -> java.lang.Object
                    Type objectType = TypeParser.createFrom(Object.class.getName(), true);
                    base.setType(objectType);
                }
            } else {
                baseTarget = resolveBase((DeclaredReferenceExpression) memberExpression.getBase());
                base.setRefersTo(baseTarget);
            }
            if (baseTarget instanceof EnumDeclaration) {
                String name = memberExpression.getName();
                Optional<EnumConstantDeclaration> memberTarget = ((EnumDeclaration) baseTarget).getEntries().stream().filter(e -> e.getName().equals(name)).findFirst();
                if (memberTarget.isPresent()) {
                    memberExpression.setRefersTo(memberTarget.get());
                    return;
                }
            } else if (baseTarget instanceof RecordDeclaration) {
                Type baseType = TypeParser.createFrom(baseTarget.getName(), true);
                if (!recordMap.containsKey(baseType)) {
                    final Type containingT = baseType;
                    Optional<Type> fqnResolvedType = recordMap.keySet().stream().filter(t -> t.getName().endsWith("." + containingT.getName())).findFirst();
                    if (fqnResolvedType.isPresent()) {
                        baseType = fqnResolvedType.get();
                    }
                }
                memberExpression.setRefersTo(resolveMember(baseType, memberExpression));
                return;
            }
        }
        Type baseType = memberExpression.getBase().getType();
        if (!recordMap.containsKey(baseType)) {
            final Type containingT = baseType;
            Optional<Type> fqnResolvedType = recordMap.keySet().stream().filter(t -> t.getName().endsWith("." + containingT.getName())).findFirst();
            if (fqnResolvedType.isPresent()) {
                baseType = fqnResolvedType.get();
            }
        }
        memberExpression.setRefersTo(resolveMember(baseType, memberExpression));
    }
}
Also used : Util.warnWithFileLocation(de.fraunhofer.aisec.cpg.helpers.Util.warnWithFileLocation) java.util(java.util) DeclaredReferenceExpression(de.fraunhofer.aisec.cpg.graph.statements.expressions.DeclaredReferenceExpression) Logger(org.slf4j.Logger) LoggerFactory(org.slf4j.LoggerFactory) de.fraunhofer.aisec.cpg.graph(de.fraunhofer.aisec.cpg.graph) ScopedWalker(de.fraunhofer.aisec.cpg.helpers.SubgraphWalker.ScopedWalker) NodeBuilder.newRecordDeclaration(de.fraunhofer.aisec.cpg.graph.NodeBuilder.newRecordDeclaration) Collectors(java.util.stream.Collectors) TranslationResult(de.fraunhofer.aisec.cpg.TranslationResult) MemberCallExpression(de.fraunhofer.aisec.cpg.graph.statements.expressions.MemberCallExpression) Matcher(java.util.regex.Matcher) de.fraunhofer.aisec.cpg.graph.declarations(de.fraunhofer.aisec.cpg.graph.declarations) MemberExpression(de.fraunhofer.aisec.cpg.graph.statements.expressions.MemberExpression) Util(de.fraunhofer.aisec.cpg.helpers.Util) de.fraunhofer.aisec.cpg.graph.types(de.fraunhofer.aisec.cpg.graph.types) Pattern(java.util.regex.Pattern) JavaLanguageFrontend(de.fraunhofer.aisec.cpg.frontends.java.JavaLanguageFrontend) Nullable(org.checkerframework.checker.nullness.qual.Nullable) MemberExpression(de.fraunhofer.aisec.cpg.graph.statements.expressions.MemberExpression) NodeBuilder.newRecordDeclaration(de.fraunhofer.aisec.cpg.graph.NodeBuilder.newRecordDeclaration) DeclaredReferenceExpression(de.fraunhofer.aisec.cpg.graph.statements.expressions.DeclaredReferenceExpression) NodeBuilder.newRecordDeclaration(de.fraunhofer.aisec.cpg.graph.NodeBuilder.newRecordDeclaration) JavaLanguageFrontend(de.fraunhofer.aisec.cpg.frontends.java.JavaLanguageFrontend)

Example 5 with MemberExpression

use of de.fraunhofer.aisec.cpg.graph.statements.expressions.MemberExpression in project cpg by Fraunhofer-AISEC.

the class VariableUsageResolver method resolveLocalVarUsage.

protected void resolveLocalVarUsage(RecordDeclaration currentClass, Node parent, Node current) {
    if (lang == null) {
        Util.errorWithFileLocation(current, log, "Could not resolve local variable usage: language frontend is null");
        return;
    }
    if (current instanceof DeclaredReferenceExpression && !(current instanceof MemberExpression)) {
        DeclaredReferenceExpression ref = (DeclaredReferenceExpression) current;
        if (parent instanceof MemberCallExpression && current == ((MemberCallExpression) parent).getMember() && !(ref.getType() instanceof FunctionPointerType)) {
            // function pointer call
            return;
        }
        // only consider resolving, if the language frontend did not specify a resolution
        Optional<? extends Declaration> refersTo = ref.getRefersTo() == null ? Optional.ofNullable(lang.getScopeManager().resolveReference(ref)) : Optional.of(ref.getRefersTo());
        Type recordDeclType = null;
        if (currentClass != null) {
            recordDeclType = TypeParser.createFrom(currentClass.getName(), true);
        }
        if (ref.getType() instanceof FunctionPointerType && refersTo.isEmpty()) {
            refersTo = resolveFunctionPtr(recordDeclType, ref);
        }
        // only add new nodes for non-static unknown
        if (refersTo.isEmpty() && !(((DeclaredReferenceExpression) current).isStaticAccess()) && recordDeclType != null && recordMap.containsKey(recordDeclType)) {
            // Maybe we are referring to a field instead of a local var
            if (current.getName().contains(lang.getNamespaceDelimiter())) {
                List<String> path = Arrays.asList(current.getName().split(Pattern.quote(lang.getNamespaceDelimiter())));
                recordDeclType = TypeParser.createFrom(String.join(lang.getNamespaceDelimiter(), path.subList(0, path.size() - 1)), true);
            }
            ValueDeclaration field = resolveMember(recordDeclType, (DeclaredReferenceExpression) current);
            if (field != null) {
                refersTo = Optional.of(field);
            }
        }
        // just enables CXX static fields
        if (refersTo.isEmpty() && current.getName().contains(lang.getNamespaceDelimiter())) {
            var path = Arrays.asList(current.getName().split(Pattern.quote(lang.getNamespaceDelimiter())));
            recordDeclType = TypeParser.createFrom(String.join(lang.getNamespaceDelimiter(), path.subList(0, path.size() - 1)), true);
            var field = resolveMember(recordDeclType, (DeclaredReferenceExpression) current);
            if (field != null) {
                refersTo = Optional.of(field);
            }
        }
        if (refersTo.isPresent()) {
            ref.setRefersTo(refersTo.get());
        } else {
            warnWithFileLocation(current, log, "Did not find a declaration for {}", ref.getName());
        }
    }
}
Also used : MemberExpression(de.fraunhofer.aisec.cpg.graph.statements.expressions.MemberExpression) DeclaredReferenceExpression(de.fraunhofer.aisec.cpg.graph.statements.expressions.DeclaredReferenceExpression) MemberCallExpression(de.fraunhofer.aisec.cpg.graph.statements.expressions.MemberCallExpression)

Aggregations

MemberExpression (de.fraunhofer.aisec.cpg.graph.statements.expressions.MemberExpression)6 BaseTest (de.fraunhofer.aisec.cpg.BaseTest)3 FieldDeclaration (de.fraunhofer.aisec.cpg.graph.declarations.FieldDeclaration)3 MethodDeclaration (de.fraunhofer.aisec.cpg.graph.declarations.MethodDeclaration)3 RecordDeclaration (de.fraunhofer.aisec.cpg.graph.declarations.RecordDeclaration)3 TranslationUnitDeclaration (de.fraunhofer.aisec.cpg.graph.declarations.TranslationUnitDeclaration)3 DeclaredReferenceExpression (de.fraunhofer.aisec.cpg.graph.statements.expressions.DeclaredReferenceExpression)3 Collectors (java.util.stream.Collectors)3 Test (org.junit.jupiter.api.Test)3 TestUtils (de.fraunhofer.aisec.cpg.TestUtils)2 CallExpression (de.fraunhofer.aisec.cpg.graph.statements.expressions.CallExpression)2 MemberCallExpression (de.fraunhofer.aisec.cpg.graph.statements.expressions.MemberCallExpression)2 Path (java.nio.file.Path)2 List (java.util.List)2 Assertions (org.junit.jupiter.api.Assertions)2 TranslationResult (de.fraunhofer.aisec.cpg.TranslationResult)1 JavaLanguageFrontend (de.fraunhofer.aisec.cpg.frontends.java.JavaLanguageFrontend)1 de.fraunhofer.aisec.cpg.graph (de.fraunhofer.aisec.cpg.graph)1 Node (de.fraunhofer.aisec.cpg.graph.Node)1 NodeBuilder.newRecordDeclaration (de.fraunhofer.aisec.cpg.graph.NodeBuilder.newRecordDeclaration)1