diff options
author | Warner Losh <imp@FreeBSD.org> | 2017-03-23 02:36:51 +0000 |
---|---|---|
committer | Warner Losh <imp@FreeBSD.org> | 2017-03-23 02:36:51 +0000 |
commit | 192af3b7c375fdeab9fcdf07e16ba63bb31fb338 (patch) | |
tree | 96ffbb23fcbe75f9cc0aa4bfab986b9cbad07e8a /sbin/devd/devd.cc | |
parent | 5dd71be557a111f23ac77bc7ba59efdc225c2886 (diff) | |
download | src-192af3b7c375fdeab9fcdf07e16ba63bb31fb338.tar.gz src-192af3b7c375fdeab9fcdf07e16ba63bb31fb338.zip |
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
Notes
Notes:
svn path=/head/; revision=315773
Diffstat (limited to 'sbin/devd/devd.cc')
-rw-r--r-- | sbin/devd/devd.cc | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/sbin/devd/devd.cc b/sbin/devd/devd.cc index baeb472a96f6..d37f0ee66c9e 100644 --- a/sbin/devd/devd.cc +++ b/sbin/devd/devd.cc @@ -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'; |