Client: unescape special characters read from /etc/os-release

The information in /etc/os-release is allowed to contain some special shell characters that are escaped so the file can be easily read by shell scripts. We store this information in the database and do our own escaping. The strip_quotes() function now does not remove quotes from the end of the string if they are escaped.
This commit is contained in:
Christian Beer 2016-09-06 08:39:01 +02:00
parent 0e3bc65fb3
commit eef4d45db5
4 changed files with 84 additions and 8 deletions

View File

@ -1654,6 +1654,7 @@ int HOST_INFO::get_os_info() {
found_something = true;
safe_strcpy(buf2, strchr(buf, '=') + 1);
strip_quotes(buf2);
unescape_os_release(buf2);
safe_strcpy(dist_pretty, buf2);
continue;
}
@ -1661,6 +1662,7 @@ int HOST_INFO::get_os_info() {
found_something = true;
safe_strcpy(buf2, strchr(buf, '=') + 1);
strip_quotes(buf2);
unescape_os_release(buf2);
safe_strcpy(dist_name, buf2);
continue;
}
@ -1668,6 +1670,7 @@ int HOST_INFO::get_os_info() {
found_something = true;
safe_strcpy(buf2, strchr(buf, '=') + 1);
strip_quotes(buf2);
unescape_os_release(buf2);
safe_strcpy(dist_version, buf2);
continue;
}
@ -1676,6 +1679,7 @@ int HOST_INFO::get_os_info() {
found_something = true;
safe_strcpy(buf2, strchr(buf, '=') + 1);
strip_quotes(buf2);
unescape_os_release(buf2);
safe_strcpy(dist_codename, buf2);
continue;
}

View File

@ -97,8 +97,10 @@ void strip_quotes(char *str) {
while (n>0) {
n--;
if (str[n] == '"' || str[n] == '\'') {
str[n] = 0;
continue;
if (str[n-1] != '\\') {
str[n] = 0;
continue;
}
}
if (!isascii(str[n])) break;
if (!isspace(str[n])) break;
@ -121,8 +123,10 @@ void strip_quotes(string& str) {
int n = (int) str.length();
while (n>0) {
if (str[n-1] == '"' || str[n-1] == '\'') {
n--;
continue;
if (str[n-2] != '\\') {
n--;
continue;
}
}
if (!isascii(str[n-1])) break;
if (!isspace(str[n-1])) break;
@ -131,6 +135,34 @@ void strip_quotes(string& str) {
str.erase(n, str.length()-n);
}
void unescape_os_release(char* buf) {
char* out = buf;
char* in = buf;
while (*in) {
if (*in != '\\') {
*out++ = *in++;
} else if (*(in+1) == '$') {
*out++ = '$';
in += 2;
} else if (*(in+1) == '\'') {
*out++ = '\'';
in += 2;
} else if (*(in+1) == '"') {
*out++ = '"';
in += 2;
} else if (*(in+1) == '\\') {
*out++ = '\\';
in += 2;
} else if (*(in+1) == '`') {
*out++ = '`';
in += 2;
} else {
*out++ = *in++;
}
}
*out = 0;
}
int main(void) {
char buf[256], features[1024], model_buf[1024];
bool vendor_found=false, model_found=false;
@ -491,10 +523,12 @@ int main(void) {
if (f) {
while (fgets(buf, 256, f)) {
strip_whitespace(buf);
// check if substr is at the beginning of the line
if ( strstr(buf, "PRETTY_NAME=") == buf ) {
found_something = true;
safe_strcpy(buf2, strchr(buf, '=') + 1);
strip_quotes(buf2);
unescape_os_release(buf2);
safe_strcpy(dist_pretty, buf2);
continue;
}
@ -502,6 +536,7 @@ int main(void) {
found_something = true;
safe_strcpy(buf2, strchr(buf, '=') + 1);
strip_quotes(buf2);
unescape_os_release(buf2);
safe_strcpy(dist_name, buf2);
continue;
}
@ -509,6 +544,7 @@ int main(void) {
found_something = true;
safe_strcpy(buf2, strchr(buf, '=') + 1);
strip_quotes(buf2);
unescape_os_release(buf2);
safe_strcpy(dist_version, buf2);
continue;
}
@ -517,6 +553,7 @@ int main(void) {
found_something = true;
safe_strcpy(buf2, strchr(buf, '=') + 1);
strip_quotes(buf2);
unescape_os_release(buf2);
safe_strcpy(dist_codename, buf2);
continue;
}

View File

@ -352,8 +352,10 @@ void strip_quotes(char *str) {
while (n>0) {
n--;
if (str[n] == '"' || str[n] == '\'') {
str[n] = 0;
continue;
if (str[n-1] != '\\') {
str[n] = 0;
continue;
}
}
if (!isascii(str[n])) break;
if (!isspace(str[n])) break;
@ -376,8 +378,10 @@ void strip_quotes(string& str) {
int n = (int) str.length();
while (n>0) {
if (str[n-1] == '"' || str[n-1] == '\'') {
n--;
continue;
if (str[n-2] != '\\') {
n--;
continue;
}
}
if (!isascii(str[n-1])) break;
if (!isspace(str[n-1])) break;
@ -386,6 +390,36 @@ void strip_quotes(string& str) {
str.erase(n, str.length()-n);
}
// This only unescapes some special shell characters used in /etc/os-release
// see https://www.freedesktop.org/software/systemd/man/os-release.html
void unescape_os_release(char* buf) {
char* out = buf;
char* in = buf;
while (*in) {
if (*in != '\\') {
*out++ = *in++;
} else if (*(in+1) == '$') {
*out++ = '$';
in += 2;
} else if (*(in+1) == '\'') {
*out++ = '\'';
in += 2;
} else if (*(in+1) == '"') {
*out++ = '"';
in += 2;
} else if (*(in+1) == '\\') {
*out++ = '\\';
in += 2;
} else if (*(in+1) == '`') {
*out++ = '`';
in += 2;
} else {
*out++ = *in++;
}
}
*out = 0;
}
char* time_to_string(double t) {
static char buf[100];
if (!t) {

View File

@ -31,6 +31,7 @@ extern void strip_whitespace(char *str);
extern void strip_whitespace(std::string&);
extern void strip_quotes(char *str);
extern void strip_quotes(std::string&);
extern void unescape_os_release(char *str);
extern char* time_to_string(double);
extern char* precision_time_to_string(double);
extern void secs_to_hmsf(double, char*);