java/non-final-call-in-constructor: a call made inside a lambda in the constructor is not reported

Aberta
#22,970 0 comentários 0 reações 0 responsáveis Ver no GitHub

Mantenedores costumam responder em até 1 dia

Ninguém assumiu esta issue ainda.

Avaliação

Dificuldade
4/5
Tempo estimado
3-5 dias
Facilidade para iniciantes
45/100
Tipo de issue
Bug
Clareza
Claramente especificada
Status de atividade
Ativa
Stack de tecnologia
java
Domínio
security

Direção de pesquisa

The report points at the unqualifiedCallToNonAbstractMethod predicate, which requires the call's enclosing callable to be the constructor (result.getEnclosingCallable() = c), so a call inside a lambda is missed. Start from the query java/non-final-call-in-constructor and the two seed files, CtorSeed.java and CtorVariant.java, and run the query on each database to confirm the gap. Done means the lambda case is reported at line 6 of CtorVariant.java while the existing results on CtorSeed.java stay the same.

Escrita pelo modelo de indexação a partir do texto da issue.

Descrição

Description of the issue

The query reports toString() in the constructor of CtorSeed.Senior: Junior overrides it, the override reads name, and name is only assigned after super() returns, so new Junior() throws. Move the call into a lambda that the constructor runs right away (CtorVariant) and nothing is reported, though the call still happens during construction with the same effect.

Probably unqualifiedCallToNonAbstractMethod, which requires the call's enclosing callable to be the constructor (result.getEnclosingCallable() = c). Inside the lambda the enclosing callable is the lambda's own method.

Query: java/non-final-call-in-constructor (codeql/java-queries 1.1.10)

CodeQL CLI: 2.27.2

Code samples

seed/CtorSeed.java:

public class CtorSeed {

    public static class Senior {
        public Senior() {
            toString();                        // overridden in Junior, reads a field not yet set
        }
        public String toString() {
            return "Senior";
        }
    }

    public static class Junior extends Senior {
        private String name;
        public Junior() {
            super();
            name = "Junior";
        }
        public String toString() {
            return name.toUpperCase();         // NullPointerException when called from Senior()
        }
    }
}

variant/CtorVariant.java:

public class CtorVariant {

    public static class Senior {
        public Senior() {
            Runnable r = () -> {
                toString();                    // the same call, inside a lambda run at once; not reported
            };
            r.run();
        }
        public String toString() {
            return "Senior";
        }
    }

    public static class Junior extends Senior {
        private String name;
        public Junior() {
            super();
            name = "Junior";
        }
        public String toString() {
            return name.toUpperCase();
        }
    }
}

How to reproduce

codeql database create db --language=java --build-mode=none \
    --source-root=<one directory> --overwrite
codeql database analyze db \
    codeql/java-queries:codeql-suites/java-security-and-quality.qls \
    --format=csv --output=out.csv
# one database per directory

Expected result

"Non-final method invocation in constructor" on the toString() call inside the lambda in CtorVariant.java (line 6), as on CtorSeed.java (line 5).

Output of the commands above:

### CodeQL 2.27.2  query: java/non-final-call-in-constructor
### suite: java-security-and-quality.qls, --build-mode=none, per-file isolated databases
### extraction JDK: openjdk version "21.0.11" 2026-04-21 LTS

--- SEED -- expected: query fires (seed/)
"Non-final method invocation in constructor","If a constructor calls a method that is overridden in a subclass

--- VARIANT -- expected: query fires, actual: not reported (the bug) (variant/)
    (query reported nothing)
Linguagem predominante
CodeQL
Estrelas
10.3k
Forks
2.1k
Merge médio
1d 22h
PRs com merge (30d)
126

Preparar o ambiente

Abrir no Codespaces

Inicia o contêiner de desenvolvimento do projeto no navegador, com a sua própria conta do GitHub.

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Mais de github/codeql

Todas as issues de github/codeql

Issues semelhantes

Mais issues de Security

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.