CFPropertyList icon indicating copy to clipboard operation
CFPropertyList copied to clipboard

Output of toXML() for <real>s is locale-dependent and causes creation of invalid PList-XML

Open stefanschramm opened this issue 3 years ago • 4 comments

Describe the bug When using a locale that uses commas (,) instead of points (.) as decimal delimiter, the output of CFPropertyList::toXML() uses this charater for <real>s which is invalid PList-Data. The cause is probably some implicit toString conversion that will use the current locale.

To Reproduce Execute this script:

<?php
use CFPropertyList\CFPropertyList;
require_once('vendor/autoload.php');
$example = <<<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"><dict><key>ExampleReal</key><real>1.5</real></dict></plist>
EOF;
setlocale(LC_ALL, 'de_DE.UTF-8');
$plist = new CFPropertyList();
$plist->parse($example);
echo $plist->toXML();

It's output will be:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"><dict><key>ExampleReal</key><real>1,5</real></dict></plist>

Expected behavior This output:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"><dict><key>ExampleReal</key><real>1.5</real></dict></plist>

(1.5 instead of 1,5)

Desktop

  • Linux 5.4, PHP 7.4.3 using CLI, Composer-Package rodneyrehm/plist v2.0.2

stefanschramm avatar May 31 '21 12:05 stefanschramm

Hi

I reproduce. The problem is caused by the use of the function floatval() which outputs a float in a format dependent on your locale.

btry avatar Jun 03 '21 21:06 btry

Please test the patch above, and feedback.

btry avatar Jun 03 '21 22:06 btry

The patch adds the dependency to install the php-intl-Extension.

Using bigger numbers like 1234.5 will add thousands-separators: 1,234.5. Adding $formatter->setAttribute(\NumberFormatter::GROUPING_USED, false); solves this for me.

stefanschramm avatar Jun 03 '21 23:06 stefanschramm

Hi

Yes, you're right. I add this extra attribute to the PR.

However I cannot merge the fix right now : I need to add an unit test for your issue, and migrate test environment to github actions. I need some time to do this, merge and build a new release.

EDIT : I added the dependency to php-intl. I think it is better to rely on NumberFormatter instead of a filthy string manipulation, which may break for some foreign language.

btry avatar Jun 04 '21 06:06 btry