Unverified Commit 52ddc9d1 authored by Jenn Magder's avatar Jenn Magder Committed by GitHub

Handle null values during yaml metadata parsing validation (#104022)

parent b8b3b09a
...@@ -51,11 +51,7 @@ FlutterProjectType? stringToProjectType(String value) { ...@@ -51,11 +51,7 @@ FlutterProjectType? stringToProjectType(String value) {
} }
/// Verifies the expected yaml keys are present in the file. /// Verifies the expected yaml keys are present in the file.
bool _validateMetadataMap(Object? yamlRoot, Map<String, Type> validations, Logger logger) { bool _validateMetadataMap(YamlMap map, Map<String, Type> validations, Logger logger) {
if (yamlRoot != null && yamlRoot is! YamlMap) {
return false;
}
final YamlMap map = yamlRoot! as YamlMap;
bool isValid = true; bool isValid = true;
for (final MapEntry<String, Object> entry in validations.entries) { for (final MapEntry<String, Object> entry in validations.entries) {
if (!map.keys.contains(entry.key)) { if (!map.keys.contains(entry.key)) {
...@@ -63,9 +59,10 @@ FlutterProjectType? stringToProjectType(String value) { ...@@ -63,9 +59,10 @@ FlutterProjectType? stringToProjectType(String value) {
logger.printTrace('The key `${entry.key}` was not found'); logger.printTrace('The key `${entry.key}` was not found');
break; break;
} }
if (map[entry.key] != null && (map[entry.key] as Object).runtimeType != entry.value) { final Object? metadataValue = map[entry.key];
if (metadataValue.runtimeType != entry.value) {
isValid = false; isValid = false;
logger.printTrace('The value of key `${entry.key}` in .metadata was expected to be ${entry.value} but was ${(map[entry.key] as Object).runtimeType}'); logger.printTrace('The value of key `${entry.key}` in .metadata was expected to be ${entry.value} but was ${metadataValue.runtimeType}');
break; break;
} }
} }
...@@ -89,28 +86,26 @@ class FlutterProjectMetadata { ...@@ -89,28 +86,26 @@ class FlutterProjectMetadata {
} on YamlException { } on YamlException {
// Handled in _validate below. // Handled in _validate below.
} }
if (yamlRoot == null || yamlRoot is! YamlMap) { if (yamlRoot is! YamlMap) {
_logger.printTrace('.metadata file at ${_metadataFile.path} was empty or malformed.'); _logger.printTrace('.metadata file at ${_metadataFile.path} was empty or malformed.');
return; return;
} }
final YamlMap map = yamlRoot;
if (_validateMetadataMap(yamlRoot, <String, Type>{'version': YamlMap}, _logger)) { if (_validateMetadataMap(yamlRoot, <String, Type>{'version': YamlMap}, _logger)) {
final Object? versionYaml = map['version']; final Object? versionYamlMap = yamlRoot['version'];
if (_validateMetadataMap(versionYaml, <String, Type>{ if (versionYamlMap is YamlMap && _validateMetadataMap(versionYamlMap, <String, Type>{
'revision': String, 'revision': String,
'channel': String, 'channel': String,
}, _logger)) { }, _logger)) {
final YamlMap versionYamlMap = versionYaml! as YamlMap;
_versionRevision = versionYamlMap['revision'] as String?; _versionRevision = versionYamlMap['revision'] as String?;
_versionChannel = versionYamlMap['channel'] as String?; _versionChannel = versionYamlMap['channel'] as String?;
} }
} }
if (_validateMetadataMap(yamlRoot, <String, Type>{'project_type': String}, _logger)) { if (_validateMetadataMap(yamlRoot, <String, Type>{'project_type': String}, _logger)) {
_projectType = stringToProjectType(map['project_type'] as String); _projectType = stringToProjectType(yamlRoot['project_type'] as String);
} }
final Object? migrationYaml = map['migration']; final Object? migrationYaml = yamlRoot['migration'];
if (migrationYaml != null && migrationYaml is YamlMap) { if (migrationYaml is YamlMap) {
migrateConfig.parseYaml(map['migration'] as YamlMap, _logger); migrateConfig.parseYaml(migrationYaml, _logger);
} }
} }
...@@ -289,13 +284,12 @@ migration: ...@@ -289,13 +284,12 @@ migration:
final Object? platformsYaml = map['platforms']; final Object? platformsYaml = map['platforms'];
if (_validateMetadataMap(map, <String, Type>{'platforms': YamlList}, logger)) { if (_validateMetadataMap(map, <String, Type>{'platforms': YamlList}, logger)) {
if (platformsYaml is YamlList && platformsYaml.isNotEmpty) { if (platformsYaml is YamlList && platformsYaml.isNotEmpty) {
for (final Object? platform in platformsYaml) { for (final YamlMap platformYamlMap in platformsYaml.whereType<YamlMap>()) {
if (_validateMetadataMap(platform, <String, Type>{ if (_validateMetadataMap(platformYamlMap, <String, Type>{
'platform': String, 'platform': String,
'create_revision': String, 'create_revision': String,
'base_revision': String, 'base_revision': String,
}, logger)) { }, logger)) {
final YamlMap platformYamlMap = platform! as YamlMap;
final SupportedPlatform platformString = SupportedPlatform.values.firstWhere( final SupportedPlatform platformString = SupportedPlatform.values.firstWhere(
(SupportedPlatform val) => val.toString() == 'SupportedPlatform.${platformYamlMap['platform'] as String}' (SupportedPlatform val) => val.toString() == 'SupportedPlatform.${platformYamlMap['platform'] as String}'
); );
......
...@@ -50,6 +50,21 @@ void main() { ...@@ -50,6 +50,21 @@ void main() {
expect(logger.traceText, contains('.metadata file at .metadata was empty or malformed.')); expect(logger.traceText, contains('.metadata file at .metadata was empty or malformed.'));
}); });
testWithoutContext('projectType is populated when version is null', () {
metadataFile
..createSync()
..writeAsStringSync('''
version:
project_type: plugin
''');
final FlutterProjectMetadata projectMetadata = FlutterProjectMetadata(metadataFile, logger);
expect(projectMetadata.projectType, FlutterProjectType.plugin);
expect(projectMetadata.versionChannel, isNull);
expect(projectMetadata.versionRevision, isNull);
expect(logger.traceText, contains('The value of key `version` in .metadata was expected to be YamlMap but was Null'));
});
testWithoutContext('projectType is populated when version is malformed', () { testWithoutContext('projectType is populated when version is malformed', () {
metadataFile metadataFile
..createSync() ..createSync()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment