Comment On Classic WTF: Five Wrongs Don't Make a Right

Let's say you were given the requirement "ensure that all five lines of a shipping address contains valid characters." How do you suppose you would go about implementing such a requirement? Let's hope your solution would be far, far away from Buri's coworker's implementation which not only has a separate function for each address but manages to have an astonishingly unique method of testing for bad characters ... [expand full text]
« PrevPage 1 | Page 2Next »

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 08:07 • by configurator (unregistered)
So it throws an Exception when invalid, returns 1 for valid and 0 for null.

TRWTF is Java, of course.

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 08:09 • by Fred (unregistered)
If this line is not blank then maybe 5 seconds can make a frist.
If this line is not blank then maybe 5 seconds can make a frist.
{snip}
If this line is not blank then maybe 5 seconds can make a frist.

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 08:11 • by Victor (unregistered)
/** Valid signs */

You don't need to read any further than that to know you're not dealing with a programmer here.

But when he went home at night I bet he was thinking yeah I'm sooooo cool I wrote some code today yeehaw!

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 08:12 • by drake (unregistered)
If he had used Regular Expressions, he would have had 10 problems

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 08:14 • by Walter (unregistered)
Well at least he implemented a whitelist not a blacklist. Even if I offered a $10,000 bonus, I don't think I could get our lead web "developer" to grasp that concept.

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 08:17 • by Smug Unix User (unregistered)
398160 in reply to 398158
10 problems are less than 101 problems.

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 08:19 • by Yasmin (unregistered)
You might think this could be reduced to a single function, but you would be forgetting the unique messages:

"Vsadr5 with invalid sign"

(And, of course, your users are naturally intuitively going to know what Vsadr5 means... to say nothing of invalid sign.)


WARNING: CAPTCHA not invalid!

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 08:59 • by Foo Bar (unregistered)
If Cedille, Eszett, and Y acute are all considered valid address characters, either the company expects to ship all over Europe, or the "programmer" is having too much fun with keyboard symbols.

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 09:11 • by @Deprecated
That's awesome how all the tests have the same logic, just the exception message and the variable names are different.

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 09:11 • by Dazed (unregistered)
I suppose this might have been written with one of the early Java versions that didn't have regexes. But that's not much of an excuse ...

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 09:11 • by ObiWayneKenobi
Ah the classic case of a clueless/lazy programmer who, rather than sit back after the first one and think "Hey wait a minute, this seems really inefficient. What if we need to validate more than one line?" and then goes and refactors out the code properly, does it once, says "It's done Boss" and then copy-pastes that function when they need to do it again.

It's a damn shame these bozos are more common than they should be.

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 09:14 • by ObiWayneKenobi
398167 in reply to 398165
Dazed:
I suppose this might have been written with one of the early Java versions that didn't have regexes. But that's not much of an excuse ...


Even if it was, that's not an excuse for not refactoring this out into a method so the code doesn't have to be repeated. That's the real WTF here, not the way it's implemented but that it's not reusable so it has to be copied.

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 09:32 • by F (unregistered)
398169 in reply to 398166
ObiWayneKenobi:
Ah the classic case of a clueless/lazy programmer who, rather than sit back after the first one and think "Hey wait a minute, this seems really inefficient. What if we need to validate more than one line?" and then goes and refactors out the code properly, does it once, says "It's done Boss" and then copy-pastes that function when they need to do it again.

It's a damn shame these bozos are more common than they should be.


That's what you should expect when people get rated on lines of code instead of quality.

He's missed a trick, though. He could have added code for address lines 6 to 10, `"to allow for future enhancement".

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 10:20 • by That Guy (unregistered)
398171 in reply to 398162
Foo Bar:
If Cedille, Eszett, and Y acute are all considered valid address characters, either the company expects to ship all over Europe, or the "programmer" is having too much fun with keyboard symbols.


I was more worried about the semicolon, back slash, and the open and close parens. What, curly braces are too good for your addresses?

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 10:21 • by Matt Westwood
The clunking tedium of creating an array of characters: 'A', 'B', .... yecch. My immediate thought (in absence of any knowledge of the existence of regexps) would be:

String validChars = "ABCDE ... "

But apart from repeating the business end 5 times (oh, and failing to handle exceptions and null cases correctly) I've seen plenty worse.

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 10:25 • by Matt Westwood
He should have written it like this:


for (i = 0; i < address.length(); i++) {
if (address[i:i] != 'A' then {
if (address[i:i] != 'B' then {
.... etc. ad barf
}
}
}

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 11:01 • by MarkMc (unregistered)
My eyes. The goggles aren't helping. How many times do we need to write
something like the following?


private boolean ValidateShippingAddress( String input )
{
String whitelist =
"^[a-zA-Z0-9\.,\'-/&!\"$%()*+:;=\üéâäàçêëèïîìßôöòûùßáíóúñÑÄÖÜ#åÿýÁÂÀÅÇÉÊËÈÍÎÏÌÓÔÒÚÛÙÝ]*$";
Pattern pattern = Pattern.compile(whitelist);
return pattern.matcher(input).matches();
}


Or more likely refactor this to generalize for all the other input fields that need validation, providing a standardized regex pattern.

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 12:01 • by Yaos
398177 in reply to 398171
That Guy:
Foo Bar:
If Cedille, Eszett, and Y acute are all considered valid address characters, either the company expects to ship all over Europe, or the "programmer" is having too much fun with keyboard symbols.


I was more worried about the semicolon, back slash, and the open and close parens. What, curly braces are too good for your addresses?


I feel great joy when I ask how do we know what we want. Suddenly people realize that they never bothered to figure out what they actually want.

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 12:03 • by Matt Westwood
398178 in reply to 398176
MarkMc:
My eyes. The goggles aren't helping. How many times do we need to write
something like the following?


private boolean ValidateShippingAddress( String input )
{
String whitelist =
"^[a-zA-Z0-9\.,\'-/&!\"$%()*+:;=\üéâäàçêëèïîìßôöòûùßáíóúñÑÄÖÜ#åÿýÁÂÀÅÇÉÊËÈÍÎÏÌÓÔÒÚÛÙÝ]*$";
Pattern pattern = Pattern.compile(whitelist);
return pattern.matcher(input).matches();
}


Or more likely refactor this to generalize for all the other input fields that need validation, providing a standardized regex pattern.


What, like this:


private boolean ValidateBusinessString( String input, String whitelist )
{
Pattern pattern = Pattern.compile(whitelist);
return pattern.matcher(input).matches();
}


Possibly even compile the pattern statically and pass the pattern in. At which stage there is a school of thought that suggests you might as well factor out the method itself as it contains but one line. I would probably keep the method just in case it needs to get more complicated in future.

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 13:17 • by jay (unregistered)
398179 in reply to 398165
Dazed:
I suppose this might have been written with one of the early Java versions that didn't have regexes. But that's not much of an excuse ...


It must also have been written with one of the early versions of Java where you couldn't call the same function in two different places with two different values for the parameter.

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 14:32 • by Adin (unregistered)
398185 in reply to 398158
Ha ha. Absolutely agree.

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 14:36 • by Jeff Grigg (unregistered)
Well, I find it helpful that they allow the single quote character ('), for SQL injection attacks. And the ampersand character (&) for HTML injection/cross-site scripting attacks. They're always working harder to make my life easier!!!

>;->

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 15:25 • by Meep (unregistered)
398189 in reply to 398164
@Deprecated:
That's awesome how all the tests have the same logic, just the exception message and the variable names are different.


Which is perfectly reasonable since you might want to change the logic for one field.

What's awesome is how the author didn't simply put the common functionality in another method. "I'll write a method for each field, but I'd rather copy and paste my code five times than create a sixth."

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 15:34 • by instigator (unregistered)
398190 in reply to 398172
If only ASCII was arranged in a logical manner, then you wouldn't even need regular expressions. You could do something like:

for( int i = 0; i < vsadr1.length(); i++ )
{
char c = vsadr1.charAt(i)
if(!( (c >= 'A' && c <= 'Z') ||
(c >= 'a' && c <= 'z') ||
(c >= '0' && c <= '9') ||
(c == ' ') // || ...
))
return false;
}
return true;

captcha: sagaciter: The SAGACITER loved to reference "Lord of the Rings"

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 16:22 • by Darth Paul (unregistered)
The other WTF - yet another data modeller/BA who thinks that addresses consist of 5 fields.

No doubt it is near impossible to create a report to the effect of "sales by state" and the excuse will be "no-one has ever asked for that in all the years I have been here."

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 16:49 • by Anonymous (unregistered)
The requirement is mostly bogus, too... We've all seen the multi-page regex to (mostly) get email addresses right, and postal addresses are a lot more irregular. There is no way to construct a whitelist, except closely studying the postal guidelines of all the countries you're shipping to, going insane, then settle on a blacklist of the most esoteric Unicode blocks – it's most likely none of ⟺ or ☻ or 💂.

Then again, why bother? Just print it on the label and have the postman figure it out.

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 16:50 • by urza9814 (unregistered)
398193 in reply to 398190
instigator:
If only ASCII was arranged in a logical manner, then you wouldn't even need regular expressions. You could do something like:

for( int i = 0; i < vsadr1.length(); i++ )
{
char c = vsadr1.charAt(i)
if(!( (c >= 'A' && c <= 'Z') ||
(c >= 'a' && c <= 'z') ||
(c >= '0' && c <= '9') ||
(c == ' ') // || ...
))
return false;
}
return true;

captcha: sagaciter: The SAGACITER loved to reference "Lord of the Rings"


Wouldn't need a regex, but it's still far simpler...because you can do the same basic thing. Why type out "(c >= 'A' && c <= 'Z') ||" when you could just use "[A-Z]"?

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 17:06 • by Alex Emelianov (unregistered)
And then you need to ship to Japan. Oops (times five)!

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 17:12 • by moreON (unregistered)
398195 in reply to 398190
So that's:

if(expr){
return !expr;
}
return expr;


why not just
return !expr;
?

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 19:21 • by Mr. Shine (unregistered)
I think y'all are being too hard on this programmer. He *did* recognize that he needed only one validSign array, after all.

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 20:10 • by dkf
398201 in reply to 398192
Anonymous:
The requirement is mostly bogus, too... We've all seen the multi-page regex to (mostly) get email addresses right, and postal addresses are a lot more irregular. There is no way to construct a whitelist, except closely studying the postal guidelines of all the countries you're shipping to, going insane, then settle on a blacklist of the most esoteric Unicode blocks – it's most likely none of ⟺ or ☻ or 💂.

Then again, why bother? Just print it on the label and have the postman figure it out.
You don't know how true that is. I know someone who used to work on systems for automated reading of postal labels and routing of letters and parcels based on that (he might still be doing that, building post sorting machines for post offices) and he said that it was incredibly hard. He particularly noted that the UK was especially bad, as there is no standard address form (though we do have detailed postal codes to make things easier, and they're in common use). Ultimately, the best policy is indeed to just put whatever the user gave you on the label and let the post office deal with it.

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 21:04 • by Jeff Grigg (unregistered)
398203 in reply to 398201
dkf:
Anonymous:
The requirement is mostly bogus, too... ... postal addresses are a lot more irregular. There is no way to construct a whitelist, except closely studying the postal guidelines of all the countries you're shipping to, going insane, then settle on a blacklist of the most esoteric Unicode blocks – it's most likely none of ⟺ or ☻ or 💂. ...


You don't know how true that is. ... it was incredibly hard. ... the UK was especially bad, as there is no standard address form ... Ultimately, the best policy is indeed to just put whatever the user gave you on the label and let the post office deal with it.


I would suggest that one should first trust the user to be able to type in an address that will get it to them. If they can't do that, then you have more serious problems than playing games with what characters to allow.

OK, you should probably not allow non-printable characters.

But I would suggest that instead of making up "requirements," maybe one should consult the appropriate standards. For United States addresses, it would be "Publication #28."

http://pe.usps.gov/cpim/ftp/pubs/pub28/pub28.pdf

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 21:04 • by Norman Diamond (unregistered)
398204 in reply to 398162
Foo Bar:
If Cedille, Eszett, and Y acute are all considered valid address characters, either the company expects to ship all over Europe, or the "programmer" is having too much fun with keyboard symbols.
Not really. The company expects to ship to Scandinavia and Germany but not to Greece, Turkey, and some Slavic countries.

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 21:11 • by Norman Diamond (unregistered)
398205 in reply to 398203
Jeff Grigg:
But I would suggest that instead of making up "requirements," maybe one should consult the appropriate standards. For United States addresses, it would be "Publication #28."

http://pe.usps.gov/cpim/ftp/pubs/pub28/pub28.pdf
USPS standards aren't there to be obeyed, you know. One standard says that senders should put their country name at the end of the return address. Government operations such as one called "IRS" (not that there's anything internal or service about it) put "PA" at the end of their return address, which is the ISO abbreviation for Panama. Whenever the sender puts a nondeliverable destination address on a letter, the receiving country has to send it back to Panama. Guess who gets blamed and who gets their refunds stolen.

Re: Classic WTF: Five Wrongs Don't Make a Right

2012-12-31 23:05 • by Coyne
5 x the lines
5 x the functions
5 x the productivity
5 x the maintenance

5 x the pay, right?

TRWTF is that he didn't make 5 copies of the array. WIW is wrong with the programmer?

Sigh. How are we supposed to win when the turkeys outnumber the eagles 5:1?

Re: Classic WTF: Five Wrongs Don't Make a Right

2013-01-01 08:00 • by Dotan Cohen (unregistered)
398208 in reply to 398203
Jeff Grigg:
I would suggest that one should first trust the user to be able to type in an address that will get it to them. If they can't do that, then you have more serious problems than playing games with what characters to allow.

OK, you should probably not allow non-printable characters.


This is my address without nonprintable characters:
64/2 רמב"ם

This is my address with nonprintable characters:
‫64/2 רמב"ם

So even those are important.

Re: Classic WTF: Five Wrongs Don't Make a Right

2013-01-01 09:06 • by Kasper (unregistered)
398209 in reply to 398159
Walter:
Well at least he implemented a whitelist not a blacklist.
But a blacklist would have been easier to get right since it would have been a lot shorter than a whitelist.

I have yet to come across a situation where the validity of an input field can be correctly validated using a list of valid characters. There are however cases, where a list of valid characters can provide a good enough approximation.

If for example an input field contains a value such as a number or an IP address, then a whitelist of permitted characters could make sense. It would still permit lots of invalid inputs, but you'd rule out all inputs that could perform some sort of injection attack.

As soon as your inputs start looking even slightly similar to free text, then forget about validating using a list of valid characters. The only proper approach to such fields is to consider all characters to be valid and apply proper escaping. Most of the possible escaping bugs can be caught by simply testing that you can indeed use all different characters.

Re: Classic WTF: Five Wrongs Don't Make a Right

2013-01-01 10:05 • by David (unregistered)
398210 in reply to 398186
Jeff Grigg:
Well, I find it helpful that they allow the single quote character ('), for SQL injection attacks. And the ampersand character (&) for HTML injection/cross-site scripting attacks. They're always working harder to make my life easier!!!

>;->


Because there's no need for anyone at Plummer's Landing to reliably get their mail, is there? Programmers don't get to mangle people's data for their convenience.

Re: Classic WTF: Five Wrongs Don't Make a Right

2013-01-01 13:53 • by derula
398213 in reply to 398195
moreON:
So that's:

if(expr){
return !expr;
}
return expr;


why not just
return !expr;
?


I hope you're trolling.

Re: Classic WTF: Five Wrongs Don't Make a Right

2013-01-01 16:33 • by fjf (unregistered)
398214 in reply to 398201
dkf:
Anonymous:
The requirement is mostly bogus, too... We've all seen the multi-page regex to (mostly) get email addresses right, and postal addresses are a lot more irregular. There is no way to construct a whitelist, except closely studying the postal guidelines of all the countries you're shipping to, going insane, then settle on a blacklist of the most esoteric Unicode blocks – it's most likely none of ⟺ or ☻ or 💂.

Then again, why bother? Just print it on the label and have the postman figure it out.
You don't know how true that is. I know someone who used to work on systems for automated reading of postal labels and routing of letters and parcels based on that (he might still be doing that, building post sorting machines for post offices) and he said that it was incredibly hard. He particularly noted that the UK was especially bad, as there is no standard address form (though we do have detailed postal codes to make things easier, and they're in common use). Ultimately, the best policy is indeed to just put whatever the user gave you on the label and let the post office deal with it.
Interestingly, this is basically an extended version of the SPOT (Single Point Of Truth) principle. Though here, the point of truth is not in the application at all, but external (post office). I guess for some programmers and managers, this is too hard to swallow, so they rather do a half-assed, buggy job than not doing anything.

Re: Classic WTF: Five Wrongs Don't Make a Right

2013-01-01 16:53 • by LK (unregistered)
Of course TRWTF is that he replaces the valid characters in that string with spaces instead of empty strings. So he needs the 2nd loop to check each character instead of checking if the string is empty... :-)

Re: Classic WTF: Five Wrongs Don't Make a Right

2013-01-01 16:57 • by fjf (unregistered)
398216 in reply to 398215
LK:
Of course TRWTF is that he replaces the valid characters in that string with spaces instead of empty strings. So he needs the 2nd loop to check each character instead of checking if the string is empty... :-)
If you think that's the RWTF, look again. For starters, the fact that he's doing a full string replacement for each valid character (whether it occurs or not) is much worse for performance. Once they support Unicode, these will be thousands.

Re: Classic WTF: Five Wrongs Don't Make a Right

2013-01-01 18:11 • by Decius (unregistered)
At least packages won't get lost in the æther.

Re: Classic WTF: Five Wrongs Don't Make a Right

2013-01-01 18:22 • by Jimmy the Greek (unregistered)
398218 in reply to 398214
fjf:
dkf:
Anonymous:
The requirement is mostly bogus, too... We've all seen the multi-page regex to (mostly) get email addresses right, and postal addresses are a lot more irregular. There is no way to construct a whitelist, except closely studying the postal guidelines of all the countries you're shipping to, going insane, then settle on a blacklist of the most esoteric Unicode blocks – it's most likely none of ⟺ or ☻ or 💂.

Then again, why bother? Just print it on the label and have the postman figure it out.
You don't know how true that is. I know someone who used to work on systems for automated reading of postal labels and routing of letters and parcels based on that (he might still be doing that, building post sorting machines for post offices) and he said that it was incredibly hard. He particularly noted that the UK was especially bad, as there is no standard address form (though we do have detailed postal codes to make things easier, and they're in common use). Ultimately, the best policy is indeed to just put whatever the user gave you on the label and let the post office deal with it.
Interestingly, this is basically an extended version of the SPOT (Single Point Of Truth) principle. Though here, the point of truth is not in the application at all, but external (post office). I guess for some programmers and managers, this is too hard to swallow, so they rather do a half-assed, buggy job than not doing anything.

Generally, it is best to keep user data as is for things like this.
Who are the experts in delivering to (hopefully) the right address - a programmer who thinks he understands addresses or a Post Office who deals with addresses every day? Of course, there may be some sense in ensuring there's no data injection, but beyond that the validity of the data requires an expert to assess it - so short of the the PO providing explicit rules (alla the pdf link someone posted) on how the address is parsed, the address should be left up to them to deal with....

Re: Classic WTF: Five Wrongs Don't Make a Right

2013-01-01 19:34 • by Worf (unregistered)
There is only one field that will be present on ALL postal addresses - the country. It's often omitted (and thus local is assumed), but it's present in all addresses.

And this makes it a lot easier. If the country is your own, most post offices offer an address validation system - either online or offline subscription which will contain every valid address in the country. You can use it to validate in-country addresses.

FOr out of country addresses, the postal service looks at the country field and routes it there and lets the local post office handle it.

And let's not forget about Mojibake making things even more interesting.

Re: Classic WTF: Five Wrongs Don't Make a Right

2013-01-01 20:02 • by A. Nonymous (unregistered)
398220 in reply to 398157
Victor:
/** Valid signs */

You don't need to read any further than that ...


This!

Re: Classic WTF: Five Wrongs Don't Make a Right

2013-01-01 20:41 • by Some dude but not the other some dude (unregistered)
398221 in reply to 398219
Worf:
If the country is your own, most post offices offer an address validation system - either online or offline subscription which will contain every valid address in the country.

ORLY? What is most? Do you mean most post offices in a certain country, or do you mean most postal sevices/systems?

Pretty sure they don't in my country....

Re: Classic WTF: Five Wrongs Don't Make a Right

2013-01-02 01:33 • by Norman Diamond (unregistered)
398222 in reply to 398219
Worf:
There is only one field that will be present on ALL postal addresses - the country.
I wonder. When sending letters to Hong Kong now, I write Hong Kong, China. But in the past I didn't write Hong Kong, UK, I just wrote Hong Kong. I write Puerto Rico, USA, but if I were writing to Guam I'm not sure if I would write USA.

Yahoo auctions resemble eBay. When I give my address to sellers, I omit the country because it's assumed that everyone is in Japan, and in case anyone ever doubted because of my foreign name they'd see my address starting with a postal code and 東京都 (Tokyo). Well, one time a seller shipped from China. They didn't insert 日本国 (Japan) which would go at the beginning in Chinese or Japanese order or at the end in common international addressing order. They just copied my address and mailed the package from China. The Chinese post office figured out what country Tokyo is in. (That predated war moves on the Senkaku islands. Who knows if they'd be cooperate today.)

Re: Classic WTF: Five Wrongs Don't Make a Right

2013-01-02 04:27 • by argle bargle (unregistered)
398223 in reply to 398209
But a blacklist would have been easier to get right since it would have been a lot shorter than a whitelist.


In the name of all that is holy, stay far away from me. Blacklists are a great way to ensure that your code is insecure. The fact that it may be easier to get right doesn't make it the right option. The submitter's code is terrible, but only because it is redundant, difficult to maintain, and needlessly inefficient. Doing it with a blacklist would make it redundant, difficult to maintain, inefficient AND insecure.

Re: Classic WTF: Five Wrongs Don't Make a Right

2013-01-02 05:03 • by Jon Haugsand (unregistered)
398225 in reply to 398204
Norman Diamond:
Foo Bar:
If Cedille, Eszett, and Y acute are all considered valid address characters, either the company expects to ship all over Europe, or the "programmer" is having too much fun with keyboard symbols.
Not really. The company expects to ship to Scandinavia and Germany but not to Greece, Turkey, and some Slavic countries.


Actually, not Norway and Denmark as the letters 'Æ' and 'Ø' are missing, e.g. "Færøy", http://www.faeroy.no/.

/Jon
« PrevPage 1 | Page 2Next »

Add Comment