# drush ev 'echo iconv("utf8", "ASCII//TRANSLIT", " héllô") . "\n";'
h?ll?
# php -r 'echo iconv("utf8", "ASCII//TRANSLIT", " héllô");'
hello

I find this difference very dangerous and would like to have a clear sight of what's happening here.

First I used ini_get_all() to compare settings between drush (Drupal bootstrap) and php, about localization :
After inserting in my cli/php.ini:
# mbstring.language = uni

the following shell snippet:

for func in mb_get_info iconv_get_encoding  localeconv; do
   diff <(php -r "var_dump($func());") <(drush ev "var_dump($func());")
done

returned no output...
good sign, the settings are the same and, except iconv_get_encoding() whose value are set to ISO-8859-1, all others are those of an UTF-8 setup.
(standard Squeeze fr.FR_UTF-8, php5-cli 5.3.3-7+squeeze3)

I don't have anything special in my .drush directory. Which settings are left to test in order to spot this annoying inconsistency ?

[ NB: I had to assign a version number ]

Comments

drzraf’s picture

One bug was in my configuration for sure :

inserting the word "déchet" (é = uC3A9 <=> e9 in iso8859-1) :
browser: Accept-Charset: utf-8,*
mysql<<<"show create table taxonomy_term_data;" => ENGINE=InnoDB CHARSET=utf8

/taxonomy/term/3/edit, POSTED name=d%C3%A9chets
mysql -N <<<"select name from taxonomy_term_data where tid = 3;"|xxd => 64e9 6368 6574 730a

tracked it down to :
show create database <db> => DEFAULT CHARACTER SET latin1

[ but I still have to find why the drush ev and php commands above differ ]

I would close it, but I strongly think that the DB charset check should be done by the installer (even pecl uploadprogress is checked for its usability).
Or an admin may agree on this and reassign to Core / Locale / installer ?

greg.1.anderson’s picture

Searching the issue queue seems to be broken on drupal.org right now (?), but I would recommend searching for iconv in the Drush queue. There may be an older issue that could offer some insight as to what Drush is doing vis-a-vis character encodings, and why.

greg.1.anderson’s picture

Searching working again -- no issues with 'iconv', but I think there was an old issue that might be interesting, if you can find it.

greg.1.anderson’s picture

The issue I was thinking of was #797700: Convert drush output to terminal console code page, but not sure that explains the output shown in #0 above.

drzraf’s picture

I don't think the case in the original subject has to do with the terminal encoding:
both :
echo -n "héllô"|xxd -ps
php -r 'echo "héllô";'|xxd -ps
drush ev 'echo "héllô";'|xxd -ps
print:
68c3a96c6cc3b4

but ...
I missed to say that my test with drush were done with specifying an alias (eg: drush @beta ev ...)
and I just found that when using my default database (which has the same settings), it works (iconv/translit prints "hello" as it should) !
(my @beta alias only contains the 'root' and 'uri' parameters)

I'll dig this further (but could it be related to aliases handling ?)

jdonson’s picture

Component: Miscellaneous » SQL

Trying to clarify issues from database side below....

My apologies if I am missing the point.

Note that there are several layers of character set and collation encoding in mysql.

server default
schema default
table definition
connection
client settings

Try this and note that each can be configured statically and dynamically, as per version of mysqld:

mysql> show variables like '%char%';
+--------------------------+--------------------------------------------------+
| Variable_name | Value |
+--------------------------+--------------------------------------------------+
| character_set_client | latin1 |
| character_set_connection | latin1 |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | latin1 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /Applications/MAMP/Library/share/mysql/charsets/ |
+--------------------------+--------------------------------------------------+
8 rows in set (0.00 sec)

mysql> show variables like '%collat%';
+----------------------+-------------------+
| Variable_name | Value |
+----------------------+-------------------+
| collation_connection | latin1_swedish_ci |
| collation_database | latin1_swedish_ci |
| collation_server | latin1_swedish_ci |
+----------------------+-------------------+
3 rows in set (0.00 sec)

drzraf’s picture

I've exactly the same setup, except /usr/share/mysql/charsets/ as character_sets_dir :)

kotnik’s picture

If you do it outside Drupal (hence without Drupal bootstrap) you get correct output:

~ $ php -r 'echo iconv("utf8", "ASCII//TRANSLIT", " héllô") . "\n";'
 hello
~ $ drush ev 'echo iconv("utf8", "ASCII//TRANSLIT", " héllô") . "\n";'
 hello
~ $ cd /var/www/drupal7
/var/www/drupal7 $ php -r 'echo iconv("utf8", "ASCII//TRANSLIT", " héllô") . "\n";'
 hello
/var/www/drupal7 $ drush ev 'echo iconv("utf8", "ASCII//TRANSLIT", " héllô") . "\n";'
 h?ll?

Will check what in boostrap makes it behave this way.

greg.1.anderson’s picture

I predict that whatever it is that is affecting encoding will be found in the Drupal bootstrap code. Best of luck in your isolation efforts.

drzraf’s picture

thanks !
I'm still not able to reproduce this by tweaking different directory (will try later)
but I bissected bootstrap.inc down to the "faulty" line which is... obviously :
setlocale(LC_ALL, 'C');, l. 698 in includes/bootstrap.inc
[ removed it and it works as it should ]
So why is this line here in the first place. LC_COLLATE=C would make sense in order to fix glob([a-Z]*) problems
but I don't understand its use for LC_ALL.
Back to 33c7e4da it was done in order fix #614124: Bootstrap should reset locale settings
But a setlocale(LC_CTYPE) happened to be into include/unicode.inc back from 11a4aba9 (2005) to fix #26688: Add mbstring support to Drupal
but LC_CTYPE would *also* have affected iconv in such case (LC_COLLATE wouldn't)

#614124: Bootstrap should reset locale settings is still opened and unassigned... so no need to reopen...
but still have to understand how it's related to the use of aliases or root directory.

damien tournoud’s picture

Drupal should not respect the locale settings of the server. Especially, the very important part is LC_NUMERIC=C because otherwise PHP formats floats in a locale-dependent fashion.

Respecting the locale settings of the shell might be in the scope of Drush, but it's not in the scope of Drupal.

greg.1.anderson’s picture

If Drupal does a setlocale(LC_ALL, 'C');, it seems that it would be undesirable for Drush to undo that, unless, perhaps it could do a save/set/restore locale setting around actual output in drush_print & c.

This returns us to #0, which shows the symptoms but not the use case. The data that is being "incorrectly" transliterated was provided from the cli in the encoding expected for the system. This is different than data coming from the Drupal database being incorrectly interpreted. Perhaps you need to iconv to UTF8 your data before you pass it to Drush. Alternately, perhaps Drush needs to iconv the cli parameters prior to bootstrapping Drupal. And what about drushrc.php option values; do they need to be transliterated as well?

Edit: Input data is indeed UTF8; the problem here is not in the encoding of the input data, but the way that setting the locale to 'C' affects the output transliteration of iconv.

drzraf’s picture

The fact that it comes from the CLI, a DB, a file, ... does not really matter as long
as we ensure it is valid UTF-8. For example, the problem also happens with :
echo t( iconv( "utf8", "ASCII//TRANSLIT", system("echo \"héllô\";" ) ) )
(you may also touch /tmp/héllô && iconv ( system( "ls /tmp" ) );)

The problem is in the way the core resets the whole locale thus making
locale-dependant functions (like iconv()) fail. The issue probably also affect modules
which handles files / lists directories.

greg.1.anderson’s picture

Yes, you may very well be right, but there is nothing Drush can do about the locale setting after the Drupal bootstrap. If you have code in your drush module that needs to operate under a particular locale, you could call setlocale yourself immediately prior to the i18n calls; however, you'd need to set it back again when you were done, or you'd risk breaking Drupal's expected behavior.

I think we have no choice but to close this issue as 'works as designed'.

drzraf’s picture

I agree on closing this issue.
about the "DB charset check" from #1 I'll see if it's worth opening an issue.
About the drush @beta ev vs drush ev I'm not able to reproduce a difference.
(both print "h?ll?").
Anyway, there's still the strange behavior experimented by kotnik where the output depends
on the directory it's run from.
Could the execution of includes/bootstrap.inc drupal_environment_initialize()
be related in some way to the directory drush is run into ? I don't know.

greg.1.anderson’s picture

Status: Active » Closed (works as designed)

Drush will attempt to find a Drupal site at the cwd, so whether or not Drupal is bootstrapped can indeed depend on where drush is executed from.

greg.1.anderson’s picture

Issue summary: View changes

style