/** * g_shell_unquote: * @quoted_string: shell-quoted string * @error: error return location or NULL * * Unquotes a string as the shell (/bin/sh) would. Only handles * quotes; if a string contains file globs, arithmetic operators, * variables, backticks, redirections, or other special-to-the-shell * features, the result will be different from the result a real shell * would produce (the variables, backticks, etc. will be passed * through literally instead of being expanded). This function is * guaranteed to succeed if applied to the result of * g_shell_quote(). If it fails, it returns %NULL and sets the * error. The @quoted_string need not actually contain quoted or * escaped text; g_shell_unquote() simply goes through the string and * unquotes/unescapes anything that the shell would. Both single and * double quotes are handled, as are escapes including escaped * newlines. The return value must be freed with g_free(). Possible * errors are in the #G_SHELL_ERROR domain. * * Shell quoting rules are a bit strange. Single quotes preserve the * literal string exactly. escape sequences are not allowed; not even * \' - if you want a ' in the quoted text, you have to do something * like 'foo'\''bar'. Double quotes allow $, `, ", \, and newline to * be escaped with backslash. Otherwise double quotes preserve things * literally. * * Returns: an unquoted string **/ std::string g_shell_unquote (std::string& quoted_string) { std::string unquoted = quoted_string; std::string retval; std::string::iterator start = quoted_string.begin(); /* The loop allows cases such as * "foo"blah blah'bar'woo foo"baz"la la la\'\''foo' */ while(start != quoted_string.end()) { /* Append all non-quoted chars, honoring backslash escape */ while ((start != quoted_string.end()) && not (*start == '"' or *start == '\'')) { if (*start == '\\') { /* all characters can get escaped by backslash, * except newline, which is removed if it follows * a backslash outside of quotes */ start ++; if (start != quoted_string.end()) { if (*start != '\n') { retval += *start; } start ++; } } else { retval += *start; start++; } } if (start != quoted_string.end()) { std::pair<std::string, std::string::iterator> res = unquote_string_inplace (start, quoted_string.end()); retval += res.first; start = res.second; } } return retval; }
/** * Unquotes a string as the shell (/bin/sh) would. Only handles * quotes; if a string contains file globs, arithmetic operators, * variables, backticks, redirections, or other special-to-the-shell * features, the result will be different from the result a real shell * would produce (the variables, backticks, etc. will be passed * through literally instead of being expanded). This function is * guaranteed to succeed if applied to the result of * _dbus_shell_quote(). If it fails, it returns %NULL. * The @quoted_string need not actually contain quoted or * escaped text; _dbus_shell_unquote() simply goes through the string and * unquotes/unescapes anything that the shell would. Both single and * double quotes are handled, as are escapes including escaped * newlines. The return value must be freed with dbus_free(). * * Shell quoting rules are a bit strange. Single quotes preserve the * literal string exactly. escape sequences are not allowed; not even * \' - if you want a ' in the quoted text, you have to do something * like 'foo'\''bar'. Double quotes allow $, `, ", \, and newline to * be escaped with backslash. Otherwise double quotes preserve things * literally. * * @quoted_string: shell-quoted string **/ char* _dbus_shell_unquote (const char *quoted_string) { char *unquoted; char *end; char *start; char *ret; DBusString retval; unquoted = _dbus_strdup (quoted_string); if (unquoted == NULL) return NULL; start = unquoted; end = unquoted; if (!_dbus_string_init (&retval)) { dbus_free (unquoted); return NULL; } /* The loop allows cases such as * "foo"blah blah'bar'woo foo"baz"la la la\'\''foo' */ while (*start) { /* Append all non-quoted chars, honoring backslash escape */ while (*start && !(*start == '"' || *start == '\'')) { if (*start == '\\') { /* all characters can get escaped by backslash, * except newline, which is removed if it follows * a backslash outside of quotes */ ++start; if (*start) { if (*start != '\n') { if (!_dbus_string_append_byte (&retval, *start)) goto error; } ++start; } } else { if (!_dbus_string_append_byte (&retval, *start)) goto error; ++start; } } if (*start) { if (!unquote_string_inplace (start, &end)) goto error; else { if (!_dbus_string_append (&retval, start)) goto error; start = end; } } } ret = _dbus_strdup (_dbus_string_get_data (&retval)); if (!ret) goto error; dbus_free (unquoted); _dbus_string_free (&retval); return ret; error: dbus_free (unquoted); _dbus_string_free (&retval); return NULL; }