aboutsummaryrefslogtreecommitdiff
path: root/sbin/devd/devd.cc
diff options
context:
space:
mode:
authorWarner Losh <imp@FreeBSD.org>2017-03-23 02:36:51 +0000
committerWarner Losh <imp@FreeBSD.org>2017-03-23 02:36:51 +0000
commit192af3b7c375fdeab9fcdf07e16ba63bb31fb338 (patch)
tree96ffbb23fcbe75f9cc0aa4bfab986b9cbad07e8a /sbin/devd/devd.cc
parent5dd71be557a111f23ac77bc7ba59efdc225c2886 (diff)
downloadsrc-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.cc35
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';