php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #78113 Number formatting does not properly handle locales with multibyte decimal_point
Submitted: 2019-06-05 17:38 UTC Modified: 2020-10-19 12:51 UTC
From: bjorsch at wikimedia dot org Assigned: cmb (profile)
Status: Closed Package: *General Issues
PHP Version: 7.3Git-2019-06-05 (Git) OS: Debian sid
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: bjorsch at wikimedia dot org
New email:
PHP Version: OS:

 

 [2019-06-05 17:38 UTC] bjorsch at wikimedia dot org
Description:
------------
PHP's support for locales in its number formatting assumes that 'decimal_point' will be a single char. This is not always the case, however. On my system, for example, locale "ps_AF" has it as "٫" as represented in UTF-8 encoding.[1] PHP uses only the first byte of that, producing "Ù" in the console output.

This seems to affect at least string casts and the printf() family of functions. 

I note though that number_format() is not affected, it works fine when multibyte values are passed for the separators.

I reproduce this in PHP 7.0.31, 7.1.20, 7.2.11, 7.3.4, and current git master (5f3ee3afe7).


[1]: Note this is not really a Unicode issue though. If the locale had decimal_point set to the string "dec" for some reason, PHP would similarly use only "d".

Test script:
---------------
<?php

echo PHP_VERSION . "\n";

$n = 123456.789;

// If this locale doesn't exist on your system or doesn't have a non-ASCII
// 'decimal_point', change it to one that does.
var_dump( setlocale( LC_NUMERIC, 'ps_AF' ) );

var_dump( localeconv() );

echo "$n\n";
printf( "%.15g\n", $n );
echo number_format( $n, 3, localeconv()['decimal_point'], localeconv()['thousands_sep'] ) . "\n";


Expected result:
----------------
8.0.0-dev
string(5) "ps_AF"
array(18) {
  ["decimal_point"]=>
  string(2) "٫"
  ["thousands_sep"]=>
  string(2) "٬"
  ["int_curr_symbol"]=>
  string(0) ""
  ["currency_symbol"]=>
  string(0) ""
  ["mon_decimal_point"]=>
  string(0) ""
  ["mon_thousands_sep"]=>
  string(0) ""
  ["positive_sign"]=>
  string(0) ""
  ["negative_sign"]=>
  string(0) ""
  ["int_frac_digits"]=>
  int(127)
  ["frac_digits"]=>
  int(127)
  ["p_cs_precedes"]=>
  int(127)
  ["p_sep_by_space"]=>
  int(127)
  ["n_cs_precedes"]=>
  int(127)
  ["n_sep_by_space"]=>
  int(127)
  ["p_sign_posn"]=>
  int(127)
  ["n_sign_posn"]=>
  int(127)
  ["grouping"]=>
  array(1) {
    [0]=>
    int(3)
  }
  ["mon_grouping"]=>
  array(0) {
  }
}
123456٫789
123456٫789
123٬456٫789

Actual result:
--------------
8.0.0-dev
string(5) "ps_AF"
array(18) {
  ["decimal_point"]=>
  string(2) "٫"
  ["thousands_sep"]=>
  string(2) "٬"
  ["int_curr_symbol"]=>
  string(0) ""
  ["currency_symbol"]=>
  string(0) ""
  ["mon_decimal_point"]=>
  string(0) ""
  ["mon_thousands_sep"]=>
  string(0) ""
  ["positive_sign"]=>
  string(0) ""
  ["negative_sign"]=>
  string(0) ""
  ["int_frac_digits"]=>
  int(127)
  ["frac_digits"]=>
  int(127)
  ["p_cs_precedes"]=>
  int(127)
  ["p_sep_by_space"]=>
  int(127)
  ["n_cs_precedes"]=>
  int(127)
  ["n_sep_by_space"]=>
  int(127)
  ["p_sign_posn"]=>
  int(127)
  ["n_sign_posn"]=>
  int(127)
  ["grouping"]=>
  array(1) {
    [0]=>
    int(3)
  }
  ["mon_grouping"]=>
  array(0) {
  }
}
123456Ù789
123456Ù789
123٬456٫789

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-08-04 08:44 UTC] cmb@php.net
-Status: Open +Status: Verified
 [2020-10-19 12:51 UTC] cmb@php.net
-Status: Verified +Status: Closed -Assigned To: +Assigned To: cmb
 [2020-10-19 12:51 UTC] cmb@php.net
Well, as of PHP 8.0.0, float to string conversion is no longer
depending on the current locale[1].  I don't think it makes sense
to fix this long standing issue for the stable versions, so I'm
closing this ticket.

[1] <https://wiki.php.net/rfc/locale_independent_float_to_string>
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Dec 10 08:01:27 2024 UTC