From 94da724868a795d201288dc6f5efdd60f92eef00 Mon Sep 17 00:00:00 2001 From: Christopher Fujino Date: Fri, 15 Jul 2022 11:56:09 -0700 Subject: [PATCH] [flutter_tools] fix RangeError in gen-l10n by checking for empty string (#107604) --- .../lib/src/localizations/gen_l10n.dart | 3 ++ .../lib/src/localizations/gen_l10n_types.dart | 3 ++ .../generate_localizations_test.dart | 36 +++++++++++++++++-- 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/packages/flutter_tools/lib/src/localizations/gen_l10n.dart b/packages/flutter_tools/lib/src/localizations/gen_l10n.dart index ea3a659751..b073d26fdd 100644 --- a/packages/flutter_tools/lib/src/localizations/gen_l10n.dart +++ b/packages/flutter_tools/lib/src/localizations/gen_l10n.dart @@ -1050,6 +1050,9 @@ class LocalizationsGenerator { } static bool _isValidGetterAndMethodName(String name) { + if (name.isEmpty) { + return false; + } // Public Dart method name must not start with an underscore if (name[0] == '_') { return false; diff --git a/packages/flutter_tools/lib/src/localizations/gen_l10n_types.dart b/packages/flutter_tools/lib/src/localizations/gen_l10n_types.dart index 314e7c35f7..076abcc4d5 100644 --- a/packages/flutter_tools/lib/src/localizations/gen_l10n_types.dart +++ b/packages/flutter_tools/lib/src/localizations/gen_l10n_types.dart @@ -124,6 +124,9 @@ class L10nException implements Exception { L10nException(this.message); final String message; + + @override + String toString() => message; } // One optional named parameter to be used by a NumberFormat. diff --git a/packages/flutter_tools/test/general.shard/generate_localizations_test.dart b/packages/flutter_tools/test/general.shard/generate_localizations_test.dart index c3a0f6ae3d..8516df6410 100644 --- a/packages/flutter_tools/test/general.shard/generate_localizations_test.dart +++ b/packages/flutter_tools/test/general.shard/generate_localizations_test.dart @@ -992,9 +992,7 @@ class AppLocalizationsEn extends AppLocalizations { }); testWithoutContext( - 'throws an error attempting to add preferred locales ' - 'when there is no corresponding arb file for that ' - 'locale', + 'throws an error attempting to add preferred locales when there is no corresponding arb file for that locale', () { final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n') ..createSync(recursive: true); @@ -1161,6 +1159,38 @@ class AppLocalizationsEn extends AppLocalizations { )), ); }); + + testWithoutContext('throws when an empty string is used as a key', () { + const String arbFileStringWithEmptyResourceId = ''' +{ + "market": "MARKET", + "": { + "description": "This key is invalid" + } +}'''; + + final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n') + ..createSync(recursive: true); + l10nDirectory.childFile('app_en.arb') + .writeAsStringSync(arbFileStringWithEmptyResourceId); + + expect( + () => LocalizationsGenerator( + fileSystem: fs, + inputPathString: defaultL10nPathString, + outputPathString: defaultL10nPathString, + templateArbFileName: 'app_en.arb', + outputFileString: defaultOutputFileString, + classNameString: defaultClassNameString, + ).loadResources(), + throwsA(isA().having( + (L10nException e) => e.message, + 'message', + contains('Invalid ARB resource name ""'), + )), + ); + }); + testWithoutContext('throws when the same locale is detected more than once', () { const String secondMessageArbFileString = ''' {