Merge lp:~mterry/unity-scopes-api/turkish into lp:unity-scopes-api/devel

Proposed by Michael Terry
Status: Merged
Approved by: Michi Henning
Approved revision: 372
Merged at revision: 691
Proposed branch: lp:~mterry/unity-scopes-api/turkish
Merge into: lp:unity-scopes-api/devel
Diff against target: 59 lines (+14/-2)
4 files modified
debian/control (+1/-0)
src/scopes/internal/ConfigBase.cpp (+1/-1)
src/scopes/internal/Utils.cpp (+1/-1)
test/gtest/scopes/internal/Utils/Utils_test.cpp (+11/-0)
To merge this branch: bzr merge lp:~mterry/unity-scopes-api/turkish
Reviewer Review Type Date Requested Status
Marcus Tomlinson (community) Approve
unity-api-1-bot continuous-integration Approve
Review via email: mp+308610@code.launchpad.net

This proposal supersedes a proposal from 2016-10-07.

Commit message

Fix reading scope metadata in a Turkish locale.

Description of the change

I don't know of any existing bug symptom caused by this. I came across this while investigating a crash due to a misconfigured locale.

We're using std::locale("") to handle lowercasing user-input (well developer-input) scope metadata keys into standardized key names. This has two effects:

1) If the environment-specified locale is not set up correctly, an exception will be thrown. Fair enough I guess, but still a harsh possible side effect of just trying to lowercase some ASCII characters.

2) Using a locale-sensitive lowercasing algorithm has some odd side effects. Most notably in Turkish. See [1] and other such sites if you google "turkish i problem." Basically, if your problem domain is ASCII and/or you are not dealing with strings that the user will see, you probably don't want to be converting characters with the user's locale.

I've added a test that demonstrates the issue. With the old code, if you don't have the tr_TR.UTF-8 locale installed, the test will crash. If you do, it will fail. With the new code, it will pass in both cases. I've added language-pack-tr to the Build-Depends to make sure the locale is valid during normal build tests (the i problem is more interesting to test than the invalid locale problem, which is probably expected behavior anyway).

[1] http://haacked.com/archive/2012/07/05/turkish-i-problem-and-why-you-should-care.aspx/

To post a comment you must log in.
Revision history for this message
Marcus Tomlinson (marcustomlinson) wrote : Posted in a previous version of this proposal

Excellent work adding a test case for this! LGTM

review: Approve
Revision history for this message
Michael Terry (mterry) wrote :

I retargeted to devel, please re-approve.

Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote :

PASSED: Continuous integration, rev:372
https://jenkins.canonical.com/unity-api-1/job/lp-unity-scopes-api-ci/51/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/890
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/897
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/703
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/703/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/703
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/703/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/703
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/703/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/703
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/703/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/703
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/703/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/703
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/703/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/703
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/703/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/703
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/703/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/703
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/703/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-unity-scopes-api-ci/51/rebuild

review: Approve (continuous-integration)
Revision history for this message
Marcus Tomlinson (marcustomlinson) wrote :

Ah, my bad for missing that

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/control'
2--- debian/control 2016-09-09 06:57:47 +0000
3+++ debian/control 2016-10-17 08:54:00 +0000
4@@ -18,6 +18,7 @@
5 exuberant-ctags,
6 google-mock,
7 graphviz,
8+ language-pack-tr,
9 libaccounts-glib-dev,
10 libapparmor-dev,
11 libboost-filesystem-dev,
12
13=== modified file 'src/scopes/internal/ConfigBase.cpp'
14--- src/scopes/internal/ConfigBase.cpp 2014-08-28 00:20:56 +0000
15+++ src/scopes/internal/ConfigBase.cpp 2016-10-17 08:54:00 +0000
16@@ -219,7 +219,7 @@
17
18 void ConfigBase::to_lower(string & str)
19 {
20- locale locale("");
21+ locale locale("C"); // Use "C" to avoid the Turkish I problem
22 const ctype<char>& ct = use_facet<ctype<char> >(locale);
23 transform(str.begin(), str.end(), str.begin(),
24 bind1st(std::mem_fun(&ctype<char>::tolower), &ct));
25
26=== modified file 'src/scopes/internal/Utils.cpp'
27--- src/scopes/internal/Utils.cpp 2015-11-25 08:55:19 +0000
28+++ src/scopes/internal/Utils.cpp 2016-10-17 08:54:00 +0000
29@@ -113,7 +113,7 @@
30
31 string uncamelcase(string const& str)
32 {
33- const locale loc("");
34+ const locale loc("C"); // Use "C" to avoid the Turkish I problem
35 if (str.size() == 0)
36 {
37 return str;
38
39=== modified file 'test/gtest/scopes/internal/Utils/Utils_test.cpp'
40--- test/gtest/scopes/internal/Utils/Utils_test.cpp 2015-09-15 07:36:09 +0000
41+++ test/gtest/scopes/internal/Utils/Utils_test.cpp 2016-10-17 08:54:00 +0000
42@@ -37,6 +37,17 @@
43 EXPECT_EQ("foo-bar", uncamelcase("foo-Bar"));
44 }
45
46+TEST(Utils, uncamelcase_turkish)
47+{
48+ char *old_locale = strdup(getenv("LC_ALL"));
49+ setenv("LC_ALL", "tr_TR.UTF-8", 1);
50+
51+ EXPECT_EQ("small-i", uncamelcase("smallI"));
52+
53+ setenv("LC_ALL", old_locale, 1);
54+ free(old_locale);
55+}
56+
57 TEST(Utils, convert_to)
58 {
59 {

Subscribers

People subscribed via source and target branches

to all changes: