Fix friendly frame parsing bugs.
Fix bug parsing a friendly frame with spaces in the member name.
Fix bug parsing a friendly frame where the location is a data url.
BUG=
R=nweiz@google.com
Review-Url: https://codereview.chromium.org//2739643004 .
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 293538f..53cdd37 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 1.7.2
+* Fix bug parsing a friendly frame with spaces in the member name.
+* Fix bug parsing a friendly frame where the location is a data url.
+
## 1.7.1
* Make `Trace.parse()`, `Chain.parse()`, treat the VM's new causal asynchronous
diff --git a/lib/src/frame.dart b/lib/src/frame.dart
index 8dde788..8599245 100644
--- a/lib/src/frame.dart
+++ b/lib/src/frame.dart
@@ -52,9 +52,11 @@
r'$');
// foo/bar.dart 10:11 Foo._bar
+// foo/bar.dart 10:11 (anonymous function).dart.fn
// http://dartlang.org/foo/bar.dart Foo._bar
+// data:... 10:11 Foo._bar
final _friendlyFrame = new RegExp(
- r'^(\S+)(?: (\d+)(?::(\d+))?)?\s+([^\d]\S*)$');
+ r'^(\S+)(?: (\d+)(?::(\d+))?)?\s+([^\d].*)$');
/// A regular expression that matches asynchronous member names generated by the
/// VM.
@@ -186,7 +188,8 @@
// as "Anonymous function".
return parseLocation(match[2],
match[1].replaceAll("<anonymous>", "<fn>")
- .replaceAll("Anonymous function", "<fn>"));
+ .replaceAll("Anonymous function", "<fn>")
+ .replaceAll("(anonymous function)", "<fn>"));
} else {
// The second form looks like " at LOCATION", and is used for anonymous
// functions.
@@ -249,8 +252,11 @@
throw new FormatException(
"Couldn't parse package:stack_trace stack trace line '$frame'.");
}
-
- var uri = Uri.parse(match[1]);
+ // Fake truncated data urls generated by the friendly stack trace format
+ // cause Uri.parse to throw an exception so we have to special case them.
+ var uri = match[1] == 'data:...'
+ ? new Uri.dataFromString('')
+ : Uri.parse(match[1]);
// If there's no scheme, this is a relative URI. We should interpret it as
// relative to the current working directory.
if (uri.scheme == '') {
diff --git a/pubspec.yaml b/pubspec.yaml
index 4289a6e..dd081ea 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -7,7 +7,7 @@
#
# When the major version is upgraded, you *must* update that version constraint
# in pub to stay in sync with this.
-version: 1.7.1
+version: 1.7.2
author: "Dart Team <misc@dartlang.org>"
homepage: https://github.com/dart-lang/stack_trace
description: >
diff --git a/test/frame_test.dart b/test/frame_test.dart
index 080c8b8..a5f8b23 100644
--- a/test/frame_test.dart
+++ b/test/frame_test.dart
@@ -448,7 +448,7 @@
expect(frame.member, equals('Foo.<fn>.bar'));
});
- test('parses a stack frame with no line correctly', () {
+ test('parses a stack frame with no column correctly', () {
var frame = new Frame.parseFriendly(
"http://dartlang.org/foo/bar.dart 10 Foo.<fn>.bar");
expect(frame.uri, equals(Uri.parse("http://dartlang.org/foo/bar.dart")));
@@ -472,6 +472,45 @@
expectIsUnparsed((text) => new Frame.parseFriendly(text),
'foo/bar.dart 10:11');
});
+
+ test('parses a data url stack frame with no line or column correctly', () {
+ var frame = new Frame.parseFriendly(
+ "data:... main");
+ expect(frame.uri.scheme, equals('data'));
+ expect(frame.line, isNull);
+ expect(frame.column, isNull);
+ expect(frame.member, equals('main'));
+ });
+
+ test('parses a data url stack frame correctly', () {
+ var frame = new Frame.parseFriendly(
+ "data:... 10:11 main");
+ expect(frame.uri.scheme, equals('data'));
+ expect(frame.line, equals(10));
+ expect(frame.column, equals(11));
+ expect(frame.member, equals('main'));
+ });
+
+ test('parses a stack frame with spaces in the member name correctly', () {
+ var frame = new Frame.parseFriendly(
+ "foo/bar.dart 10:11 (anonymous function).dart.fn");
+ expect(frame.uri,
+ equals(path.toUri(path.absolute(path.join('foo', 'bar.dart')))));
+ expect(frame.line, equals(10));
+ expect(frame.column, equals(11));
+ expect(frame.member, equals('(anonymous function).dart.fn'));
+ });
+
+ test('parses a stack frame with spaces in the member name and no line or '
+ 'column correctly', () {
+ var frame = new Frame.parseFriendly(
+ "http://dartlang.org/foo/bar.dart (anonymous function).dart.fn");
+ expect(
+ frame.uri, equals(Uri.parse("http://dartlang.org/foo/bar.dart")));
+ expect(frame.line, isNull);
+ expect(frame.column, isNull);
+ expect(frame.member, equals('(anonymous function).dart.fn'));
+ });
});
test('only considers dart URIs to be core', () {
diff --git a/test/trace_test.dart b/test/trace_test.dart
index 077f1ba..327eff0 100644
--- a/test/trace_test.dart
+++ b/test/trace_test.dart
@@ -72,6 +72,23 @@
equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
expect(trace.frames[2].uri,
equals(Uri.parse("http://pub.dartlang.org/thing.js")));
+
+ trace = new Trace.parse(
+ 'Exception: foo\n'
+ ' bar\n'
+ ' at Foo._bar (http://pub.dartlang.org/stuff.js:42:21)\n'
+ ' at http://pub.dartlang.org/stuff.js:0:2\n'
+ ' at (anonymous function).zip.zap '
+ '(http://pub.dartlang.org/thing.js:1:100)');
+
+ expect(trace.frames[0].uri,
+ equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
+ expect(trace.frames[1].uri,
+ equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
+ expect(trace.frames[1].member, equals("<fn>"));
+ expect(trace.frames[2].uri,
+ equals(Uri.parse("http://pub.dartlang.org/thing.js")));
+ expect(trace.frames[2].member, equals("<fn>.zip.zap"));
});
// JavaScriptCore traces are just like V8, except that it doesn't have a