Do not replace nonexistent environment variables

References to environment variables embedded in a filename are expanded
and replaced by their value. However, if a variable does not exist, its
reference is simply erased from the filename, causing havoc (see #7801).

This has been like that since ever and cannot be changed, both for
backward compatibility and because this feature is currently used in
the Windows installer.

A possible backward compatible strategy is leaving as is the reference
to the environment variable (introduced by a $ sign) in the filename
if it does not exist. This is done in this patch, which also assumes
that an escape character is never used in a filename (inserting a $ in
the filename is easy, but I don't think one is able to easily insert
an escape character).
This commit is contained in:
Enrico Forestieri 2021-01-04 23:00:42 +01:00
parent bbffbf92ac
commit 2099dca5d3

View File

@ -683,8 +683,12 @@ string const onlyFileName(string const & fname)
// Search the string for ${VAR} and $VAR and replace VAR using getenv. // Search the string for ${VAR} and $VAR and replace VAR using getenv.
// If VAR does not exist, ${VAR} and $VAR are left as is in the string.
string const replaceEnvironmentPath(string const & path) string const replaceEnvironmentPath(string const & path)
{ {
if (!contains(path, '$'))
return path;
// ${VAR} is defined as // ${VAR} is defined as
// $\{[A-Za-z_][A-Za-z_0-9]*\} // $\{[A-Za-z_][A-Za-z_0-9]*\}
static string const envvar_br = "[$]\\{([A-Za-z_][A-Za-z_0-9]*)\\}"; static string const envvar_br = "[$]\\{([A-Za-z_][A-Za-z_0-9]*)\\}";
@ -702,14 +706,23 @@ string const replaceEnvironmentPath(string const & path)
string result = path; string result = path;
while (1) { while (1) {
smatch what; smatch what;
bool brackets = true;
if (!regex_match(result, what, envvar_br_re)) { if (!regex_match(result, what, envvar_br_re)) {
brackets = false;
if (!regex_match(result, what, envvar_re)) if (!regex_match(result, what, envvar_re))
break; break;
} }
string env_var = getEnv(what.str(2)); string env_var = getEnv(what.str(2));
if (env_var.empty()) {
// temporarily use escape (0x1B) in place of $
if (brackets)
env_var = "\e{" + what.str(2) + '}';
else
env_var = "\e" + what.str(2);
}
result = what.str(1) + env_var + what.str(3); result = what.str(1) + env_var + what.str(3);
} }
return result; return subst(result, '\e', '$');
} catch (exception const & e) { } catch (exception const & e) {
LYXERR0("Something is very wrong: " << e.what()); LYXERR0("Something is very wrong: " << e.what());
return path; return path;