Skip to content

Commit 9ecdcdd

Browse files
committed
Refactor locale parsing
Fixes validation of the locale string, too.
1 parent 2fb74bf commit 9ecdcdd

File tree

1 file changed

+45
-20
lines changed

1 file changed

+45
-20
lines changed

src/desktopfilereader.cpp

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -92,35 +92,60 @@ namespace linuxdeploy {
9292
if (key.empty())
9393
throw ParseError("Empty keys are not allowed");
9494

95-
// keys may only contain A-Za-z- characters according to specification
96-
for (const char c : key) {
95+
// check if the string is a potentially localized string
96+
// if yes, parse name and locale out, and check them for validity
97+
std::string entryName, entryLocale;
98+
99+
auto openingBracketPos = key.find('[');
100+
if (openingBracketPos != std::string::npos) {
101+
entryName = key.substr(0, key.find('['));
102+
entryLocale = key.substr(openingBracketPos, key.size());
103+
} else {
104+
entryName = key;
105+
}
106+
107+
// name may only contain A-Za-z- characters according to specification
108+
for (const char c : entryName) {
97109
if (!(
98110
(c >= 'A' && c <= 'Z') ||
99111
(c >= 'a' && c <= 'z') ||
100112
(c >= '0' && c <= '9') ||
101-
(c == '-') ||
102-
// FIXME: remove this hack after introducing localization support to
103-
// conform to desktop file spec again
104-
(c == '[') || (c == ']')
113+
(c == '-')
105114
)
106115
) {
107-
throw ParseError(
108-
"Key " + key + " contains invalid character " + std::string{c}
109-
);
116+
throw ParseError("Key " + key + " contains invalid character " + std::string{c});
110117
}
111118
}
112119

113-
if (std::count(key.begin(), key.end(), '[') > 1 ||
114-
std::count(key.begin(), key.end(), ']') > 1 ||
115-
// make sure that both [ and ] are present
116-
(key.find('[') != std::string::npos && key.find(']') == std::string::npos) ||
117-
(key.find('[') == std::string::npos && key.find(']') != std::string::npos) ||
118-
// disallow empty locale names
119-
(key.find('[') != std::string::npos && key.find(']') != std::string::npos && (key.find(']') - key.find('[')) < 2) ||
120-
// ensure order of [ and ]
121-
(key.find('[') != std::string::npos && key.find('[' ) > key.find(']'))
122-
) {
123-
throw ParseError("Invalid localization syntax used in key " + key);
120+
// validate locale part
121+
if (!entryLocale.empty()) {
122+
static const auto errorPrefix = "Invalid localization syntax used in key " + key + ": ";
123+
124+
if (std::count(entryLocale.begin(), entryLocale.end(), '[') != 1 ||
125+
std::count(entryLocale.begin(), entryLocale.end(), '[') != 1) {
126+
throw ParseError(errorPrefix + "mismatching [] brackets");
127+
}
128+
129+
// just for clarification: _this_ should never happen, given how the strings are
130+
// split above
131+
if (entryLocale.find('[') != 0) {
132+
throw ParseError(errorPrefix + "invalid [ position");
133+
}
134+
135+
if (entryLocale.find(']') != entryLocale.size()-1) {
136+
throw ParseError(errorPrefix + "invalid ] position");
137+
}
138+
139+
// locale may only contain A-Za-z- characters according to specification
140+
for (const char c : entryName) {
141+
if (!(
142+
(c >= 'A' && c <= 'Z') ||
143+
(c >= 'a' && c <= 'z') ||
144+
(c == '_') || (c == '@')
145+
)) {
146+
throw ParseError("Key " + key + " contains invalid character " + std::string{c});
147+
}
148+
}
124149
}
125150

126151
auto& section = sections[currentSectionName];

0 commit comments

Comments
 (0)