diff --git a/client/hostinfo_unix.cpp b/client/hostinfo_unix.cpp index 88f0dad4b8..9eab4c3db7 100644 --- a/client/hostinfo_unix.cpp +++ b/client/hostinfo_unix.cpp @@ -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; } diff --git a/client/hostinfo_unix_test.cpp b/client/hostinfo_unix_test.cpp index 72a3c38a01..3bb56304e3 100644 --- a/client/hostinfo_unix_test.cpp +++ b/client/hostinfo_unix_test.cpp @@ -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; } diff --git a/lib/str_util.cpp b/lib/str_util.cpp index 36c4748bbe..2e37a527f5 100644 --- a/lib/str_util.cpp +++ b/lib/str_util.cpp @@ -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) { diff --git a/lib/str_util.h b/lib/str_util.h index a139690174..24746156c4 100644 --- a/lib/str_util.h +++ b/lib/str_util.h @@ -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*);