[PATCH] - improved decoding of URL special characters
Dustin Kirkland <[email protected]> Wed, 19 Oct 2005 13:19:54 -0500
| Newsgroups | gmane.comp.multimedia.xmms.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi-
I've attached a small patch that improves the decoding of URL special
characters. XMMS has long supported converting "%20" into a blank
space. However, other multibyte characters (apostrophes, parentheses,
etc) are not converted in the same manner.
I first reported this problem 2002-10-24 in a bugzilla, with a
suggested fix, but not a completed patch:
http://bugs.xmms.org/show_bug.cgi?id=1068
I later reworked the patch as below, which has worked very well for me
for several years now. I would like to see this accepted in the
upstream XMMS.
There are two helper functions that are added by this patch, axtoi()
and urldecodestr() in urldecode.c.
The first, axtoi() takes a string pointer as input and returns an
integer. It will calculate the decimal integer value of a 2-character
hexadecimal string, such as "20" -> 32, or "2A" -> 42.
The second, urldecodestr(), takes a pointer to a string pointer, and
searches through the string for the % character. When this is found,
the location is passed to the axtoi() function, which will attempt to
convert the following two characters to an integer. If it is able to
do so, the "%XX" three characters in the string are replaced with the
appropriate character that was url-encoded. The string passed in is
modified (rather than mallocing a new pointer).
Finally, the few places in the code where the %20-to-whitespace
conversion happened were replaced with a call to urldecodestr().
This provides support for several characters that are frequently found
in mp3 filenames besides the blank space, such as: the apostrophe,
comma, tilda, parentheses, brackets, braces, etc.
For example...
http://localhost/Bob%20Dylan/Biograph%20%28Disc%203%20of%203%29/15%20-%20Knockin%27%20On%20Heaven%27s%20Door.mp3]
now translates to the following in the playlist window (with parens
and tick marks correctly placed)...
Bob Dylan/Biograph (Disc 3 of 3)/15 - Knockin' On Heaven's Door.mp3
Comments are welcome. I would very much like to see this included in
the next release.
:-Dustin
diff -uprN xmms-1.2.10/xmms/playlist.c xmms-1.2.10-hex_to_char/xmms/playlist.c
--- xmms-1.2.10/xmms/playlist.c 2004-02-23 14:31:43.000000000 -0600
+++ xmms-1.2.10-hex_to_char/xmms/playlist.c 2005-10-19 04:47:52.000000000 -0500
@@ -983,16 +983,7 @@ char *playlist_get_info_text(void)
while ((tmp = strchr(text, '_')) != NULL)
*tmp = ' ';
if (cfg.convert_twenty)
- while ((tmp = strstr(text, "%20")) != NULL)
- {
- char *tmp2;
- tmp2 = tmp + 3;
- *(tmp++) = ' ';
- while (*tmp2)
- *(tmp++) = *(tmp2++);
- *tmp = '\0';
- }
-
+ urldecodestr(&text);
return text;
}
diff -uprN xmms-1.2.10/xmms/playlist_list.c
xmms-1.2.10-hex_to_char/xmms/playlist_list.c
--- xmms-1.2.10/xmms/playlist_list.c 2003-06-11 13:44:17.000000000 -0500
+++ xmms-1.2.10-hex_to_char/xmms/playlist_list.c 2005-10-19
04:58:47.000000000 -0500
@@ -314,18 +314,7 @@ void playlist_list_draw_string_wc(PlayLi
}
if (cfg.convert_twenty && len > 2)
- {
- GdkWChar *wtmp;
- while ((wtmp = find_in_wstr(wtext, "%20")) != NULL)
- {
- GdkWChar *wtmp2 = wtmp + 3;
- *(wtmp++) = L' ';
- while (*wtmp2)
- *(wtmp++) = *(wtmp2++);
- *wtmp = L'\0';
- len -= 2;
- }
- }
+ urldecodestr(&wtext);
newlen = len + 2;
@@ -366,14 +355,8 @@ void playlist_list_draw_string(PlayList_
while ((tmp = strchr(text, '_')) != NULL)
*tmp = ' ';
if (cfg.convert_twenty)
- while ((tmp = strstr(text, "%20")) != NULL)
- {
- char *tmp2 = tmp + 3;
- *(tmp++) = ' ';
- while (*tmp2)
- *(tmp++) = *(tmp2++);
- *tmp = '\0';
- }
+ urldecodestr(&text);
len = strlen(text);
while (gdk_text_width(font, text, len) > width && len > 4)
{
diff -uprN xmms-1.2.10/xmms/urldecode.c xmms-1.2.10-hex_to_char/xmms/urldecode.c
--- xmms-1.2.10/xmms/urldecode.c 2003-05-19 16:22:08.000000000 -0500
+++ xmms-1.2.10-hex_to_char/xmms/urldecode.c 2005-10-19 04:46:07.000000000 -0500
@@ -61,3 +61,47 @@ char *xmms_urldecode_path(char *encoded_
return encoded_path;
}
+
+
+/* take a 2-character hex string and return the integer value */
+int axtoi(char *hexstr) {
+ int i = 0;
+ int hexint[2];
+ hexint[0] = hexint[1] = 0;
+ while (i < 2) {
+ if (hexstr[i]=='\0')
+ break;
+ else if (hexstr[i] >= '0' && hexstr[i] <= '9' )
+ hexint[i] = hexstr[i] - '0';
+ else if (hexstr[i] >='A' && hexstr[i] <= 'F')
+ hexint[i] = 10 + (hexstr[i] - 'A');
+ else if (hexstr[i] >='a' && hexstr[i] <= 'f')
+ hexint[i] = 10 + (hexstr[i] - 'a');
+ else break;
+ i++;
+ }
+ return hexint[0]*16 + hexint[1];
+}
+
+
+/* for each "%" found in string, attempt to decode following two bytes and
+ replace with URL special character */
+int urldecodestr(char **text) {
+ char *str, *tmp, *hexstr, *cur;
+ int i;
+ str = cur = *text;
+ while ((hexstr = strchr(str, '%')) != NULL) {
+ cur = hexstr + 1;
+ i = axtoi(cur);
+ if (i > 0) {
+ tmp = hexstr + 3;
+ *(hexstr++) = (char)i;
+ while (*tmp)
+ *(hexstr++) = *(tmp++);
+ *hexstr = '\0';
+ }
+ str = cur;
+ }
+ return 0;
+}
+
diff -uprN xmms-1.2.10/xmms/urldecode.h xmms-1.2.10-hex_to_char/xmms/urldecode.h
--- xmms-1.2.10/xmms/urldecode.h 2000-05-31 21:56:20.000000000 -0500
+++ xmms-1.2.10-hex_to_char/xmms/urldecode.h 2005-10-19 04:46:41.000000000 -0500
@@ -17,3 +17,5 @@
*/
char *xmms_urldecode_path(char *);
+int axtoi(char *hexstr);
+int urldecodestr(char **text);