Skip to content

Commit 3e368a7

Browse files
committed
fix(yaml): Fix stack overflow in deepHashCode for self-referential lists
Replaces #2362 Replace a nested call to `deepHashCode` with `deepHashCodeInner` to fix a stack overflow with self referential iterables.
1 parent 7f986ea commit 3e368a7

4 files changed

Lines changed: 22 additions & 2 deletions

File tree

pkgs/yaml/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 3.1.4-wip
2+
3+
* Fix a stack overflow in `deepHashCode` when handling self-referential lists.
4+
15
## 3.1.3
26

37
* Require Dart 3.4

pkgs/yaml/lib/src/equality.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,8 @@ int deepHashCode(Object? obj) {
113113
return equality.hash(value.keys.map(deepHashCodeInner)) ^
114114
equality.hash(value.values.map(deepHashCodeInner));
115115
} else if (value is Iterable) {
116-
return const IterableEquality<Object?>().hash(value.map(deepHashCode));
116+
return const IterableEquality<Object?>()
117+
.hash(value.map(deepHashCodeInner));
117118
} else if (value is YamlScalar) {
118119
return (value.value as Object?).hashCode;
119120
} else {

pkgs/yaml/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: yaml
2-
version: 3.1.3
2+
version: 3.1.4-wip
33
description: A parser for YAML, a human-friendly data serialization standard
44
repository: https://github.com/dart-lang/tools/tree/main/pkgs/yaml
55
issue_tracker: https://github.com/dart-lang/tools/labels/package%3Ayaml

pkgs/yaml/test/yaml_test.dart

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,6 +1118,21 @@ void main() {
11181118
expect(anchorList, same(aliasList));
11191119
});
11201120

1121+
test('self-referential list does not cause stack overflow in deepHashCode',
1122+
() {
1123+
var doc = loadYaml(cleanUpLiteral('''
1124+
? &anchor [*anchor]
1125+
: value'''));
1126+
expect(doc, isNotNull);
1127+
var key = doc.keys.first;
1128+
expect(key, isA<YamlList>());
1129+
expect(key[0], same(key));
1130+
1131+
var map = deepEqualsMap();
1132+
map[key] = 'value';
1133+
expect(map[key], 'value');
1134+
});
1135+
11211136
test('[Example 7.1]', () {
11221137
expectYamlLoads({
11231138
'First occurrence': 'Foo',

0 commit comments

Comments
 (0)