php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #59571 Bug due to Localization
Submitted: 2011-01-11 13:38 UTC Modified: 2015-01-09 18:22 UTC
From: dubuscyr at gmail dot com Assigned: mkoppanen (profile)
Status: Wont fix Package: imagick (PECL)
PHP Version: 5.3.2 OS: Ubuntu 10.04
Private report: No CVE-ID: None
 [2011-01-11 13:38 UTC] dubuscyr at gmail dot com
Description:
------------
Hi, 

I'm reporting this bug because I've just spent 4 hours on it...

When you set the locale LC_ALL to fr_FR.utf-8 (and maybe others) you cannot pass a float number to functions like ImagickDraw::line(a,b,c,d). It throws an exception (code 460)

If you replace fr_FR.utf-8 by us_US.utf8 in the code below, it works fine !

Reproduce code:
---------------
<?php
setlocale(LC_ALL, 'fr_FR.utf-8');
try
{
	$image = new Imagick();
	$image->newImage( 400, 400, new ImagickPixel( 'wheat' ) );
	$draw = new ImagickDraw();
	$draw->line(0, 0, 0, 100.5);
	$image->drawImage( $draw );
	$image->setImageFormat( "png" );
	header( "Content-Type: image/png" );
	echo $image;
	exit;	
}
catch (Exception $e)
{
	print_r($e);
}
?>

Expected result:
----------------
An image should be drawn

Actual result:
--------------
Exception 460 thrown

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2011-01-11 14:05 UTC] mkoppanen@php.net
Try:

ini_set('imagick.locale_fix', 1);
 [2011-01-12 03:02 UTC] dubuscyr at gmail dot com
Hi, 

Thank you for your (really) quick answer. Unfortunately your fix is not working. I've added ini_set('imagick.locale_fix', 1); at the top of the reproduce code, and the error is still there.
 [2015-01-09 18:22 UTC] danack@php.net
-Status: Assigned +Status: Wont fix
 [2015-01-09 18:22 UTC] danack@php.net
Hi,

The short version is that setlocale isn't guaranteed to be safe to use in PHP. Although it can be used in very simple programs, there is no way to use it safely in any program that uses libraries or threads. If you want to have localised numbers, dates or other formatting you need to use safe functions such as http://php.net/manual/en/class.numberformatter.php

The only safe call that can be made to it is to set the locale to "C" which is the locale that libraries expect to be set.

The long version of what is happening is that:

* When you call `$draw->line(0, 0, 0, 100.5);` ImageMagick is making an SVG line primitive. It does this by calling something similar to `printf("Line %f %f %f %f", 0, 0, 0, 100.5);`

* When the locale is set to C (or other US style formatting) the result is "Line 0 0 0 100.5". When the locale is set to fr_FR.utf-8 (or other locale that has a comma for the fraction separator) the result it "Line 0 0 0 100,5"

* The SVG spec says that all numbers should be done with C style formatting of numbers - so the line primitive generated when the local is set fr_FR is not valid, and so the call to drawImage fails due to the invalid primitive.

If you are running PHP in a single threaded environment (e.g. from the comamand line) then you may be able to set the locale to the US style before calling Imagick and then setting it back to fr_FR after calling Imagick. However this is not guaranteed to be sucessful if the library uses threads, and is definitely not save to use in any environment where PHP itself has more than one thread.

The reason for that is setlocal is not a thread safe function to call, and it affects all threads at once.

e.g. it is possible that the result of printf("Point %f %f", 0.5, 0.5);` would be "Point 0.5 0,5" if the value of setlocal is modified by another thread during the call to printf. 

Because of this, it's just not safe to attempt to use ImageMagick with a locale setting other than "C". Although it may possibly work under certain circumstances, any issues that are seen when calling Imagick with that setting aren't ones we will be able to solve.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Dec 26 13:01:30 2024 UTC