php / php-src

The PHP Interpreter
https://www.php.net
Other
37.98k stars 7.73k forks source link

IntlDateFormatter Throws Memory Allocation Error with Forced Arabic Numbering System #13434

Closed jimbo2150 closed 7 months ago

jimbo2150 commented 7 months ago

Description

The following code:

<?php

$formatter = new IntlDateFormatter(
    'ar_AE@numbers=latn',
    IntlDateFormatter::FULL,
    IntlDateFormatter::FULL,
    'Europe/Berlin'
);

echo 'ar_AE@numbers=latn: ' . $formatter->format(new DateTime('2021-12-31 23:59:59'));
echo PHP_EOL;

$formatter = new IntlDateFormatter(
    'ar_AE@numbers=arabic',
    IntlDateFormatter::FULL,
    IntlDateFormatter::FULL,
    'Europe/Berlin'
);

echo 'ar_AE@numbers=arabic: ' . $formatter->format(new DateTime('2021-12-31 23:59:59'));
echo PHP_EOL;

$formatter = new IntlDateFormatter(
    'ar-u-nu-arabic',
    IntlDateFormatter::FULL,
    IntlDateFormatter::FULL,
    'Europe/Berlin'
);

echo 'ar-u-nu-arabic : ' . $formatter->format(new DateTime('2021-12-31 23:59:59'));
echo PHP_EOL;

$formatter = new IntlDateFormatter(
    'ar_QA',
    IntlDateFormatter::FULL,
    IntlDateFormatter::FULL,
    'Europe/Berlin'
);

echo 'ar_QA: ' . $formatter->format(new DateTime('2021-12-31 23:59:59'));
echo PHP_EOL;

$formatter = new IntlDateFormatter(
    'ar_SA',
    IntlDateFormatter::FULL,
    IntlDateFormatter::FULL,
    'Europe/Berlin'
);

echo 'ar_SA: ' . $formatter->format(new DateTime('2021-12-31 23:59:59'));
echo PHP_EOL;

Resulted in this output:

ar_AE@numbers=latn: الجمعة، 31 ديسمبر، 2021 11:59:59 م توقيت وسط أوروبا الرسمي

Fatal error: Uncaught IntlException: datefmt_create: date formatter creation failed: U_MEMORY_ALLOCATION_ERROR in /srv/www/htdocs/intl/DateFormatter/arabic-date-numbers.php:13 Stack trace: #0 /srv/www/htdocs/intl/DateFormatter/arabic-date-numbers.php(13): IntlDateFormatter->__construct() #1 {main} thrown in /srv/www/htdocs/intl/DateFormatter/arabic-date-numbers.php on line 13

But I expected this output instead:

ar_AE@numbers=latn: الجمعة، 31 ديسمبر، 2021 11:59:59 م توقيت وسط أوروبا الرسمي
ar_AE@numbers=arabic: السبت، ١ يناير ٢٠٢٢ في ١٢:٥٩:٥٩ ص توقيت وسط أوروبا الرسمي
ar-u-nu-arabic: السبت، ١ يناير ٢٠٢٢ في ١٢:٥٩:٥٩ ص توقيت وسط أوروبا الرسمي
ar_QA: السبت، ١ يناير ٢٠٢٢ في ١٢:٥٩:٥٩ ص توقيت وسط أوروبا الرسمي
ar_SA: السبت، ١ يناير ٢٠٢٢ م في ١٢:٥٩:٥٩ ص توقيت وسط أوروبا الرسمي

If I use other numbering systems, it works without error:

ar_AE@numbers=latn: السبت، 1 يناير 2022 في 12:59:59 ص توقيت وسط أوروبا الرسمي
ar_AE@numbers=thai: السبت، ๑ يناير ๒๐๒๒ في ๑๒:๕๙:๕๙ ص توقيت وسط أوروبا الرسمي
ar-u-nu-roman: السبت، I يناير MMXXII في XII:LIX:LIX ص توقيت وسط أوروبا الرسمي
ar_QA: السبت، ١ يناير ٢٠٢٢ في ١٢:٥٩:٥٩ ص توقيت وسط أوروبا الرسمي
ar_SA: السبت، ١ يناير ٢٠٢٢ م في ١٢:٥٩:٥٩ ص توقيت وسط أوروبا الرسمي

3V4L also showing the error in all supported PHP versions: https://3v4l.org/JPFB9

PHP Version

PHP 8.2.15

Operating System

OpenSUSE Tumbleweed

devnexen commented 7 months ago

At first glance, PHP does nothing wrong nor fancy, it is hitting this code path :

if(timeStyle != UDAT_PATTERN) {
        if(locale == 0) {
            fmt = DateFormat::createDateTimeInstance((DateFormat::EStyle)dateStyle,
                (DateFormat::EStyle)timeStyle);
        }
        else {
            **fmt = DateFormat::createDateTimeInstance((DateFormat::EStyle)dateStyle,
                (DateFormat::EStyle)timeStyle,
                Locale(locale));**
        }
    }

where it gets a null pointer with the aforementioned locale. I ll see what the icu4c folks are going to say, keep you posted.

hormus commented 7 months ago

Is ar_AE@numbers=arab not ar_AE@numbers=arabic. Numberformat https://unicode-org.github.io/icu/userguide/locale/

jimbo2150 commented 7 months ago

@hormus You are correct. I saw it written that way on another site. Thank you.

devnexen commented 7 months ago

Thanks @hormus I also thought it was arabic... good to know !