Be more resilient to bad data from VM (#18132)

Fixes https://github.com/flutter/flutter/issues/14517
Or at least, fixes the crash part of that.
This commit is contained in:
Ian Hickson
2018-06-04 19:12:55 -07:00
committed by GitHub
parent e396cc79ea
commit 6be81ebf9b
2 changed files with 88 additions and 4 deletions

View File

@@ -412,7 +412,24 @@ class HotRunner extends ResidentRunner {
/// Prints errors if [printErrors] is [true].
static bool validateReloadReport(Map<String, dynamic> reloadReport,
{ bool printErrors: true }) {
if (reloadReport['type'] != 'ReloadReport') {
if (reloadReport == null) {
if (printErrors)
printError('Hot reload did not receive reload report.');
return false;
}
if (!(reloadReport['type'] == 'ReloadReport' &&
(reloadReport['success'] == true ||
(reloadReport['success'] == false &&
(reloadReport['details'] is Map<String, dynamic> &&
reloadReport['details']['notices'] is List<dynamic> &&
reloadReport['details']['notices'].isNotEmpty &&
reloadReport['details']['notices'].every(
(dynamic item) => item is Map<String, dynamic> && item['message'] is String
)
)
)
)
)) {
if (printErrors)
printError('Hot reload received invalid response: $reloadReport');
return false;

View File

@@ -11,9 +11,76 @@ void main() {
group('validateReloadReport', () {
testUsingContext('invalid', () async {
expect(HotRunner.validateReloadReport(<String, dynamic>{}), false);
expect(HotRunner.validateReloadReport(
<String, dynamic>{'type': 'ReloadReport', 'success': true, 'details': <String, dynamic>{}}),
true);
expect(HotRunner.validateReloadReport(<String, dynamic>{
'type': 'ReloadReport',
'success': false,
'details': <String, dynamic>{},
}), false);
expect(HotRunner.validateReloadReport(<String, dynamic>{
'type': 'ReloadReport',
'success': false,
'details': <String, dynamic>{
'notices': <Map<String, dynamic>>[
],
},
}), false);
expect(HotRunner.validateReloadReport(<String, dynamic>{
'type': 'ReloadReport',
'success': false,
'details': <String, dynamic>{
'notices': <String, dynamic>{
'message': 'error',
},
},
}), false);
expect(HotRunner.validateReloadReport(<String, dynamic>{
'type': 'ReloadReport',
'success': false,
'details': <String, dynamic>{
'notices': <Map<String, dynamic>>[],
},
}), false);
expect(HotRunner.validateReloadReport(<String, dynamic>{
'type': 'ReloadReport',
'success': false,
'details': <String, dynamic>{
'notices': <Map<String, dynamic>>[
<String, dynamic>{ 'message': false, }
],
},
}), false);
expect(HotRunner.validateReloadReport(<String, dynamic>{
'type': 'ReloadReport',
'success': false,
'details': <String, dynamic>{
'notices': <Map<String, dynamic>>[
<String, dynamic>{ 'message': <String>['error'], },
],
},
}), false);
expect(HotRunner.validateReloadReport(<String, dynamic>{
'type': 'ReloadReport',
'success': false,
'details': <String, dynamic>{
'notices': <Map<String, dynamic>>[
<String, dynamic>{ 'message': 'error', },
<String, dynamic>{ 'message': <String>['error'], },
],
},
}), false);
expect(HotRunner.validateReloadReport(<String, dynamic>{
'type': 'ReloadReport',
'success': false,
'details': <String, dynamic>{
'notices': <Map<String, dynamic>>[
<String, dynamic>{ 'message': 'error', },
],
},
}), false);
expect(HotRunner.validateReloadReport(<String, dynamic>{
'type': 'ReloadReport',
'success': true,
}), true);
});
});
}