# snprintf/var_export issues

- Thread: https://externals.io/message/30196
- Original archive: https://news-web.php.net/php.internals/30196
- Started by Derick Rethans on 2007-06-15T11:54:18+00:00
- Messages: 2
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #30196 — Derick Rethans — 2007-06-15T11:54:18+00:00

URL: https://externals.io/message/30196#30196

Hello,

While testing a bit of code under a different locale (de_DE) we found 
that `var_export()` uses a , for representing floating point decimal 
separators. As `var_export()` is supposed to generate "valid PHP code" 
there is now a bug in this function.

While looking into this, I found that internally it uses the following 
call:

php_printf("%.*G", (int) EG(precision), Z_DVAL_PP(struc));

However, the G modifier, unlike F, is locale-aware and will happily 
create "5,12" as a "valid PHP float". This of course does not parse. I 
expected the uppercase G to be locale-insensitve and the lowercase g to 
be locale-sensitive. However, looking at the code it only switched 
between E and e. The g/G modifier as is implemented now does not seem to 
have any locale-insensitive option. The difference between "f" and "g" 
is that g/G is smarter regarding appending 0's. Trailing zeroes are not 
wanted when rendering a float as "valid PHP code" (as it looks different 
than when it was written in the application).

I see a few options to address this:

1. Change "G" to be locale-insensitve.

   We can't really do that as it's also use in _convert_to_string.

2. Add a new modifier "H" or "L" that is like G, but 
   locale-insensitive.

3. Change "g" to be locale-insensitve, as this one does not seem to be 
   used anywhere in the code base.


I think we should pick option 2, find another modifier letter as it 
won't impact anything else.


Notes:

- _build_trace_args (from Zend/zend_exceptions.c) seems also to be 
  affected, as it uses the G modifier to build argument lists as string 
  for exception traces. So now it uses the , to separate arguments AND 
  as float decimal sep in case of a de_DE locale.


regards,
Derick


-- 
Derick Rethans
http://derickrethans.nl | http://ez.no | http://xdebug.org

---

## #30250 — Derick Rethans — 2007-06-19T12:31:29+00:00

URL: https://externals.io/message/30196#30250 · In reply to: #30196

> 2. Add a new modifier "H" or "L" that is like G, but 
>    locale-insensitive.

I implemented this as the "H" modifier.

> Notes:
> 
> - _build_trace_args (from Zend/zend_exceptions.c) seems also to be 
>   affected, as it uses the G modifier to build argument lists as string 
>   for exception traces. So now it uses the , to separate arguments AND 
>   as float decimal sep in case of a de_DE locale.

This one can not be fixed, as it uses zend_sprintf() which just wraps 
around `sprintf()` incase sprintf is not "broken". `sprintf()` doesn't have 
a format modifier for this purpose, so what we can do here is 1. always 
use our `sprintf()` implementation; 2. use php_printf() or 3. ignore it.

Derick
