Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[vm] Fix soundness issue when awaiting a user-defined Future
TEST=language/async/await_user_defined_future_soundness_test Issue: #49345 Change-Id: Ieaaa9baace13dad242c770a710d4d459e135af81 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/250222 Reviewed-by: Slava Egorov <vegorov@google.com> Commit-Queue: Alexander Markov <alexmarkov@google.com>
- Loading branch information
1 parent
4308eb3
commit abedfaf
Showing
5 changed files
with
171 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 51 additions & 0 deletions
51
tests/language/async/await_user_defined_future_soundness_test.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file | ||
// for details. All rights reserved. Use of this source code is governed by a | ||
// BSD-style license that can be found in the LICENSE file. | ||
|
||
// Verifies that user-define Future cannot provide a value of incorrect | ||
This comment has been minimized.
Sorry, something went wrong. |
||
// type by casting 'onValue' callback. | ||
// Regression test for https://github.com/dart-lang/sdk/issues/49345. | ||
|
||
import 'dart:async'; | ||
|
||
import "package:expect/expect.dart"; | ||
|
||
import 'dart:async'; | ||
|
||
bool checkpoint1 = false; | ||
bool checkpoint2 = false; | ||
bool checkpoint3 = false; | ||
bool checkpoint4 = false; | ||
|
||
Future<void> foo(Future<String> f) async { | ||
checkpoint1 = true; | ||
final String result = await f; | ||
checkpoint3 = true; | ||
print(result.runtimeType); | ||
} | ||
|
||
class F implements Future<String> { | ||
Future<R> then<R>(FutureOr<R> Function(String) onValue, {Function? onError}) { | ||
checkpoint2 = true; | ||
final result = (onValue as FutureOr<R> Function(dynamic))(10); | ||
This comment has been minimized.
Sorry, something went wrong.
lrhn
Member
|
||
checkpoint4 = true; | ||
return Future.value(result); | ||
} | ||
|
||
@override | ||
dynamic noSuchMethod(i) => throw 'Unimplimented'; | ||
This comment has been minimized.
Sorry, something went wrong. |
||
} | ||
|
||
void main() { | ||
bool seenError = false; | ||
runZoned(() { | ||
foo(F()); | ||
}, onError: (e, st) { | ||
seenError = true; | ||
}); | ||
Expect.isTrue(checkpoint1); | ||
Expect.isTrue(checkpoint2); | ||
Expect.isFalse(checkpoint3); | ||
Expect.isFalse(checkpoint4); | ||
Expect.isTrue(seenError); | ||
} |
53 changes: 53 additions & 0 deletions
53
tests/language_2/async/await_user_defined_future_soundness_test.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file | ||
// for details. All rights reserved. Use of this source code is governed by a | ||
// BSD-style license that can be found in the LICENSE file. | ||
|
||
// @dart = 2.9 | ||
|
||
// Verifies that user-define Future cannot provide a value of incorrect | ||
// type by casting 'onValue' callback. | ||
// Regression test for https://github.com/dart-lang/sdk/issues/49345. | ||
|
||
import 'dart:async'; | ||
|
||
import "package:expect/expect.dart"; | ||
|
||
import 'dart:async'; | ||
|
||
bool checkpoint1 = false; | ||
bool checkpoint2 = false; | ||
bool checkpoint3 = false; | ||
bool checkpoint4 = false; | ||
|
||
Future<void> foo(Future<String> f) async { | ||
checkpoint1 = true; | ||
final String result = await f; | ||
checkpoint3 = true; | ||
print(result.runtimeType); | ||
} | ||
|
||
class F implements Future<String> { | ||
Future<R> then<R>(FutureOr<R> Function(String) onValue, {Function onError}) { | ||
checkpoint2 = true; | ||
final result = (onValue as FutureOr<R> Function(dynamic))(10); | ||
checkpoint4 = true; | ||
return Future.value(result); | ||
} | ||
|
||
@override | ||
dynamic noSuchMethod(i) => throw 'Unimplimented'; | ||
} | ||
|
||
void main() { | ||
bool seenError = false; | ||
runZoned(() { | ||
foo(F()); | ||
}, onError: (e, st) { | ||
seenError = true; | ||
}); | ||
Expect.isTrue(checkpoint1); | ||
Expect.isTrue(checkpoint2); | ||
Expect.isFalse(checkpoint3); | ||
Expect.isFalse(checkpoint4); | ||
Expect.isTrue(seenError); | ||
} |
user-define -> a user-defined