LinkedCaseInsensitiveMap.keySet().remove returns false after removing a null-valued entry

Đang mở Phù hợp với người mới
#37,470 3 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

  • #37478 của @zsewasdsdsd — đã đóng, không merge

Đánh giá

Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
78/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
java, spring
Lĩnh vực
backend

Hướng nghiên cứu

Lỗi nằm ở lớp nội KeySet trong LinkedCaseInsensitiveMap.java của spring-core. Tại đó, remove(o) quyết định kết quả boolean dựa trên việc Map.remove có trả về null hay không, nên một entry có giá trị null sẽ báo false. Hãy chạy đoạn Repro.java trong issue với spring-core để xác nhận dòng đầu và dòng thứ ba đều in ra false. Công việc hoàn thành khi keySet().remove và keySet().removeAll trả về true với một key có mặt và giá trị null, và các test hiện có của LinkedCaseInsensitiveMap vẫn chạy thành công.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

status: waiting-for-triage
Affected versions

Verified with the published spring-core 7.0.9 and 6.2.19 artifacts on JDK 21. The same result was reproduced with the affected classes compiled from main at 85a532dce455655aec8fd5a301b37c6c5ceda5bb, with the remaining dependencies supplied by spring-core 7.0.9. This was a focused reproduction, not a full Gradle build.

Problem

LinkedCaseInsensitiveMap supports null values. When a key is mapped to null, keySet().remove(key) removes the entry but returns false. This contradicts the Set removal contract, and also makes keySet().removeAll(...) report no change when it chooses its remove-based path.

Callers relying on the boolean result to detect a change receive the wrong result even though the map was modified.

Minimal reproduction

Save as Repro.java:

import java.util.Locale;
import java.util.Set;
import org.springframework.util.LinkedCaseInsensitiveMap;

public class Repro {
    public static void main(String[] args) {
        var map = new LinkedCaseInsensitiveMap<String>(Locale.ROOT);
        map.put("key", null);
        System.out.println(map.keySet().remove("key"));
        System.out.println(map.isEmpty());

        map.put("key", null);
        map.put("other", "value");
        System.out.println(map.keySet().removeAll(Set.of("key")));
        System.out.println(map.containsKey("key"));
        System.out.println(map.size());
    }
}

Run on Java 17 or later:

curl -fLO https://repo.maven.apache.org/maven2/org/springframework/spring-core/7.0.9/spring-core-7.0.9.jar
java -cp spring-core-7.0.9.jar Repro.java

Actual output:

false
true
false
false
1

Expected: the first and third lines should be true, because both operations removed an existing key. The remaining lines are correct.

Cause

LinkedCaseInsensitiveMap.KeySet.remove returns LinkedCaseInsensitiveMap.this.remove(o) != null. A null return from Map.remove cannot distinguish an absent key from a present null-valued mapping.

The Java Set.remove contract requires true when the set contained the element and it was removed.

Related reports checked

#22821 / #23644 addressed stale internal key registrations after collection-view removals. This report concerns the boolean return value after a successful removal; the internal key registration is correctly cleared in this reproduction. #37351 concerns computeIfAbsent registrations and is also a separate case. Searches for LinkedCaseInsensitiveMap keySet and LinkedCaseInsensitiveMap null remove did not reveal a direct duplicate.

Ngôn ngữ chính
Java
Star
60.3k
Fork
38.7k
Merge trung bình
1 ngày 14 giờ
Pull request đã merge (30 ngày)
34

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của spring-projects/spring-framework

Tất cả issue của spring-projects/spring-framework

Issue tương tự

Thêm issue về Java

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.