Implement quote escaping. String values may now contain " if you

it is preceded by \.

foo="I \"like\" C++"

gives the value 'I "like" C++' to the variable 'foo'. If a character
other than " follows the \, both the \ and that character are passed
through.

Differential Revision: https://reviews.freebsd.org/D6286
Sponsored by: Netflix
This commit is contained in:
Warner Losh 2017-03-23 02:36:51 +00:00
parent 5dd71be557
commit 192af3b7c3
2 changed files with 37 additions and 3 deletions

View File

@ -411,6 +411,32 @@ var_list::is_set(const string &var) const
return (_vars.find(var) != _vars.end());
}
/** fix_value
*
* Removes quoted characters that have made it this far. \" are
* converted to ". For all other characters, both \ and following
* character. So the string 'fre\:\"' is translated to 'fred\:"'.
*/
const std::string &
var_list::fix_value(const std::string &val) const
{
char *tmp, *dst;
const char *src;
std::string *rv;
dst = tmp = new char[val.length()];
src = val.c_str();
while (*src) {
if (*src == '\\' && src[1] == '"')
src++;
else
*dst++ = *src++;
}
rv = new string(tmp);
delete tmp;
return *rv;
}
void
var_list::set_variable(const string &var, const string &val)
{
@ -420,9 +446,9 @@ var_list::set_variable(const string &var, const string &val)
* can consume excessive amounts of systime inside of connect(). Only
* log when we're in -d mode.
*/
_vars[var] = fix_value(val);
if (no_daemon)
devdlog(LOG_DEBUG, "setting %s=%s\n", var.c_str(), val.c_str());
_vars[var] = val;
}
void
@ -711,8 +737,13 @@ config::chop_var(char *&buffer, char *&lhs, char *&rhs) const
if (*walker == '"') {
walker++; // skip "
rhs = walker;
while (*walker && *walker != '"')
while (*walker && *walker != '"') {
// Skip \" ... We leave it in the string and strip the \ later.
// due to the super simplistic parser that we have here.
if (*walker == '\\' && walker[1] == '"')
walker++;
walker++;
}
if (*walker != '"')
return (false);
rhs[-2] = '\0';

View File

@ -48,14 +48,17 @@ public:
* no variable of %var is set, then %bogus will be returned.
*/
const std::string &get_variable(const std::string &var) const;
/** Is there a variable of %var set in thi stable?
/** Is there a variable of %var set in this table?
*/
bool is_set(const std::string &var) const;
/** A completely bogus string.
*/
static const std::string bogus;
static const std::string nothing;
private:
const std::string &fix_value(const std::string &val) const;
std::map<std::string, std::string> _vars;
};