diff --git a/packages/flutter/lib/src/services/asset_bundle.dart b/packages/flutter/lib/src/services/asset_bundle.dart index 4227451d8c..f6a933ce97 100644 --- a/packages/flutter/lib/src/services/asset_bundle.dart +++ b/packages/flutter/lib/src/services/asset_bundle.dart @@ -214,7 +214,7 @@ abstract class CachingAssetBundle extends AssetBundle { class PlatformAssetBundle extends CachingAssetBundle { @override Future load(String key) async { - final Uint8List encoded = utf8.encoder.convert(new Uri(path: key).path); + final Uint8List encoded = utf8.encoder.convert(new Uri(path: Uri.encodeFull(key)).path); final ByteData asset = await BinaryMessages.send('flutter/assets', encoded.buffer.asByteData()); if (asset == null) diff --git a/packages/flutter_tools/lib/src/flutter_manifest.dart b/packages/flutter_tools/lib/src/flutter_manifest.dart index 03cd721abd..1731ceba72 100644 --- a/packages/flutter_tools/lib/src/flutter_manifest.dart +++ b/packages/flutter_tools/lib/src/flutter_manifest.dart @@ -59,7 +59,7 @@ class FlutterManifest { } List get assets { - return _flutterDescriptor['assets']?.map(Uri.parse)?.toList() ?? const []; + return _flutterDescriptor['assets']?.map(Uri.encodeFull)?.map(Uri.parse)?.toList() ?? const []; } List _fonts; diff --git a/packages/flutter_tools/test/asset_bundle_package_test.dart b/packages/flutter_tools/test/asset_bundle_package_test.dart index ab7e2a43b8..baf92ea104 100644 --- a/packages/flutter_tools/test/asset_bundle_package_test.dart +++ b/packages/flutter_tools/test/asset_bundle_package_test.dart @@ -69,7 +69,7 @@ $assetsSection for (String packageName in packages) { for (String asset in assets) { - final String entryKey = 'packages/$packageName/$asset'; + final String entryKey = Uri.encodeFull('packages/$packageName/$asset'); expect(bundle.entries.containsKey(entryKey), true); expect( utf8.decode(await bundle.entries[entryKey].contentsAsBytes()), @@ -415,4 +415,29 @@ $assetsSection ); }); }); + + testUsingContext('Asset paths can contain URL reserved characters', () async { + establishFlutterRoot(); + + writePubspecFile('pubspec.yaml', 'test'); + writePackagesFile('test_package:p/p/lib/'); + + final List assets = ['a/foo', 'a/foo[x]']; + writePubspecFile( + 'p/p/pubspec.yaml', + 'test_package', + assets: assets, + ); + + writeAssets('p/p/', assets); + const String expectedAssetManifest = + '{"packages/test_package/a/foo":["packages/test_package/a/foo"],' + '"packages/test_package/a/foo%5Bx%5D":["packages/test_package/a/foo%5Bx%5D"]}'; + + await buildAndVerifyAssets( + assets, + ['test_package'], + expectedAssetManifest, + ); + }); }