replace Xalloca + strdup with Xstrdup_a
[claws.git] / src / utils.c
index c197163f38bd4bc7636b026c3b6a0d2d252c0a13..b647739478c3d5ac0db79649984bb4149d41d925 100644 (file)
@@ -653,10 +653,15 @@ void eliminate_quote(gchar *str, gchar quote_chr)
 
 void extract_quote(gchar *str, gchar quote_chr)
 {
-       register gchar *p;
+       register gchar *p, *p2;
 
        if ((str = strchr(str, quote_chr))) {
-               if ((p = strchr(str + 1, quote_chr))) {
+               p2 = str;
+               while ((p = strchr(p2 + 1, quote_chr)) && (p[-1] == '\\')) {
+                       memmove(p - 1, p, strlen(p) + 1);
+                       p2 = p - 1;
+               }
+               if(p) {
                        *p = '\0';
                        memmove(str, str + 1, p - str);
                }
@@ -1815,25 +1820,137 @@ gint execute_command_line(const gchar *cmdline, gboolean async)
        return ret;
 }
 
+static gint is_unchanged_uri_char(char c)
+{
+       switch (c) {
+               case '(':
+               case ')':
+               case ',':
+                       return 0;
+               default:
+                       return 1;
+       }
+}
+
+void encode_uri(gchar *encoded_uri, gint bufsize, const gchar *uri)
+{
+       int i;
+       int k;
+
+       k = 0;
+       for(i = 0; i < strlen(uri) ; i++) {
+               if (is_unchanged_uri_char(uri[i])) {
+                       if (k + 2 >= bufsize)
+                               break;
+                       encoded_uri[k++] = uri[i];
+               }
+               else {
+                       char * hexa = "0123456789ABCDEF";
+                       
+                       if (k + 4 >= bufsize)
+                               break;
+                       encoded_uri[k++] = '%';
+                       encoded_uri[k++] = hexa[uri[i] / 16];
+                       encoded_uri[k++] = hexa[uri[i] % 16];
+               }
+       }
+       encoded_uri[k] = 0;
+}
+
+/* Converts two-digit hexadecimal to decimal.  Used for unescaping escaped 
+ * characters
+ */
+static gint axtoi(const gchar *hexstr)
+{
+       gint hi, lo, result;
+       
+       hi = hexstr[0];
+       if ('0' <= hi && hi <= '9') {
+               hi -= '0';
+       } else
+               if ('a' <= hi && hi <= 'f') {
+                       hi -= ('a' - 10);
+               } else
+                       if ('A' <= hi && hi <= 'F') {
+                               hi -= ('A' - 10);
+                       }
+
+       lo = hexstr[1];
+       if ('0' <= lo && lo <= '9') {
+               lo -= '0';
+       } else
+               if ('a' <= lo && lo <= 'f') {
+                       lo -= ('a'-10);
+               } else
+                       if ('A' <= lo && lo <= 'F') {
+                               lo -= ('A' - 10);
+                       }
+       result = lo + (16 * hi);
+       return result;
+}
+
+
+/* Decodes URL-Encoded strings (i.e. strings in which spaces are replaced by
+ * plusses, and escape characters are used)
+ */
+
+void decode_uri(gchar *decoded_uri, const gchar *encoded_uri)
+{
+       const gchar *encoded;
+       gchar *decoded;
+
+       encoded = encoded_uri;
+       decoded = decoded_uri;
+
+       while (*encoded) {
+               if (*encoded == '%') {
+                       encoded++;
+                       if (isxdigit(encoded[0])
+                           && isxdigit(encoded[1])) {
+                               *decoded = (gchar) axtoi(encoded);
+                               decoded++;
+                               encoded += 2;
+                       }
+               }
+               else if (*encoded == '+') {
+                       *decoded = ' ';
+                       decoded++;
+                       encoded++;
+               }
+               else {
+                       *decoded = *encoded;
+                       decoded++;
+                       encoded++;
+               }
+       }
+
+       *decoded = '\0';
+}
+
+
 gint open_uri(const gchar *uri, const gchar *cmdline)
 {
        static gchar *default_cmdline = "netscape -remote openURL(%s,raise)";
        gchar buf[BUFFSIZE];
        gchar *p;
-
+       gchar encoded_uri[BUFFSIZE];
+       
        g_return_val_if_fail(uri != NULL, -1);
 
+       /* an option to choose whether to use encode_uri or not ? */
+       encode_uri(encoded_uri, BUFFSIZE, uri);
+       
        if (cmdline &&
            (p = strchr(cmdline, '%')) && *(p + 1) == 's' &&
            !strchr(p + 2, '%'))
-               g_snprintf(buf, sizeof(buf), cmdline, uri);
+               g_snprintf(buf, sizeof(buf), cmdline, encoded_uri);
        else {
                if (cmdline)
                        g_warning(_("Open URI command line is invalid: `%s'"),
                                  cmdline);
-               g_snprintf(buf, sizeof(buf), default_cmdline, uri);
+               g_snprintf(buf, sizeof(buf), default_cmdline, encoded_uri);
        }
-
+       
        execute_command_line(buf, TRUE);
 
        return 0;