Handle empty entry in asset list and add more explicit validation (#41735)
diff --git a/packages/flutter_tools/lib/src/flutter_manifest.dart b/packages/flutter_tools/lib/src/flutter_manifest.dart index 247a21d..5334b5b 100644 --- a/packages/flutter_tools/lib/src/flutter_manifest.dart +++ b/packages/flutter_tools/lib/src/flutter_manifest.dart
@@ -186,16 +186,27 @@ : fontList.map<Map<String, dynamic>>(castStringKeyedMap).toList(); } - List<Uri> get assets { + List<Uri> get assets => _assets ??= _computeAssets(); + List<Uri> _assets; + List<Uri> _computeAssets() { final List<dynamic> assets = _flutterDescriptor['assets']; if (assets == null) { return const <Uri>[]; } - return assets - .cast<String>() - .map<String>(Uri.encodeFull) - ?.map<Uri>(Uri.parse) - ?.toList(); + final List<Uri> results = <Uri>[]; + for (Object asset in assets) { + if (asset is! String || asset == null || asset == '') { + printError('Asset manifest contains a null or empty uri.'); + continue; + } + final String stringAsset = asset; + try { + results.add(Uri.parse(Uri.encodeFull(stringAsset))); + } on FormatException { + printError('Asset manifest contains invalid uri: $asset.'); + } + } + return results; } List<Font> _fonts;
diff --git a/packages/flutter_tools/test/general.shard/flutter_manifest_test.dart b/packages/flutter_tools/test/general.shard/flutter_manifest_test.dart index ef3c910..8432487 100644 --- a/packages/flutter_tools/test/general.shard/flutter_manifest_test.dart +++ b/packages/flutter_tools/test/general.shard/flutter_manifest_test.dart
@@ -572,6 +572,26 @@ expect(flutterManifest, null); expect(logger.errorText, contains('Expected a map.')); }); + + testUsingContext('Does not crash on empty entry', () async { + final BufferLogger logger = context.get<Logger>(); + const String manifest = ''' +name: test +dependencies: + flutter: + sdk: flutter +flutter: + uses-material-design: true + assets: + - lib/gallery/example_code.dart + - +'''; + final FlutterManifest flutterManifest = FlutterManifest.createFromString(manifest); + final List<Uri> assets = flutterManifest.assets; + + expect(logger.errorText, contains('Asset manifest contains a null or empty uri.')); + expect(assets.length, 1); + }); }); group('FlutterManifest with MemoryFileSystem', () {