Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@Danilospano00
Copy link

Status

READY

Breaking Changes

NO

Description

The actual version has a bug in mapEquals() that causes false positives when comparing maps with:

  • Same length
  • Different keys
  • At least one null value

🔴 The Bug Explained

Buggy Code

bool mapEquals(Map<Object?, Object?> a, Map<Object?, Object?> b) {
  if (identical(a, b)) return true;
  if (a.length != b.length) return false;
  for (final key in a.keys) {
    if (!objectsEquals(a[key], b[key])) return false;  // ❌ BUG HERE
  }
  return true;
}

The Problem

When you access b[key] and the key doesn't exist in map b, Dart returns null:

final map1 = {'a': 1, 'b': null};
final map2 = {'a': 1, 'c': null};  // 'b' doesn't exist

// Without containsKey:
map1['b']  // = null (explicit)
map2['b']  // = null (missing key!)
objectsEquals(null, null)  // = true ✅
// Result: mapEquals returns TRUE ❌ BUG!

Example with the BUG: User Permissions

class User extends Equatable {
  final Map<String, bool> permissions;
  
  @override
  List<Object> get props => [permissions];
}

final admin = User(permissions: {'read': true, 'write': null});
final guest = User(permissions: {'read': true, 'admin': null});

admin == guest;  // Returns TRUE 
// Admin and guest are treated as equal!

✅ Fix

added !b.containsKey(key)

bool mapEquals(Map<Object?, Object?> a, Map<Object?, Object?> b) {
  if (identical(a, b)) return true;
  if (a.length != b.length) return false;
  for (final key in a.keys) {
    if (!b.containsKey(key) || !objectsEquals(a[key], b[key])) return false;
  }
  return true;
}

…s and null values, add corresponding tests, and document the bug fix.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant