Date: Thu, 23 Mar 2017 02:36:51 +0000 (UTC) From: Warner Losh <imp@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r315773 - head/sbin/devd Message-ID: <201703230236.v2N2apvX051799@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: imp Date: Thu Mar 23 02:36:51 2017 New Revision: 315773 URL: https://svnweb.freebsd.org/changeset/base/315773 Log: 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 Modified: head/sbin/devd/devd.cc head/sbin/devd/devd.hh Modified: head/sbin/devd/devd.cc ============================================================================== --- head/sbin/devd/devd.cc Thu Mar 23 02:33:27 2017 (r315772) +++ head/sbin/devd/devd.cc Thu Mar 23 02:36:51 2017 (r315773) @@ -411,6 +411,32 @@ var_list::is_set(const string &var) cons 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 * 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 *&l 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'; Modified: head/sbin/devd/devd.hh ============================================================================== --- head/sbin/devd/devd.hh Thu Mar 23 02:33:27 2017 (r315772) +++ head/sbin/devd/devd.hh Thu Mar 23 02:36:51 2017 (r315773) @@ -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; };
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201703230236.v2N2apvX051799>