[wp-trac] [WordPress Trac] #63642: Passing stringy number to _n() can result in a plural when singular is intended
WordPress Trac
noreply at wordpress.org
Tue Jul 1 04:44:35 UTC 2025
#63642: Passing stringy number to _n() can result in a plural when singular is
intended
--------------------------------------+------------------------------
Reporter: dd32 | Owner: (none)
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting Review
Component: I18N | Version: 6.5
Severity: normal | Resolution:
Keywords: has-patch has-unit-tests | Focuses:
--------------------------------------+------------------------------
Changes (by dd32):
* keywords: needs-unit-tests has-patch => has-patch has-unit-tests
Old description:
> Through #59656 a new translation layer was added that replaced the less-
> performant pomo class, for ''some operations''.
>
> WordPress passes numeric strings around quite often when they come from
> database queries, for example, as the return value of `wp_count_posts()`.
>
> This when used with `_n()` can result in an stringy numeric value being
> passed to the `$count` parameter.
>
> Long story short, POMO's [https://github.com/WordPress/wordpress-
> develop/blob/fb4ec6f5b4499208fef7032eb1db63fde8f70a77/src/wp-
> includes/pomo/translations.php#L213-L215
> Translations::translate_plural()] casts `$count` to an integer before
> strict comparisons to `1`, where as [https://github.com/WordPress
> /wordpress-develop/blob/fb4ec6f5b4499208fef7032eb1db63fde8f70a77/src/wp-
> includes/l10n/class-wp-translations.php#L127
> WP_Translations::translate_plural()]'s fallback pluralisation expects
> that it'll only ever be passed an integer and strictly compares that.
>
> This can cause `_n( 'Singular', 'Plural', '1' )` to return `Plural` as `1
> !== '1'` but it depends upon which translation handler the translation
> hits, as it will return `Singular` with a POMO handler, and likely return
> `Singular` if a translation exists via `WP_Translations`.
>
> PR incoming, which casts at the deepest point. Potentially these casts
> should live at a higher level, but this is the status-quo.
New description:
Through #59656 a new translation layer was added that replaced the less-
performant pomo class, for ''some operations''.
WordPress passes numeric strings around quite often when they come from
database queries, for example, as the return value of `wp_count_posts()`.
This when used with `_n()` can result in an stringy numeric value being
passed to the `$count` parameter.
Long story short, POMO's [https://github.com/WordPress/wordpress-
develop/blob/fb4ec6f5b4499208fef7032eb1db63fde8f70a77/src/wp-
includes/pomo/translations.php#L213-L215 Translations::translate_plural()]
casts `$count` to an integer before strict comparisons to `1`, where as
[https://github.com/WordPress/wordpress-
develop/blob/fb4ec6f5b4499208fef7032eb1db63fde8f70a77/src/wp-includes/l10n
/class-wp-translations.php#L127 WP_Translations::translate_plural()]'s
fallback pluralisation expects that it'll only ever be passed an integer
and strictly compares that.
'''This is strictly about the Fallback pluralisation, if the string is
present in the translation file, it works as expected, this is only an
issue if the string is not in the file.'''
This can cause `_n( 'Singular', 'Plural', '1' )` to return `Plural` as `1
!== '1'` but it depends upon which translation handler the translation
hits, as it will return `Singular` with a POMO handler, and likely return
`Singular` if a translation exists via `WP_Translations`.
PR incoming, which casts at the deepest point. Potentially these casts
should live at a higher level, but this is the status-quo.
--
--
Ticket URL: <https://core.trac.wordpress.org/ticket/63642#comment:2>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list