Skip to content

Commit 750a83b

Browse files
nshahancommit-bot@chromium.org
authored andcommitted
[dartdevc] Fix crash when source files contain non-UTF8 characters
* Treat the assertion condition offset as a character offset in the file. * Allow unrecognized characters to be replaced by a placeholder character. This is unrelated to the fix but is just a precautionary measure. Fixed: 39271 Change-Id: I4871ea41d3a46d26ecac5047265a1dbc1c889350 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/124602 Reviewed-by: Vijay Menon <[email protected]> Commit-Queue: Nicholas Shahan <[email protected]>
1 parent d45c3d1 commit 750a83b

File tree

4 files changed

+60
-26
lines changed

4 files changed

+60
-26
lines changed

pkg/dev_compiler/lib/src/kernel/compiler.dart

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3268,10 +3268,11 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
32683268
jsCondition = runtimeCall('test(#)', [jsCondition]);
32693269
}
32703270

3271-
var encodedConditionSource = node
3272-
.enclosingComponent.uriToSource[node.location.file].source
3273-
.sublist(node.conditionStartOffset, node.conditionEndOffset);
3274-
var conditionSource = utf8.decode(encodedConditionSource);
3271+
var encodedSource =
3272+
node.enclosingComponent.uriToSource[node.location.file].source;
3273+
var source = utf8.decode(encodedSource, allowMalformed: true);
3274+
var conditionSource =
3275+
source.substring(node.conditionStartOffset, node.conditionEndOffset);
32753276
var location = _toSourceLocation(node.conditionStartOffset);
32763277
return js.statement(' if (!#) #.assertFailed(#, #, #, #, #);', [
32773278
jsCondition,
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import "utils.dart";
6+
7+
void main() {
8+
try {
9+
assert(false, "failure message");
10+
} on AssertionError catch (error) {
11+
var message = error.toString();
12+
expectStringContains('Assertion failed:', message);
13+
expectStringContains('assertion_failure_message_test.dart:9:12', message);
14+
expectStringContains('false', message);
15+
expectStringContains('failure message', message);
16+
}
17+
18+
// 失 All offsets and source code extractions should still be correct after
19+
// non-UTF8 characters. See: https://github.com/dart-lang/sdk/issues/39271
20+
try {
21+
assert(false, "after a non-UTF8 character");
22+
} on AssertionError catch (error) {
23+
var message = error.toString();
24+
expectStringContains('Assertion failed:', message);
25+
expectStringContains('assertion_failure_message_test.dart:21:12', message);
26+
expectStringContains('false', message);
27+
expectStringContains('after a non-UTF8 character', message);
28+
}
29+
}

tests/compiler/dartdevc_native/no_such_method_errors_test.dart

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,7 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5-
import "package:expect/expect.dart";
6-
7-
_expectInErrorMessage(String expected, String actual) {
8-
Expect.isTrue(
9-
actual.contains(expected),
10-
'Error message should contain "$expected", '
11-
'but was ${actual.toString()}.');
12-
}
5+
import "utils.dart";
136

147
class A {
158
int x = 42;
@@ -33,8 +26,8 @@ void main() {
3326
instanceOfA();
3427
} on NoSuchMethodError catch (error) {
3528
var message = error.toString();
36-
_expectInErrorMessage("NoSuchMethodError: 'call'", message);
37-
_expectInErrorMessage("Receiver: Instance of 'A'", message);
29+
expectStringContains("NoSuchMethodError: 'call'", message);
30+
expectStringContains("Receiver: Instance of 'A'", message);
3831
}
3932

4033
dynamic tearOff = instanceOfA.arity1;
@@ -43,52 +36,52 @@ void main() {
4336
tearOff(1, 2);
4437
} on NoSuchMethodError catch (error) {
4538
var message = error.toString();
46-
_expectInErrorMessage("NoSuchMethodError: 'bound arity1'", message);
47-
_expectInErrorMessage("too many arguments", message);
39+
expectStringContains("NoSuchMethodError: 'bound arity1'", message);
40+
expectStringContains("too many arguments", message);
4841
}
4942

5043
// Dynamic call of a class method with too few arguments.
5144
try {
5245
tearOff();
5346
} on NoSuchMethodError catch (error) {
5447
var message = error.toString();
55-
_expectInErrorMessage("NoSuchMethodError: 'bound arity1'", message);
56-
_expectInErrorMessage("too few arguments", message);
48+
expectStringContains("NoSuchMethodError: 'bound arity1'", message);
49+
expectStringContains("too few arguments", message);
5750
}
5851

5952
// Dynamic call of a top level funciton with too many arguments.
6053
try {
6154
dynamicFunction(1, 2);
6255
} on NoSuchMethodError catch (error) {
6356
var message = error.toString();
64-
_expectInErrorMessage("NoSuchMethodError: 'arity1'", message);
65-
_expectInErrorMessage("too many arguments", message);
57+
expectStringContains("NoSuchMethodError: 'arity1'", message);
58+
expectStringContains("too many arguments", message);
6659
}
6760

6861
// Dynamic call of a top level funciton with too few arguments.
6962
try {
7063
dynamicFunction();
7164
} on NoSuchMethodError catch (error) {
7265
var message = error.toString();
73-
_expectInErrorMessage("NoSuchMethodError: 'arity1'", message);
74-
_expectInErrorMessage("too few arguments", message);
66+
expectStringContains("NoSuchMethodError: 'arity1'", message);
67+
expectStringContains("too few arguments", message);
7568
}
7669

7770
// Function.apply() with too many arguments.
7871
try {
7972
Function.apply(dynamicFunction, [1, 2]);
8073
} on NoSuchMethodError catch (error) {
8174
var message = error.toString();
82-
_expectInErrorMessage("NoSuchMethodError: 'arity1'", message);
83-
_expectInErrorMessage("too many arguments", message);
75+
expectStringContains("NoSuchMethodError: 'arity1'", message);
76+
expectStringContains("too many arguments", message);
8477
}
8578

8679
// Function.apply() with too few arguments.
8780
try {
8881
Function.apply(dynamicFunction, []);
8982
} on NoSuchMethodError catch (error) {
9083
var message = error.toString();
91-
_expectInErrorMessage("NoSuchMethodError: 'arity1'", message);
92-
_expectInErrorMessage("too few arguments", message);
84+
expectStringContains("NoSuchMethodError: 'arity1'", message);
85+
expectStringContains("too few arguments", message);
9386
}
9487
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import "package:expect/expect.dart";
6+
7+
/// Expects that [expected] appears as a substring in [actual].
8+
expectStringContains(String expected, String actual) {
9+
Expect.isTrue(actual.contains(expected),
10+
'Failure: "$expected" should appear in: "$actual".');
11+
}

0 commit comments

Comments
 (0)