Support data URIs in StandardFileSystem.
Closes https://github.com/dart-lang/sdk/issues/31594
Change-Id: I8dad1429d91cc5934b37cb0be60d1e4039293b71
Reviewed-on: https://dart-review.googlesource.com/33461
Reviewed-by: Peter von der Ahé <ahe@google.com>
diff --git a/pkg/front_end/lib/src/api_prototype/standard_file_system.dart b/pkg/front_end/lib/src/api_prototype/standard_file_system.dart
index fbe8155..c64cfd8 100644
--- a/pkg/front_end/lib/src/api_prototype/standard_file_system.dart
+++ b/pkg/front_end/lib/src/api_prototype/standard_file_system.dart
@@ -9,8 +9,10 @@
import 'file_system.dart';
-/// Concrete implementation of [FileSystem] which performs its operations using
-/// I/O.
+/// Concrete implementation of [FileSystem] handling standard URI schemes.
+///
+/// file: URIs are handled using file I/O.
+/// data: URIs return their data contents.
///
/// Not intended to be implemented or extended by clients.
class StandardFileSystem implements FileSystem {
@@ -20,28 +22,31 @@
@override
FileSystemEntity entityForUri(Uri uri) {
- if (uri.scheme != 'file' && uri.scheme != '') {
+ if (uri.scheme == 'file' || uri.scheme == '') {
+ // TODO(askesc): Empty schemes should have been handled elsewhere.
+ return new _IoFileSystemEntity(Uri.base.resolveUri(uri));
+ } else if (uri.scheme == 'data') {
+ return new _DataFileSystemEntity(Uri.base.resolveUri(uri));
+ } else {
throw new FileSystemException(
- uri, 'StandardFileSystem only supports file:* URIs');
+ uri, 'StandardFileSystem only supports file:* and data:* URIs');
}
- return new _StandardFileSystemEntity(Uri.base.resolveUri(uri));
}
}
-/// Concrete implementation of [FileSystemEntity] for use by
-/// [StandardFileSystem].
-class _StandardFileSystemEntity implements FileSystemEntity {
+/// Concrete implementation of [FileSystemEntity] for file: URIs.
+class _IoFileSystemEntity implements FileSystemEntity {
@override
final Uri uri;
- _StandardFileSystemEntity(this.uri);
+ _IoFileSystemEntity(this.uri);
@override
int get hashCode => uri.hashCode;
@override
bool operator ==(Object other) =>
- other is _StandardFileSystemEntity && other.uri == uri;
+ other is _IoFileSystemEntity && other.uri == uri;
@override
Future<bool> exists() async {
@@ -82,3 +87,33 @@
return new FileSystemException(uri, message);
}
}
+
+/// Concrete implementation of [FileSystemEntity] for data: URIs.
+class _DataFileSystemEntity implements FileSystemEntity {
+ @override
+ final Uri uri;
+
+ _DataFileSystemEntity(this.uri);
+
+ @override
+ int get hashCode => uri.hashCode;
+
+ @override
+ bool operator ==(Object other) =>
+ other is _DataFileSystemEntity && other.uri == uri;
+
+ @override
+ Future<bool> exists() async {
+ return true;
+ }
+
+ @override
+ Future<List<int>> readAsBytes() async {
+ return uri.data.contentAsBytes();
+ }
+
+ @override
+ Future<String> readAsString() async {
+ return uri.data.contentAsString();
+ }
+}
diff --git a/pkg/front_end/lib/src/testing/hybrid_file_system.dart b/pkg/front_end/lib/src/testing/hybrid_file_system.dart
index 8c0828c..ba2a2fe 100644
--- a/pkg/front_end/lib/src/testing/hybrid_file_system.dart
+++ b/pkg/front_end/lib/src/testing/hybrid_file_system.dart
@@ -37,7 +37,8 @@
Future<FileSystemEntity> get delegate async {
if (_delegate != null) return _delegate;
FileSystemEntity entity = _fs.memory.entityForUri(uri);
- if (uri.scheme != 'file' || await entity.exists()) {
+ if ((uri.scheme != 'file' && uri.scheme != 'data') ||
+ await entity.exists()) {
_delegate = entity;
return _delegate;
}
diff --git a/pkg/front_end/test/standard_file_system_test.dart b/pkg/front_end/test/standard_file_system_test.dart
index 80ffe8e..e78a3c7 100644
--- a/pkg/front_end/test/standard_file_system_test.dart
+++ b/pkg/front_end/test/standard_file_system_test.dart
@@ -8,6 +8,7 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io' as io;
+import 'dart:math' show Random;
import 'package:front_end/src/api_prototype/file_system.dart';
import 'package:front_end/src/api_prototype/standard_file_system.dart';
@@ -20,6 +21,7 @@
defineReflectiveTests(StandardFileSystemTest);
defineReflectiveTests(FileTest);
defineReflectiveTests(DirectoryTest);
+ defineReflectiveTests(DataTest);
});
}
@@ -248,3 +250,23 @@
}
}
}
+
+@reflectiveTest
+class DataTest {
+ test_Data_URIs() async {
+ String string = "<{[DART]}>";
+ Uri string_uri = new Uri.dataFromString(string, base64: false);
+ Uri string_uri_base64 = new Uri.dataFromString(string, base64: true);
+
+ Random random = new Random(123);
+ List<int> bytes = new List.generate(1000, (index) => random.nextInt(256));
+ Uri bytes_uri = new Uri.dataFromBytes(bytes, percentEncoded: true);
+ Uri bytes_uri_base64 = new Uri.dataFromBytes(bytes, percentEncoded: false);
+
+ StandardFileSystem fs = StandardFileSystem.instance;
+ expect(string, await fs.entityForUri(string_uri).readAsString());
+ expect(string, await fs.entityForUri(string_uri_base64).readAsString());
+ expect(bytes, await fs.entityForUri(bytes_uri).readAsBytes());
+ expect(bytes, await fs.entityForUri(bytes_uri_base64).readAsBytes());
+ }
+}
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index fc087b9a..d2ec7b8 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -296,12 +296,7 @@
cc/SourceReport_PossibleBreakpoints_Simple: Fail
cc/StackTraceFormat: Fail
cc/UseDartApi: Fail
-dart/data_uri_import_test/base64: CompileTimeError
-dart/data_uri_import_test/nocharset: CompileTimeError
-dart/data_uri_import_test/nomime: CompileTimeError
-dart/data_uri_import_test/percentencoded: Fail
-dart/data_uri_import_test/wrongmime: CompileTimeError
-dart/data_uri_spawn_test: RuntimeError
+dart/data_uri_import_test/utf16: MissingRuntimeError # UTF-16 data URIs work in dartk
dart/redirection_type_shuffling_test/00: Crash
dart/redirection_type_shuffling_test/none: Crash
dart/spawn_shutdown_test: SkipSlow
@@ -350,12 +345,7 @@
dart/truncating_ints_test: Skip # This test cannot be run in dartkp/legacy mode (gen_kernel does not pass --limit-ints-to-64-bits in legacy mode).
[ $compiler == dartkp && ($runtime == dart_precompiled || $runtime == vm) ]
-dart/data_uri_import_test/base64: CompileTimeError
-dart/data_uri_import_test/nocharset: CompileTimeError
-dart/data_uri_import_test/nomime: CompileTimeError
-dart/data_uri_import_test/percentencoded: CompileTimeError
-dart/data_uri_import_test/wrongmime: CompileTimeError
-dart/data_uri_spawn_test: RuntimeError
+dart/data_uri_import_test/utf16: MissingRuntimeError # UTF-16 data URIs work in dartk
dart/redirection_type_shuffling_test: SkipByDesign # Includes dart:mirrors.
dart/spawn_shutdown_test: SkipSlow