Shorten the script URI in stack traces for URI encoded scripts.

Closes https://github.com/dart-lang/sdk/issues/34091

Bug: https://github.com/dart-lang/sdk/issues/34091
Change-Id: I1dbf0c8ff282f617f3503265f7e3a24ab56dd57f
Reviewed-on: https://dart-review.googlesource.com/c/87421
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Liam Appelbe <liama@google.com>
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index e08de19..dae8d6b 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -21065,6 +21065,14 @@
       String::Handle(zone, function.QualifiedUserVisibleName());
   const String& url = String::Handle(
       zone, script.IsNull() ? String::New("Kernel") : script.url());
+
+  // If the URI starts with "data:application/dart;" this is a URI encoded
+  // script so we shouldn't print the entire URI because it could be very long.
+  const char* url_string = url.ToCString();
+  if (strstr(url_string, "data:application/dart;") == url_string) {
+    url_string = "<data:application/dart>";
+  }
+
   intptr_t line = -1;
   intptr_t column = -1;
   if (FLAG_precompiled_mode) {
@@ -21079,7 +21087,6 @@
     }
   }
 
-  const char* url_string = url.ToCString();
   if (column >= 0) {
     buffer->Printf("#%-6" Pd " %s (%s:%" Pd ":%" Pd ")\n", frame_index,
                    function_name.ToCString(), url_string, line, column);
diff --git a/tests/language_2/issue_34091.dart b/tests/language_2/issue_34091.dart
new file mode 100644
index 0000000..5756024
--- /dev/null
+++ b/tests/language_2/issue_34091.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2018, 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.
+
+// Tests that stack traces from data URIs don't contain the entire URI, and
+// instead just have the substitute file name: <data:application/dart>
+
+import "dart:isolate";
+import "package:expect/expect.dart";
+import 'dart:async';
+
+void main() {
+  // This data URI encodes:
+  /*
+    import "dart:isolate";
+    void main(_, p){
+      try {
+        throw("Hello World");
+      } catch (e, s) {
+        p.send("$e\n$s");
+      }
+    }
+  */
+  final uri = Uri.parse(
+      "data:application/dart;charset=utf8,import%20%22dart%3Aisolate%22%3Bvoi" +
+          "d%20main(_%2Cp)%7Btry%7Bthrow(%22Hello%20World%22)%3B%7Dcatch(e%2C" +
+          "%20s)%7Bp.send(%22%24e%5Cn%24s%22)%3B%7D%7D");
+  ReceivePort port = new ReceivePort();
+  Isolate.spawnUri(uri, [], port.sendPort);
+  port.listen((trace) {
+    // Test that the trace contains the exception message.
+    Expect.isTrue(trace.contains("Hello World"));
+
+    // Test that the trace contains data URI substitute.
+    Expect.isTrue(trace.contains("<data:application/dart>"));
+
+    // Test that the trace doesn't contain any leftover URL encoded junk.
+    Expect.isFalse(trace.contains("%20"));
+
+    port.close();
+  });
+}