#60678 closed defect (bug) (fixed)
Definition of WP_Translation_File_MO::MAGIC_MARKER
Reported by: | tmatsuur | Owned by: | swissspidy |
---|---|---|---|
Milestone: | 6.5 | Priority: | normal |
Severity: | normal | Version: | 6.5 |
Component: | I18N | Keywords: | has-patch commit |
Focuses: | Cc: |
Description
Currently some PHP environments may fail to load mo files.
The environment in which this problem occurred:
PHP 7.4.32 (cli) (built: Sep 28 2022 20:48:52) ( ZTS Visual C++ 2017 x86 )
I investigated the cause and found that it was due to the definition of class constants.
const MAGIC_MARKER = 0x950412de;
Dumping this constant:
var_dump( WP_Translation_File_MO::MAGIC_MARKER ); : float(2500072158)
Due to the data type of the constant being "float" instead of "int", the detect_endian_and_validate_file method was returning false when reading the .mo file.
As a temporary measure, the WP_Translation_File_MO class has been changed as follows:
const MAGIC_MARKER = '0x950412de'; : protected function detect_endian_and_validate_file( string $header ) { : if ( (int)hexdec( self::MAGIC_MARKER ) === $big ) { return 'N'; } if ( (int)hexdec( self::MAGIC_MARKER ) === $little ) { return 'V'; }
This way, the mo file can be read and the translated content will be reflected.
I'm sure there are more appropriate ways to correct this, but I hope this helps.
Change History (13)
#1
@
7 months ago
- Milestone changed from Awaiting Review to 6.5
- Owner set to swissspidy
- Status changed from new to reviewing
#4
@
7 months ago
Thanks @swissspidy .
As you pointed out, this constant is also used in the export
method. I had overlooked it.
#5
@
7 months ago
I was a little mistaken. The constant declarations do not seem to need to be changed.
const MAGIC_MARKER = 0x950412de; : protected function detect_endian_and_validate_file( string $header ) { : if ( (int) self::MAGIC_MARKER === $big ) { return 'N'; } if ( (int) self::MAGIC_MARKER === $little ) { return 'V'; }
The above changes solved the problem.
This ticket was mentioned in PR #6216 on WordPress/wordpress-develop by @swissspidy.
7 months ago
#6
- Keywords has-patch added; needs-patch removed
Trac ticket: https://core.trac.wordpress.org/ticket/60678
#7
@
7 months ago
@tmatsuur Thanks!
I just opened https://github.com/WordPress/wordpress-develop/pull/6216 to apply this change. Could you please verify whether that version works for you as well?
I updated the export
method as well in there.
#9
@
7 months ago
The base is WordPress 6.5 Beta 3 and has been replaced with the class-wp-translation-file-mo.php
which has just been modified.
I tried this in a PHP version 7.4.x environment.
PHP 7.4.32 (cli) (built: Sep 28 2022 20:48:52) ( ZTS Visual C++ 2017 x86 )
In this environment, the translated text is displayed correctly.
As an example, "Akismet" in "Installed Plugins" is displayed as follows.
For reference, the above is the case where ja.mo
and admin-ja.mo
exist, but if you generate ja.l10n.php
and admin-ja.l10n.php
, rename ja.mo
and admin-ja.mo
, and switch to not reading, the translated text will still be displayed correctly.
PHP version 8.0.x (64-bit) was also checked in an environment based on WordPress version 6.5 beta 3, with the updated class-wp-translation-file-mo.php
replaced.
The translated text is still reflected and displayed in this environment.
I believe that, from a quick glance, the fix this time has resulted in the expected display in both environments.
#10
@
7 months ago
- Keywords commit added
Awesome, thanks a lot for testing!
Let's get this in for 6.5 RC 1 then. If any more issues arise we can deal with them in follow-up commits.
Thanks for your report!
Looks like a 32 bit vs 64 bit issue, which explains why this wasn't spotted before.
On https://3v4l.org/ you can notice it in the live preview, which is x86. There it will be a float. But as soon as you press
eval();
, it will be an int.The workaround looks reasonable at first glance. Just noting that the magic marker is also used in the
export()
method, so that needs to be checked as well.Another solution can be seen in the
\MO::get_byteorder()
method, where it's simply an integer.