@@ -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