GenericData.containsKey() returns true for unset (null) declared fields, violating Map contract
まだ誰も着手していません。
評価
- 難易度
- 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:
keySet()/entrySet()Contradiction:
Onnew MyData(),containsKey("field")returnstrue, butget("field")isnull,entrySet()has size0, andkeySet().toString()outputs[].Set.containsvsIteratorInconsistency:
Becausejava.util.AbstractMap.keySet().contains(k)delegates toMap.containsKey(k),model.keySet().contains("field")evaluates totrue, while iterating overmodel.keySet()yields0elements.- Client Breakages:
Code patterns checking for field presence (such as pagination checks likeif (response.containsKey("pageToken"))) now evaluate totrueeven 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 はありません
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
googleapis/google-http-java-client のほかの issue
-
Core: Validate header names and values to prevent CRLF injection対応中かも @insaf021 が 65 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
-
Core: XmlPullParser processes external DTD entities (XXE) — disable FEATURE_PROCESS_DOCDECL in Xml#createParser()対応中かも @insaf021 が 65 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
-
Core: LowLevelHttpResponse not disconnected when HttpResponse construction throws RuntimeException対応中かも @insaf021 が 66 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
-
type: cleanup
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
-
org.apache.http.conn.ssl.SSLSocketFactory is deprecated再び着手できるかも このイシューのプルリクエストはマージされずにクローズされました。 オープンpriority: p2 type: cleanup
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
googleapis/google-http-java-client の issue をすべて見る
似ている issue
-
難易度 1/5 1〜3時間 初心者へのやさしさ 88/100
-
[Bug] The shared instance selector's placeholder and no-match text ignore the display language対応中かも このイシューにリンクされたプルリクエストがオープン中、またはマージ済みです。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 90/100
apache/rocketmq-dashboard#5561 ·
メンテナーはふだん 3 日以内に返信
-
enhancement
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
HMCL-dev/HMCL#6934 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
test(setup): GitHub configuration tests fail when the temp path is long enough for YAML foldingオープンbug good first issue help wanted priority medium size S
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
martin-francois/symphony-trello#776 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
Console.printHexオープンgood first issue kernel
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
JackFurton/who-would-build-a-kernel-in-java#33 · コメント 2 件 ·
メンテナーはふだん 1 日以内に返信