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: 2019-08-04 08:44 UTC
From: bjorsch at wikimedia dot org Assigned:
Status: Verified Package: *General Issues
PHP Version: 7.3Git-2019-06-05 (Git) OS: Debian sid
Private report: No CVE-ID: None
View Add Comment Developer Edit
Anyone can comment on a bug. Have a simpler test case? Does it work for you on a different platform? Let us know!
Just going to say 'Me too!'? Don't clutter the database with that please — but make sure to vote on the bug!
Your email address:
MUST BE VALID
Solve the problem:
4 + 28 = ?
Subscribe to this entry?

 
 [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
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Wed Dec 11 17:01:25 2019 UTC