Skip to content

Commit 4723821

Browse files
authored
protect against private use region codes in the regions field of a langtag (#1382)
1 parent 66765a5 commit 4723821

File tree

2 files changed

+75
-11
lines changed

2 files changed

+75
-11
lines changed

SIL.WritingSystems.Tests/LanguageLookupTests.cs

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ public void SuggestLanguages_ExactCountryMatch_SortsAboveFuzzyNames()
232232
{
233233
new AllTagEntry { name = "Crimean Tatar", tag="crh-Cyrl-UA", region = "UA", regions = new List<string> {"BG", "KG", "US"}},
234234
new AllTagEntry { name = "English", tag = "en", region = "US"},
235-
new AllTagEntry {name = "French", tag = "fr", region = "FR", regions = new List<string> {"FR", "US"}}
235+
new AllTagEntry {name = "French", tag = "fr", region = "FR", regions = new List<string> {"FR", "US"}}
236236
};
237237
var lookup = new LanguageLookup(entries);
238238
var languages = lookup.SuggestLanguages("United States");
@@ -314,7 +314,7 @@ public void SuggestLanguages_LanguageIsOromo_HasNoPejorativeLanguageNames()
314314
languages = lookup.SuggestLanguages("hae").ToArray();
315315
// “Kwottu” (pej.), “Qottu” (pej.), “Quottu” (pej.), “Qwottu” (pej.)
316316
Assert.False(languages.Any(l => l.Names.Contains("ottu")));
317-
// “Qotu Oromo” (pej.),
317+
// “Qotu Oromo” (pej.),
318318
Assert.False(languages.Any(l => l.Names.Contains("Qotu")));
319319
}
320320

@@ -439,6 +439,59 @@ public void SuggestLanguages_SearchingForSign_ReturnsSignLanguages()
439439
}
440440
}
441441

442+
[Test]
443+
public void EnsureTagsWithPrivateUseRegions_WorksAsExpected()
444+
{
445+
var entries = new List<AllTagEntry>
446+
{
447+
new AllTagEntry
448+
{
449+
full = "sq-Todr-AL",
450+
iana = new List<string>() { "Albanian" },
451+
iso639_3 = "sqi",
452+
name = "Albanian",
453+
names = new List<string>()
454+
{
455+
"Albanian, Tosk",
456+
"Arnaut",
457+
"Arvanitika",
458+
"Camerija",
459+
"Shkip",
460+
"Shqip",
461+
"Skchip",
462+
"Tosk",
463+
"Zhgabe"
464+
},
465+
466+
region = "AL",
467+
regionName = "Albania",
468+
regions = new List<string>()
469+
{
470+
"AT",
471+
"AU",
472+
"BE",
473+
"DE",
474+
"GR",
475+
"HR",
476+
"IT",
477+
"MK",
478+
"MN",
479+
"RS",
480+
"SE",
481+
"TR",
482+
"UA",
483+
"US",
484+
"XK"
485+
},
486+
sldr = false,
487+
tag = "sq-Todr",
488+
tags = new List<string>() { "als-Todr", "als-Todr-AL" },
489+
}
490+
};
491+
492+
Assert.DoesNotThrow(() => new LanguageLookup(entries, false));
493+
}
494+
442495
[Test]
443496
public void EnsureDefaultTags_WorksAsExpected()
444497
{

SIL.WritingSystems/LanguageLookup.cs

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -152,14 +152,7 @@ private bool AddLanguage(string code, string threelettercode, string full = null
152152
}
153153
else if (StandardSubtags.IsValidIso3166RegionCode(region))
154154
{
155-
if (StandardSubtags.IsPrivateUseRegionCode(region))
156-
{
157-
primaryCountry = region == "XK" ? "Kosovo" : "Unknown private use";
158-
}
159-
else
160-
{
161-
primaryCountry = StandardSubtags.RegisteredRegions[region].Name; // convert to full region name
162-
}
155+
primaryCountry = RegionToCountry(region);
163156
}
164157
else
165158
{
@@ -180,7 +173,7 @@ private bool AddLanguage(string code, string threelettercode, string full = null
180173
{
181174
if (!country.Contains('?') && country != "")
182175
{
183-
language.Countries.Add(StandardSubtags.RegisteredRegions[country].Name);
176+
language.Countries.Add(RegionToCountry(country));
184177
}
185178
}
186179
}
@@ -258,6 +251,24 @@ private bool AddLanguage(string code, string threelettercode, string full = null
258251
return true;
259252
}
260253

254+
private static string RegionToCountry(string region)
255+
{
256+
string country;
257+
if (StandardSubtags.IsPrivateUseRegionCode(region))
258+
{
259+
country = region == "XK" ? "Kosovo" : "Unknown private use";
260+
}
261+
else if (StandardSubtags.RegisteredRegions.TryGet(region, out var regionTag))
262+
{
263+
country = regionTag.Name; // convert to full region name
264+
}
265+
else
266+
{
267+
country = "Invalid region " + region;
268+
}
269+
return country;
270+
}
271+
261272

262273
/// <summary>
263274
/// For testing; used to detect if we need more special cases where LanguageDataIndex()

0 commit comments

Comments
 (0)