Structure and Interpretation of Computer Programmers

I make it easier and faster for you to write high-quality software.

Sunday, May 9, 2010

On localisation and security

Hot on the heels of Uli’s post on the problems of translation, I present another problem you might encounter while localising your code. This is a genuine bug (now fixed, of course) in code I have worked on in the past, only the data has been changed to protect the innocent.

We had a crash in the following line:

NSString *message = [NSString stringWithFormat:
	NSLocalizedString(@"%@ problems found", @"Discovery message"),
	problem];

Doesn’t appear to be anything wrong with that, does there? Well, as I say, it was a crasher. The app only crashed in one language though…for purposes of this argument, we’ll assume it was English. Let’s have a look at English.lproj/Localizable.strings:

/* Discovery message */
"%@ problems found" = "%@ found in %@";

Erm, that’s not so good. It would appear that at runtime, the variadic method +[NSString stringWithFormat: (NSString *)fmt, ...] is expecting two arguments to follow fmt, but only passed one, so it ends up reading its way off the end of the stack. That’s a classic format string vulnerability, but with a twist: none of our usual tools (by which I mean the various -Wformat flags and the static analyser) can detect this problem, because the format string is not contained in the code.

This problem should act as a reminder to ensure that the permissions on your app’s resources are correct, not just on the binary—an attacker can cause serious fun just by manipulating a text file. It should also suggest that you audit your translators’ work carefully, to ensure that these problems don’t arise in your app even without tampering.

posted by Graham at 00:39  

Friday, August 29, 2008

Walking a mile dans ses chausseurs

The word ‘translator’ has an interesting history. In the Anglo-Saxon language, ‘wealhstod’ meant “learned in Welsh” more or less, and described someone who could parlay with the important members of the local British tribes. As is often the case with invasions the British started to use the word, so the Welsh title ‘Gwalstawt’ means “interpreter of tongues”, i.e. the Welsh word for “can speak another language” originally meant “can speak Welsh” (there’s another word more closely related to Breton treiñ or Cornish trélya in Welsh, too; trosi).

Anyway, to see what localisation people go through during the l10n process, I decided the best thing to do was to try it myself. To save the time it would have taken to write an internationalised app, I used someone else’s; namely TextEdit. Here’s the result after about 90 minutes of work:

Trahtendebyrdenne

The first thing to notice is that I haven’t actually got much done yet. I’ve started working on the main menu NIB file (Edit.nib), and I’m about halfway through that. At this rate, it would take me at least a (working) day to finish – granted I’m no expert at the task, so I’m having to make a more heroic effort on otherwise “standard” translations than most localisers would. Although I do have a glossary to help. Even so, TextEdit is a fairly simple app; it’s easy to see that even if the translation became a mechanical process, translating a complex program would take a long time.

The other thing you might have noticed is that Mac OS X doesn’t actually support Old English, and yet that’s the language of my translation. There’s a simple trick here; convince Mac OS X that it does support Old English ;-). Type this command in the Terminal:

$ defaults write NSGlobalDomain AppleLanguages ‘(ang, en, /* other languages */)’

and Robert, as they say, is your father’s brother. Apps will now look for localised resources in ‘ang.lproj’ when they start, so that’s where your Old English resources live.

posted by Graham Lee at 22:24  

Powered by WordPress