annotate src/xspf/urlencode.c @ 439:84029a5250c1 trunk

[svn] - status icon plugin: made a tooltip popup that displays metadata of the current song
author giacomo
date Tue, 16 Jan 2007 10:34:12 -0800
parents 1983383db0f5
children 9549fea94794
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
95
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
1 /* the original code was taken from wget-1.10.2 */
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
2
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
3 #include <stdio.h>
279
1983383db0f5 [svn] build fixes:
yaz
parents: 95
diff changeset
4 #include <stdlib.h>
95
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
5 #include <string.h>
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
6 #include <glib.h>
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
7 #include <ctype.h>
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
8 #include "urlencode.h"
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
9
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
10 enum {
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
11 /* rfc1738 reserved chars + "$" and ",". */
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
12 urlchr_reserved = 1,
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
13
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
14 /* rfc1738 unsafe chars, plus non-printables. */
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
15 urlchr_unsafe = 2
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
16 };
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
17
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
18 #define urlchr_test(c, mask) (urlchr_table[(unsigned char)(c)] & (mask))
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
19 #define URL_RESERVED_CHAR(c) urlchr_test(c, urlchr_reserved)
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
20 #define URL_UNSAFE_CHAR(c) urlchr_test(c, urlchr_unsafe)
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
21 #define XNUM_TO_DIGIT(x) ("0123456789ABCDEF"[x] + 0)
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
22 #define ISXDIGIT(x) (isxdigit((unsigned char)(x)))
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
23 #define X2DIGITS_TO_NUM(h1, h2) ((XDIGIT_TO_NUM (h1) << 4) + XDIGIT_TO_NUM (h2))
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
24 #define XDIGIT_TO_NUM(h) ((h) < 'A' ? (h) - '0' : toupper (h) - 'A' + 10)
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
25
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
26 /* Shorthands for the table: */
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
27 #define R urlchr_reserved
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
28 #define U urlchr_unsafe
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
29 #define RU R|U
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
30
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
31 static const unsigned char urlchr_table[256] =
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
32 {
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
33 U, U, U, U, U, U, U, U, /* NUL SOH STX ETX EOT ENQ ACK BEL */
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
34 U, U, U, U, U, U, U, U, /* BS HT LF VT FF CR SO SI */
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
35 U, U, U, U, U, U, U, U, /* DLE DC1 DC2 DC3 DC4 NAK SYN ETB */
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
36 U, U, U, U, U, U, U, U, /* CAN EM SUB ESC FS GS RS US */
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
37 U, 0, U, RU, R, U, R, 0, /* SP ! " # $ % & ' */
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
38 0, 0, 0, R, R, 0, 0, R, /* ( ) * + , - . / */
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
39 0, 0, 0, 0, 0, 0, 0, 0, /* 0 1 2 3 4 5 6 7 */
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
40 0, 0, RU, R, U, R, U, R, /* 8 9 : ; < = > ? */
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
41 RU, 0, 0, 0, 0, 0, 0, 0, /* @ A B C D E F G */
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
42 0, 0, 0, 0, 0, 0, 0, 0, /* H I J K L M N O */
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
43 0, 0, 0, 0, 0, 0, 0, 0, /* P Q R S T U V W */
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
44 0, 0, 0, RU, U, RU, U, 0, /* X Y Z [ \ ] ^ _ */
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
45 U, 0, 0, 0, 0, 0, 0, 0, /* ` a b c d e f g */
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
46 0, 0, 0, 0, 0, 0, 0, 0, /* h i j k l m n o */
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
47 0, 0, 0, 0, 0, 0, 0, 0, /* p q r s t u v w */
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
48 0, 0, 0, U, U, U, 0, U, /* x y z { | } ~ DEL */
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
49
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
50 U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U,
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
51 U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U,
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
52 U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U,
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
53 U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U,
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
54
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
55 U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U,
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
56 U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U,
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
57 U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U,
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
58 U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U,
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
59 };
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
60 #undef R
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
61 #undef U
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
62 #undef RU
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
63
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
64 /* URL-unescape the string S.
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
65
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
66 This is done by transforming the sequences "%HH" to the character
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
67 represented by the hexadecimal digits HH. If % is not followed by
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
68 two hexadecimal digits, it is inserted literally.
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
69
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
70 The transformation is done in place. If you need the original
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
71 string intact, make a copy before calling this function. */
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
72
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
73 char *
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
74 xspf_url_decode (const char *s)
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
75 {
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
76 char *copy = strdup(s);
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
77 char *t = copy; /* t - tortoise */
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
78 char *h = copy; /* h - hare */
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
79
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
80 for (; *h; h++, t++)
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
81 {
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
82 if (*h != '%')
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
83 {
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
84 copychar:
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
85 *t = *h;
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
86 }
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
87 else
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
88 {
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
89 char c;
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
90 /* Do nothing if '%' is not followed by two hex digits. */
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
91 if (!h[1] || !h[2] || !(ISXDIGIT (h[1]) && ISXDIGIT (h[2])))
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
92 goto copychar;
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
93 c = X2DIGITS_TO_NUM (h[1], h[2]);
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
94 /* Don't unescape %00 because there is no way to insert it
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
95 into a C string without effectively truncating it. */
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
96 if (c == '\0')
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
97 goto copychar;
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
98 *t = c;
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
99 h += 2;
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
100 }
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
101 }
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
102 *t = '\0';
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
103 return copy;
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
104 }
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
105
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
106 /* The core of url_escape_* functions. Escapes the characters that
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
107 match the provided mask in urlchr_table.
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
108
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
109 If ALLOW_PASSTHROUGH is non-zero, a string with no unsafe chars
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
110 will be returned unchanged. If ALLOW_PASSTHROUGH is zero, a
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
111 freshly allocated string will be returned in all cases. */
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
112
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
113 static char *
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
114 url_escape_1 (const char *s, unsigned char mask, int allow_passthrough)
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
115 {
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
116 const char *p1;
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
117 char *p2, *newstr;
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
118 int newlen;
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
119 int addition = 0;
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
120
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
121 for (p1 = s; *p1; p1++)
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
122 if (urlchr_test (*p1, mask))
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
123 addition += 2; /* Two more characters (hex digits) */
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
124
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
125 if (!addition)
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
126 return allow_passthrough ? (char *)s : strdup (s);
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
127
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
128 newlen = (p1 - s) + addition;
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
129 newstr = (char *)malloc (newlen + 1);
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
130
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
131 p1 = s;
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
132 p2 = newstr;
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
133 while (*p1)
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
134 {
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
135 /* Quote the characters that match the test mask. */
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
136 if (urlchr_test (*p1, mask))
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
137 {
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
138 unsigned char c = *p1++;
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
139 *p2++ = '%';
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
140 *p2++ = XNUM_TO_DIGIT (c >> 4);
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
141 *p2++ = XNUM_TO_DIGIT (c & 0xf);
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
142 }
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
143 else
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
144 *p2++ = *p1++;
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
145 }
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
146 g_return_if_fail (p2 - newstr == newlen);
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
147 *p2 = '\0';
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
148
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
149 return newstr;
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
150 }
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
151
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
152 /* URL-escape the unsafe characters (see urlchr_table) in a given
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
153 string, returning a freshly allocated string. */
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
154
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
155 char *
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
156 xspf_url_encode (const char *s)
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
157 {
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
158 return url_escape_1 (s, urlchr_unsafe, 0);
b5a1b762f586 [svn] - xspf now uses url encoding for location entry.
yaz
parents:
diff changeset
159 }