github / codeql

CodeQL: the libraries and queries that power security researchers around the world, as well as code scanning in GitHub Advanced Security
https://codeql.github.com
MIT License
7.53k stars 1.5k forks source link

Java: Record components (and their annotations) are not extracted #7727

Open Marcono1234 opened 2 years ago

Marcono1234 commented 2 years ago

The components of a Record class are currently not modeled by CodeQL, and their annotations are not extracted. Therefore it is not possible to test for annotations which only use ElementType.RECORD_COMPONENT, or for annotations with ElementType.METHOD which only exist in source but not in the class file because the corresponding accessor method is overridden.

The backing private field as well as the implicit accessor method are extracted.

Example:

import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

record RecordTest(
    @RecordComponentAnnotation
    int i
) {
    @Retention(RUNTIME)
    @Target(ElementType.RECORD_COMPONENT)
    @interface RecordComponentAnnotation { }
}

The following query does not find any usage of @RecordComponentAnnotation, and does not have any element modeling the Record component as result:

import java

from Top t
where t.getLocation().getFile().getBaseName().matches("RecordTest%")
select t, t.getLocation().getStartLine(), t.getPrimaryQlClasses()

Interestingly CodeQL reports a FieldDeclaration at the location of the component. This issue might be solvable by modeling the component using the internal field (pretending the field is also the component), but this can cause inaccuracies for annotations, e.g.:

smowton commented 2 years ago

Thanks for the report, we'll triage this and add it to our Java extractor to-do list.