Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions packages/govuk-frontend/src/govuk/i18n.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
* @param {{ [key: string]: unknown }} [options] - Any options passed with the translation string, e.g: for string interpolation.
* @returns {string} The appropriate translation string.
* @throws {Error} Lookup key required
* @throws {Error} Options required for `${}` placeholders
* @throws {Error} Options required for `%{}` placeholders
*/
t(lookupKey, options) {
if (!lookupKey) {
Expand All @@ -58,9 +58,8 @@
}

if (typeof translation === 'string') {
// Check for ${} placeholders in the translation string
// eslint-disable-next-line @typescript-eslint/prefer-regexp-exec
if (translation.match(/%{(.\S+)}/)) {
// Check for %{} placeholders in the translation string
if (/%{(\S+)}/.test(translation)) {

Check failure

Code scanning / CodeQL

Polynomial regular expression used on uncontrolled data High

This
regular expression
that depends on
library input
may run slow on strings starting with '%{' and with many repetitions of '%{!'.
This
regular expression
that depends on
library input
may run slow on strings starting with '%{' and with many repetitions of '%{!'.
This
regular expression
that depends on
library input
may run slow on strings starting with '%{' and with many repetitions of '%{!'.
This
regular expression
that depends on
library input
may run slow on strings starting with '%{' and with many repetitions of '%{!'.
if (!options) {
throw new Error(
'i18n: cannot replace placeholders in string if no option data provided'
Expand Down Expand Up @@ -92,46 +91,46 @@
? new Intl.NumberFormat(this.locale)
: undefined

return translationString.replace(
/%{(.\S+)}/g,
/%{(\S+)}/g,

/**
* Replace translation string placeholders
*
* @internal
* @param {string} placeholderWithBraces - Placeholder with braces
* @param {string} placeholderKey - Placeholder key
* @returns {string} Placeholder value
*/
function (placeholderWithBraces, placeholderKey) {
if (Object.prototype.hasOwnProperty.call(options, placeholderKey)) {
const placeholderValue = options[placeholderKey]

// If a user has passed `false` as the value for the placeholder
// treat it as though the value should not be displayed
if (
placeholderValue === false ||
(typeof placeholderValue !== 'number' &&
typeof placeholderValue !== 'string')
) {
return ''
}

// If the placeholder's value is a number, localise the number formatting
if (typeof placeholderValue === 'number') {
return formatter
? formatter.format(placeholderValue)
: `${placeholderValue}`
}

return placeholderValue
}

throw new Error(
`i18n: no data found to replace ${placeholderWithBraces} placeholder in string`
)
}
)

Check failure

Code scanning / CodeQL

Polynomial regular expression used on uncontrolled data High

This
regular expression
that depends on
library input
may run slow on strings starting with '%{' and with many repetitions of '%{!'.
This
regular expression
that depends on
library input
may run slow on strings starting with '%{' and with many repetitions of '%{!'.
This
regular expression
that depends on
library input
may run slow on strings starting with '%{' and with many repetitions of '%{!'.
This
regular expression
that depends on
library input
may run slow on strings starting with '%{' and with many repetitions of '%{!'.
}

/**
Expand Down