Hacktoberfest 2026: as issues que os mantenedores marcaram para outubro, abertas e boas para iniciantes. Ver issues do Hacktoberfest

Call chain analysis exception

Aberta
#19,637 1 comentário 0 reações 0 responsáveis Ver no GitHub

Ninguém assumiu esta issue ainda.

Avaliação

Dificuldade
4/5
Tempo estimado
3-5 dias
Facilidade para iniciantes
30/100
Tipo de issue
Bug
Clareza
Precisa de esclarecimento
Status de atividade
Estagnada
Stack de tecnologia
java
Domínio
devtools, security

Direção de pesquisa

Comece pelos dois exemplos de DataFlow::ConfigSig na issue e compare o caminho bem-sucedido com a configuração isAdditionalFlowStep que falha. Rastreie como ReadObjectSource, GetHostAddressSource, MethodCall e RefType são usados e, em seguida, verifique o comportamento em relação à cadeia de chamadas de HashMap e URL mostrada. Está concluído quando o comportamento do caminho estiver explicado e a configuração encontrar o caminho pretendido ou documentar por que não consegue encontrá-lo.

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

Descrição

question

Hello, I'm not familiar with isAdditionalFlowStep, so there might be some issues with the rule I wrote. Could you please help me take a look?

public class HashMap<K,V> extends AbstractMap<K,V>
        // 4、key
        implements Map<K,V>, Cloneable, Serializable {
    static final int hash(Object key) {
        int h;
        // 5、key.hashCode()
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

    //1、s
    private void readObject(java.io.ObjectInputStream s)
            throws IOException, ClassNotFoundException {
        s.defaultReadObject();
        reinitialize();
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new InvalidObjectException("Illegal load factor: " +
                    loadFactor);
        s.readInt();           
        int mappings = s.readInt(); 
        if (mappings < 0)
            throw new InvalidObjectException("Illegal mappings count: " +
                    mappings);
        else if (mappings > 0) {
            float lf = Math.min(Math.max(0.25f, loadFactor), 4.0f);
            float fc = (float)mappings / lf + 1.0f;
            int cap = ((fc < DEFAULT_INITIAL_CAPACITY) ?
                    DEFAULT_INITIAL_CAPACITY :
                    (fc >= MAXIMUM_CAPACITY) ?
                            MAXIMUM_CAPACITY :
                            tableSizeFor((int)fc));
            float ft = (float)cap * lf;
            threshold = ((cap < MAXIMUM_CAPACITY && ft < MAXIMUM_CAPACITY) ?
                    (int)ft : Integer.MAX_VALUE);
            @SuppressWarnings({"rawtypes","unchecked"})
            Node<K,V>[] tab = (Node<K,V>[])new Node[cap];
            table = tab;

            for (int i = 0; i < mappings; i++) {
                @SuppressWarnings("unchecked")
                // 2、keu
                K key = (K) s.readObject();
                @SuppressWarnings("unchecked")
                V value = (V) s.readObject();
                // 3、hash(key)
                putVal(hash(key), key, value, false, false);
            }
        }
    }
}


public final class URL implements java.io.Serializable {

    transient URLStreamHandler handler;

    // 6
    public synchronized int hashCode() {
        if (hashCode != -1)
            return hashCode;

        // 7、handler.hashCode(this)
        hashCode = handler.hashCode(this);
        return hashCode;
    }
}


public abstract class URLStreamHandler {

    // 8、u
    protected int hashCode(URL u) {
        int h = 0;

        String protocol = u.getProtocol();
        if (protocol != null)
            h += protocol.hashCode();

        // 9、getHostAddress(u);
        InetAddress addr = getHostAddress(u);
        if (addr != null) {
            h += addr.hashCode();
        } else {
            String host = u.getHost();
            if (host != null)
                h += host.toLowerCase().hashCode();
        }

        String file = u.getFile();
        if (file != null)
            h += file.hashCode();

        if (u.getPort() == -1)
            h += getDefaultPort();
        else
            h += u.getPort();

        String ref = u.getRef();
        if (ref != null)
            h += ref.hashCode();

        return h;
    }
}

The path query from HashMap.readObject to HashMap.hash->h = key.hashCode() has been successfully completed.

class ReadObjectSource extends DataFlow::Node {
  ReadObjectSource() {
    exists(Method m |
       m.getDeclaringType().getASupertype() instanceof TypeSerializable and
       m.hasName("readObject") and
       m.getDeclaringType().hasQualifiedName("java.util", "HashMap") and
       this.asParameter() = m.getParameter(0)
    )
  }
}

class GetHostAddressSource extends DataFlow::Node {
  GetHostAddressSource() {
  exists(MethodCall call |
      call.getMethod().hasName("hashCode") and
      call.getMethod().getDeclaringType().hasQualifiedName("java.lang", "Object") and
      this.asExpr() = call.getQualifier()
    )
  }
}

module LiteralToURLConfig implements DataFlow::ConfigSig {
   predicate isSource(DataFlow::Node source) {
    source instanceof ReadObjectSource
  }

  predicate isSink(DataFlow::Node sink) {
    sink instanceof GetHostAddressSource
  }
}

However, the path from HashMap.readObject to HashMap.hash->h = key.hashCode() cannot be found as shown below, and it directly jumps to the hashCode method in other classes.

class ReadObjectSource extends DataFlow::Node {
  ReadObjectSource() {
    exists(Method m |
       m.getDeclaringType().getASupertype() instanceof TypeSerializable and
       m.hasName("readObject") and
       m.getDeclaringType().hasQualifiedName("java.util", "HashMap") and
       this.asParameter() = m.getParameter(0)
    )
  }
}

class GetHostAddressSource extends DataFlow::Node {
  GetHostAddressSource() {
  exists(MethodCall call |
      call.getMethod().hasName("getHostAddress") and
      this.asExpr() = call.getArgument(0)
    )
  }
}

module LiteralToURLConfig implements DataFlow::ConfigSig {
   predicate isSource(DataFlow::Node source) {
    source instanceof ReadObjectSource
  }

  predicate isSink(DataFlow::Node sink) {
    sink instanceof GetHostAddressSource
  }

   predicate isAdditionalFlowStep(DataFlow::Node source, DataFlow::Node sink){
    source instanceof ReadObjectSource and
    exists(
      MethodCall call,
      RefType rt
    |
      source instanceof ReadObjectSource and 
      sink.asExpr() = call.getQualifier() and 
      rt = sink.getType().(RefType)
    )
   }
}

Linguagem predominante
CodeQL
Estrelas
10.1k
Forks
2.1k
Merge médio
2d 16h
PRs com merge (30d)
143

Guia de contribuição

Abrir o guia de contribuição

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 DevTools

Receba novas issues na sua caixa de entrada

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