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 this is not your bug, you can add a comment by following this link.
If this is your bug, but 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

Add a Patch

Pull Requests

Add a Pull Request

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: Wed Apr 24 00:01:32 2024 UTC