Exemple #1
0
    /**
     * 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;
}