diff --git a/system/Language/Language.php b/system/Language/Language.php index 70d109e2319b..32eee39f2a13 100644 --- a/system/Language/Language.php +++ b/system/Language/Language.php @@ -12,6 +12,7 @@ namespace CodeIgniter\Language; use Config\Services; +use InvalidArgumentException; use MessageFormatter; /** @@ -191,7 +192,14 @@ protected function formatMessage($message, array $args = []) return $message; } - return MessageFormatter::formatMessage($this->locale, $message, $args); + $formatted = MessageFormatter::formatMessage($this->locale, $message, $args); + if ($formatted === false) { + throw new InvalidArgumentException( + lang('Language.invalidMessageFormat', [$message, implode(',', $args)]) + ); + } + + return $formatted; } /** diff --git a/system/Language/en/Language.php b/system/Language/en/Language.php new file mode 100644 index 000000000000..80920b2f16d5 --- /dev/null +++ b/system/Language/en/Language.php @@ -0,0 +1,15 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +// "Language" language settings +return [ + 'invalidMessageFormat' => 'Invalid message format: "{0}", args: "{1}"', +]; diff --git a/tests/system/Language/LanguageTest.php b/tests/system/Language/LanguageTest.php index 34313e8dfac8..5c75a6d9a28f 100644 --- a/tests/system/Language/LanguageTest.php +++ b/tests/system/Language/LanguageTest.php @@ -14,6 +14,7 @@ use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\Mock\MockLanguage; use Config\Services; +use InvalidArgumentException; use MessageFormatter; use Tests\Support\Language\SecondMockLanguage; @@ -126,6 +127,28 @@ public function testGetLineArrayFormatsMessages(): void $this->assertSame(['45 related books.'], $this->lang->getLine('books.bookList', [91 / 2])); } + /** + * @see https://github.com/codeigniter4/shield/issues/851 + */ + public function testGetLineInvalidFormatMessage(): void + { + // No intl extension? then we can't test this - go away.... + if (! class_exists(MessageFormatter::class)) { + $this->markTestSkipped('No intl support.'); + } + + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage( + 'Invalid message format: "تم الكشف عن كلمة المرور {0} بسبب اختراق البيانات وشوهدت {1 ، عدد} مرة في {2} في كلمات المرور المخترقة.", args: "password,hits,wording"' + ); + + $this->lang->setData('Auth', [ + 'errorPasswordPwned' => 'تم الكشف عن كلمة المرور {0} بسبب اختراق البيانات وشوهدت {1 ، عدد} مرة في {2} في كلمات المرور المخترقة.', + ]); + + $this->lang->getLine('Auth.errorPasswordPwned', ['password', 'hits', 'wording']); + } + /** * @see https://github.com/codeigniter4/CodeIgniter4/issues/891 */