Fix bugs in format::desktop_entry

This commit is contained in:
Sasha Koshka 2024-10-20 18:40:35 -04:00
parent 02cf7ffb05
commit f401ad26df

View File

@ -1,3 +1,4 @@
use ascii;
use bufio; use bufio;
use encoding::utf8; use encoding::utf8;
use errors; use errors;
@ -43,7 +44,7 @@ export fn next(this: *scanner) (line | io::EOF | error) = {
// group header // group header
let header = parse_group_header(text)?; let header = parse_group_header(text)?;
free(this.group); free(this.group);
this.group = header: str; this.group = strings::dup(header: str);
return header; return header;
} else { } else {
@ -89,14 +90,13 @@ fn parse_entry(line: str) (entry | error) = {
if (!strings::contains(line, '=')) return invalid_entry; if (!strings::contains(line, '=')) return invalid_entry;
let (key, valu) = strings::cut(line, "="); let (key, valu) = strings::cut(line, "=");
key = strings::ltrim(strings::rtrim(key)); key = strings::ltrim(strings::rtrim(key));
if (!validate_entry_key(key)) return invalid_entry;
let (key, local_string) = strings::cut(key, "["); let (key, local_string) = strings::cut(key, "[");
let local = if (local_string != "") { let local = if (local_string == "") {
yield locale::c; yield locale::c;
} else { } else {
local_string = strings::rtrim(local_string, ']'); local_string = strings::rtrim(local_string, ']');
if (!validate_entry_locale(local_string)) return invalid_entry; validate_entry_locale(local_string)?;
yield match(locale::parse(local_string)) { yield match(locale::parse(local_string)) {
case let local: locale::locale => yield local; case let local: locale::locale => yield local;
@ -104,6 +104,7 @@ fn parse_entry(line: str) (entry | error) = {
}; };
}; };
validate_entry_key(key)?;
return entry { return entry {
key = key, key = key,
value = valu, value = valu,
@ -112,10 +113,24 @@ fn parse_entry(line: str) (entry | error) = {
}; };
}; };
fn validate_entry_key(key: str) bool = { fn validate_entry_key(key: str) (void | error) = {
return strings::contains(key, '[', ']', '='); for (let byte .. strings::toutf8(key)) {
const ok =
(byte >= 'A' && byte <= 'Z') ||
(byte >= 'a' && byte <= 'z') ||
(byte >= '0' && byte <= '9') ||
(byte == '-');
if (!ok) return invalid_entry;
};
}; };
fn validate_entry_locale(key: str) bool = { fn validate_entry_locale(locale: str) (void | error) = {
return strings::contains(key, '[', ']', '='); for (let byte .. strings::toutf8(locale)) {
const bad =
(byte == '[') ||
(byte == ']') ||
(byte == '=') ||
!ascii::isprint(byte: rune);
if (bad) return invalid_entry;
};
}; };