Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

GenericData.containsKey() returns true for unset (null) declared fields, violating Map contract

オープン 初心者向け
#2,187 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
84/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
java

調査の方向性

com.google.api.client.util.GenericData.java から始め、DataMap.containsKey と参照されている FieldInfo へのアクセスと併せて containsKey を調べます。ExampleModel の再現を確認し、宣言された null フィールドが存在しない一方で、null ではない宣言済みフィールドと未知のフィールドが期待される Map の動作を維持することを確認します。

索引モデルが issue の本文から書いたものです。

説明

Description

PR #2151 introduced an override for GenericData.containsKey(Object name) that queries classInfo.hasFieldInfo(fieldName). However, ClassInfo.hasFieldInfo checks only whether the @Key field is declared in class reflection metadata, rather than checking whether the field holds a non-null value on the instance.

Impact & Broken Invariants

In GenericData, declared fields with null values are treated as absent from the map:

  1. keySet() / entrySet() Contradiction:
    On new MyData(), containsKey("field") returns true, but get("field") is null, entrySet() has size 0, and keySet().toString() outputs [].
  2. Set.contains vs Iterator Inconsistency:
    Because java.util.AbstractMap.keySet().contains(k) delegates to Map.containsKey(k), model.keySet().contains("field") evaluates to true, while iterating over model.keySet() yields 0 elements.
  3. Client Breakages:
    Code patterns checking for field presence (such as pagination checks like if (response.containsKey("pageToken"))) now evaluate to true even when the server never populated the field.
Reproduction
public class ExampleModel extends GenericData {
  @Key private String optionalField;
}

ExampleModel model = new ExampleModel();

// Prior to 2.2.0:
// model.containsKey("optionalField") == false

// In 2.2.0:
model.containsKey("optionalField"); // returns true!
model.get("optionalField");         // returns null
model.keySet();                     // prints []
model.keySet().contains("optionalField"); // returns true while iterator is empty
Proposed Fix

In com.google.api.client.util.GenericData.java, check whether the declared field value is non-null, matching DataMap.containsKey():

  @Override
  public final boolean containsKey(Object name) {
    if (!(name instanceof String)) {
      return false;
    }
    String fieldName = (String) name;
    FieldInfo fieldInfo = classInfo.getFieldInfo(fieldName);
    if (fieldInfo != null) {
      return fieldInfo.getValue(this) != null;
    }
    if (classInfo.getIgnoreCase()) {
      fieldName = fieldName.toLowerCase(Locale.US);
    }
    return unknownFields.containsKey(fieldName);
  }
主要言語
Java
スター
1.4k
フォーク
474
PR マージ指標
30日以内にマージされた PR はありません

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

googleapis/google-http-java-client のほかの issue

googleapis/google-http-java-client の issue をすべて見る

似ている issue

Java の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。