Logic error in setlocale() when locales not fully present on system

Bug #490904 reported by Brion Vibber
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
php-gettext
Fix Released
High
Данило Шеган

Bug Description

While working with php-gettext in StatusNet, I noticed a problem with php-gettext's setlocale() check.

If setlocale() fails to return (say, due to the exact locale not being defined machine-wide), we fall back to checking LANG environment variable. When doing a *check* for the current locale instead of *setting* it, there was a logic error in this fallback and things didn't get initialized right.

This local patch has been working well for me; I think I submitted it to the old Savannah bug tracker but want to make sure it makes it into the new location. (And thanks again for updating the package -- it's hugely useful and my half-assed reimplementation from before I found it is nowhere near done :D)

Revision history for this message
Brion Vibber (brion) wrote :
Changed in php-gettext:
status: New → Triaged
importance: Undecided → High
assignee: nobody → Данило Шеган (danilo)
Revision history for this message
Данило Шеган (danilo) wrote :

Brion, thanks for the report and a patch: sorry for not getting to it in the old tracker (I don't remember seeing it). I am not sure I fully understand the patch, though.

if ($ret and ($locale == '' or $locale == $ret))

seems mostly equivalent to what it is today:

if (($ret and $locale == '') or ($locale == $ret))

except when $ret is evaluated to false, and $locale == $ret (i.e. passed in $locale is same). I guess that can happen if you are passing $locale = ''. I'll look up through the setlocale() documentation and see when it can all return ''. I guess the right fix in that case would be to check for $ret == 0 (i.e. setlocale() has not been called).

Revision history for this message
Данило Шеган (danilo) wrote :

Ok, setlocale() returns NULL when it fails, so the proper fix will be a bit more involved because this code is trying to do several things: if either setting a locale fails, or setlocale function doesn't exist, it will use emulation. I'll work on a fix.

Revision history for this message
Данило Шеган (danilo) wrote :

Ok, I have a fix which seems to work correctly (yes, I so need unit tests for php-gettext): it's in a separate branch because I don't want to integrate it before at least someone else confirms it works fine. You can get it by using "bzr branch lp:~danilo/php-gettext/bug-490904": please let me know if it works for you.

Changed in php-gettext:
status: Triaged → In Progress
Revision history for this message
Brion Vibber (brion) wrote :

Ok, had some trouble getting bzr running on my box but I've got it checked out and confirmed that the branch code is working for my case.

Thanks!

To remind myself what's going on in this code I picked apart the call sequence also:

* app calls system setlocale(LC_MESSAGES, 'fr') which system doesn't quite like, but is fine for gettext
* app calls _('blah')...
* _get_reader() calls _setlocale(LC_MESSAGES, 0) to init & check the current locale
* _setlocale() sees the 0, notices that $CURRENTLOCALE is not initialized, and calls _setlocale(LC_MESSAGES, '') to initialize itself from LANG/locale state
* _setlocale() calls system setlocale(LC_MESSAGES, ''), which as it happens asks the system what the current locale is
* setlocale() returned false because it didn't think it had a valid locale set
* we then need to head over to _get_default_locale() to set up from the LANG env var... this is the step that failed with the old logic

Revision history for this message
Данило Шеган (danilo) wrote :

Great, thanks for the input! It's fixed now in r38. And I've started adding some PHP unit tests, with a minimal one for this.

Changed in php-gettext:
status: In Progress → Fix Committed
Revision history for this message
Данило Шеган (danilo) wrote :

I'll wait a few more days for more people to pick up 1.0.9 and then release 1.0.10 with these and any other fixes that show up.

Changed in php-gettext:
milestone: none → 1.0.10
Changed in php-gettext:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.