Magellan Linux

Annotation of /trunk/beep-media-player/patches/beep-media-player-0.9.7-unicode.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 144 - (hide annotations) (download)
Tue May 8 20:06:05 2007 UTC (17 years, 1 month ago) by niro
File size: 16841 byte(s)
-import

1 niro 144 diff -r -U3 bmp-0.9.7.orig/Input/mpg123/id3_frame_content.c bmp-0.9.7/Input/mpg123/id3_frame_content.c
2     --- bmp-0.9.7.orig/Input/mpg123/id3_frame_content.c 2005-02-25 21:45:03.000000000 -0500
3     +++ bmp-0.9.7/Input/mpg123/id3_frame_content.c 2005-02-25 21:56:14.000000000 -0500
4     @@ -44,9 +44,7 @@
5     char *
6     id3_get_content(struct id3_frame *frame)
7     {
8     - char *text, *text_beg, *ptr;
9     - char buffer[256];
10     - int spc = sizeof(buffer) - 1;
11     + gchar *text, *text_it;
12    
13     /* Type check */
14     if (frame->fr_desc->fd_id != ID3_TCON)
15     @@ -56,83 +54,82 @@
16     if (id3_decompress_frame(frame) == -1)
17     return NULL;
18    
19     - if (*(guint8 *) frame->fr_data == ID3_ENCODING_ISO_8859_1)
20     - text_beg = text = g_strdup((char *) frame->fr_data + 1);
21     - else
22     - text_beg = text = id3_utf16_to_ascii((char *) frame->fr_data + 1);
23     -
24     - /*
25     - * If content is just plain text, return it.
26     - */
27     - if (text[0] != '(') {
28     - return text;
29     - }
30     -
31     + ID3_FRAME_DEFINE_CURSOR(frame);
32     +
33     + guint8 encoding;
34     + ID3_FRAME_READ_OR_RETVAL(encoding, NULL);
35     +
36     + text = text_it = id3_string_decode(encoding, cursor, length);
37     +
38     + if (text == NULL)
39     + return NULL;
40     +
41     /*
42     * Expand ID3v1 genre numbers.
43     */
44     - ptr = buffer;
45     - while (text[0] == '(' && text[1] != '(' && spc > 0) {
46     - const char *genre;
47     - int num = 0;
48     -
49     - if (text[1] == 'R' && text[2] == 'X') {
50     - text += 4;
51     - genre = _(" (Remix)");
52     - if (ptr == buffer)
53     - genre++;
54     -
55     + while ((text_it = strstr(text_it, "(")) != NULL)
56     + {
57     + gchar* replace = NULL;
58     + gchar* ref_start = text_it + 1;
59     +
60     + if (*ref_start == ')')
61     + {
62     + /* False alarm */
63     + ++text_it;
64     + continue;
65     }
66     - else if (text[1] == 'C' && text[2] == 'R') {
67     - text += 4;
68     - genre = _(" (Cover)");
69     - if (ptr == buffer)
70     - genre++;
71     -
72     +
73     + gsize ref_size = strstr(ref_start, ")") - ref_start;
74     +
75     + if (strncmp(ref_start, "RX", ref_size) == 0)
76     + {
77     + replace = _("Remix");
78     }
79     - else {
80     - /* Get ID3v1 genre number */
81     - text++;
82     - while (*text != ')') {
83     - num *= 10;
84     - num += *text++ - '0';
85     + else if (strncmp(ref_start, "CR", ref_size) == 0)
86     + {
87     + replace = _("Cover");
88     + }
89     + else
90     + {
91     + /* Maybe an ID3v1 genre? */
92     + int genre_number;
93     + gchar* genre_number_str = g_strndup(ref_start, ref_size);
94     + if (sscanf(genre_number_str, "%d", &genre_number) > 0)
95     + {
96     + /* Boundary check */
97     + if (genre_number >= sizeof(mpg123_id3_genres) / sizeof(char *))
98     + continue;
99     + replace = gettext(mpg123_id3_genres[genre_number]);
100     }
101     - text++;
102     -
103     - /* Boundary check */
104     - if (num >= sizeof(mpg123_id3_genres) / sizeof(char *))
105     - continue;
106     -
107     - genre = gettext(mpg123_id3_genres[num]);
108     -
109     - if (ptr != buffer && spc-- > 0)
110     - *ptr++ = '/';
111     }
112    
113     - /* Expand string into buffer */
114     - while (*genre != '\0' && spc > 0) {
115     - *ptr++ = *genre++;
116     - spc--;
117     + if (replace != NULL)
118     + {
119     + /* Amazingly hairy code to replace a part of the original genre string
120     + with 'replace'. */
121     + gchar* copy = g_malloc(strlen(text) - ref_size + strlen(replace) + 1);
122     + gsize pos = 0;
123     + gsize copy_size;
124     +
125     + /* Copy the part before the replaced part */
126     + copy_size = ref_start - text;
127     + memcpy(copy + pos, text, copy_size);
128     + pos += copy_size;
129     + /* Copy the replacement instead of the original reference */
130     + copy_size = strlen(replace);
131     + memcpy(copy + pos, replace, copy_size);
132     + pos += copy_size;
133     + /* Copy the rest, including the null */
134     + memcpy(copy + pos, ref_start + ref_size, strlen(ref_start + ref_size)+1);
135     +
136     + /* Put into original variables */
137     + gsize offset = text_it - text;
138     + g_free(text);
139     + text = copy;
140     + text_it = text + offset;
141     }
142     +
143     + ++text_it;
144     }
145     -
146     - /*
147     - * Add plaintext refinement.
148     - */
149     - if (*text == '(')
150     - text++;
151     - if (*text != '\0' && ptr != buffer && spc-- > 0)
152     - *ptr++ = ' ';
153     - while (*text != '\0' && spc > 0) {
154     - *ptr++ = *text++;
155     - spc--;
156     - }
157     - *ptr = '\0';
158     -
159     - g_free(text_beg);
160     -
161     - /*
162     - * Return the expanded content string.
163     - */
164     - return g_strdup(buffer);
165     + return text;
166     }
167     diff -r -U3 bmp-0.9.7.orig/Input/mpg123/id3_frame_text.c bmp-0.9.7/Input/mpg123/id3_frame_text.c
168     --- bmp-0.9.7.orig/Input/mpg123/id3_frame_text.c 2005-02-25 21:45:03.000000000 -0500
169     +++ bmp-0.9.7/Input/mpg123/id3_frame_text.c 2005-02-26 01:25:45.613011872 -0500
170     @@ -35,21 +35,6 @@
171     #include "id3_header.h"
172    
173    
174     -char *
175     -id3_utf16_to_ascii(void *utf16)
176     -{
177     - char ascii[256];
178     - char *uc = (char *) utf16 + 2;
179     - int i;
180     -
181     - for (i = 0; *uc != 0 && i < sizeof(ascii); i++, uc += 2)
182     - ascii[i] = *uc;
183     -
184     - ascii[i] = 0;
185     - return g_strdup(ascii);
186     -}
187     -
188     -
189     /*
190     * Function id3_get_encoding (frame)
191     *
192     @@ -78,7 +63,12 @@
193     if (id3_decompress_frame(frame) == -1)
194     return -1;
195    
196     - return *(gint8 *) frame->fr_data;
197     + ID3_FRAME_DEFINE_CURSOR(frame);
198     +
199     + guint8 encoding;
200     + ID3_FRAME_READ_OR_RETVAL(encoding, -1);
201     +
202     + return encoding;
203     }
204    
205    
206     @@ -119,6 +109,108 @@
207     return 0;
208     }
209    
210     +/* Get size of string in bytes including null. */
211     +gsize id3_string_size(guint8 encoding, const void* text, gsize max_size)
212     +{
213     + switch ( encoding ) {
214     + case ID3_ENCODING_ISO_8859_1:
215     + case ID3_ENCODING_UTF8:
216     + {
217     + const guint8* text8 = text;
218     + while ( (max_size >= sizeof(*text8)) && (*text8 != 0) )
219     + {
220     + ++text8;
221     + max_size -= sizeof(*text8);
222     + }
223     +
224     + if (max_size >= sizeof(*text8))
225     + {
226     + ++text8;
227     + max_size -= sizeof(*text8);
228     + }
229     +
230     + return text8 - (guint8*)text;
231     + }
232     + case ID3_ENCODING_UTF16:
233     + case ID3_ENCODING_UTF16BE:
234     + {
235     + const guint16* text16 = (guint16*)text;
236     + while ( (max_size > 0) && (*text16 != 0) )
237     + {
238     + ++text16;
239     + max_size -= sizeof(*text16);
240     + }
241     +
242     + if (max_size > 0)
243     + {
244     + ++text16;
245     + max_size -= sizeof(*text16);
246     + }
247     +
248     + return (guint8*)text16 - (guint8*)text;
249     + }
250     + default:
251     + return 0;
252     + }
253     +}
254     +
255     +/*
256     + * Returns a newly-allocated UTF-8 string in the locale's encoding.
257     + * max_size specifies the maximum size of 'text', including terminating nulls.
258     + */
259     +gchar* id3_string_decode(guint8 encoding, const void* text, gsize max_size)
260     +{
261     + /* Otherwise, we'll end up passing -1 to functions, eliminating safety benefits. */
262     + if (max_size <= 0)
263     + return NULL;
264     +
265     + switch( encoding )
266     + {
267     + case ID3_ENCODING_ISO_8859_1:
268     + {
269     + return g_locale_to_utf8((const gchar*)text, max_size, NULL, NULL, NULL);
270     + }
271     + case ID3_ENCODING_UTF8:
272     + {
273     + gchar* end_text = (gchar*)text;
274     + if (g_utf8_validate((const gchar*)text, max_size, &end_text))
275     + return g_strndup((const gchar*)text, max_size);
276     + else
277     + {
278     + /* g_utf8_validate() with second argument positive
279     + will return 0 if the string contains nulls. Frequently
280     + someone will pass us a valid null-terminated utf8
281     + string, with max_size overestimated a bit; so we need
282     + to run another test to truly check validity */
283     + if((end_text != text) && (*end_text == NULL) &&
284     + g_utf8_validate((const gchar*)text, NULL, NULL))
285     + return g_strndup((const gchar*)text, max_size);
286     +
287     + return NULL;
288     + }
289     + }
290     + case ID3_ENCODING_UTF16:
291     + {
292     + gsize size_bytes = id3_string_size(encoding, text, max_size);
293     + gchar* utf8 = g_convert((const gchar*)text, size_bytes, "UTF-8", "UTF-16", NULL, NULL, NULL);
294     + /* If conversion passes on the BOM as-is, we strip it. */
295     + if (g_utf8_get_char(utf8) == 0xfeff)
296     + {
297     + gchar* new_utf8 = g_strdup(utf8+3);
298     + g_free(utf8);
299     + utf8 = new_utf8;
300     + }
301     + return utf8;
302     + }
303     + case ID3_ENCODING_UTF16BE:
304     + {
305     + gsize size_bytes = id3_string_size(encoding, text, max_size);
306     + return g_convert((const gchar*)text, size_bytes, "UTF-8", "UTF-16BE", NULL, NULL, NULL);
307     + }
308     + default:
309     + return NULL;
310     + }
311     +}
312    
313     /*
314     * Function id3_get_text (frame)
315     @@ -137,38 +229,21 @@
316     if (id3_decompress_frame(frame) == -1)
317     return NULL;
318    
319     + ID3_FRAME_DEFINE_CURSOR(frame);
320     +
321     + guint8 encoding;
322     + ID3_FRAME_READ_OR_RETVAL(encoding, NULL);
323     +
324     if (frame->fr_desc->fd_id == ID3_TXXX || frame->fr_desc->fd_id == ID3_COMM) {
325     /*
326     * This is a user defined text frame. Skip the description.
327     */
328     - switch (*(guint8 *) frame->fr_data) {
329     - case ID3_ENCODING_ISO_8859_1:
330     - {
331     - char *text = (char *) frame->fr_data + 1;
332     -
333     - while (*text != 0)
334     - text++;
335     -
336     - return g_strdup(++text);
337     - }
338     - case ID3_ENCODING_UTF16:
339     - {
340     - char *text16 = (char *) frame->fr_data + 1;
341     -
342     - while (*text16 != 0 || *(text16 + 1) != 0)
343     - text16 += 2;
344     -
345     - return id3_utf16_to_ascii(text16 + 2);
346     - }
347     - default:
348     - return NULL;
349     - }
350     + gsize bytes = id3_string_size(encoding, cursor, length);
351     + cursor += bytes;
352     + length -= bytes;
353     }
354    
355     - if (*(guint8 *) frame->fr_data == ID3_ENCODING_ISO_8859_1)
356     - return g_strdup((char *) frame->fr_data + 1);
357     - else
358     - return id3_utf16_to_ascii(((char *) frame->fr_data + 1));
359     + return id3_string_decode(encoding, cursor, length);
360     }
361    
362    
363     @@ -193,10 +268,12 @@
364     if (id3_decompress_frame(frame) == -1)
365     return NULL;
366    
367     - if (*(guint8 *) frame->fr_data == ID3_ENCODING_ISO_8859_1)
368     - return g_strdup((char *) frame->fr_data + 1);
369     - else
370     - return id3_utf16_to_ascii((char *) frame->fr_data + 1);
371     + ID3_FRAME_DEFINE_CURSOR(frame);
372     +
373     + guint8 encoding;
374     + ID3_FRAME_READ_OR_RETVAL(encoding, NULL);
375     +
376     + return id3_string_decode(encoding, cursor, length);
377     }
378    
379    
380     @@ -216,41 +293,19 @@
381     if (id3_decompress_frame(frame) == -1)
382     return -1;
383    
384     - /*
385     - * Generate integer according to encoding.
386     - */
387     - switch (*(guint8 *) frame->fr_data) {
388     - case ID3_ENCODING_ISO_8859_1:
389     - {
390     - char *text = ((char *) frame->fr_data) + 1;
391     -
392     - while (*text >= '0' && *text <= '9') {
393     - number *= 10;
394     - number += *text - '0';
395     - text++;
396     - }
397     -
398     - return number;
399     - }
400     - case ID3_ENCODING_UTF16:
401     - {
402     - char *text = ((char *) frame->fr_data) + 3;
403     -
404     -/* if (*(gint16 *) frame->fr_data == 0xfeff) */
405     -/* text++; */
406     -
407     - while (*text >= '0' && *text <= '9') {
408     - number *= 10;
409     - number += *text - '0';
410     - text++;
411     - }
412     -
413     - return number;
414     - }
415     -
416     - default:
417     - return -1;
418     - }
419     + ID3_FRAME_DEFINE_CURSOR(frame);
420     +
421     + guint8 encoding;
422     + ID3_FRAME_READ_OR_RETVAL(encoding, number);
423     +
424     + gchar* number_str = id3_string_decode(encoding, cursor, length);
425     + if (number_str != NULL)
426     + {
427     + sscanf(number_str, "%d", &number);
428     + g_free(number_str);
429     + }
430     +
431     + return number;
432     }
433    
434    
435     @@ -306,7 +361,6 @@
436     id3_set_text_number(struct id3_frame *frame, int number)
437     {
438     char buf[64];
439     - int pos;
440     char *text;
441    
442     /* Type check */
443     @@ -321,20 +375,12 @@
444     /*
445     * Create a string with a reversed number.
446     */
447     - pos = 0;
448     - while (number > 0 && pos < 64) {
449     - buf[pos++] = (number % 10) + '0';
450     - number /= 10;
451     - }
452     - if (pos == 64)
453     - return -1;
454     - if (pos == 0)
455     - buf[pos++] = '0';
456     + snprintf(buf, sizeof(buf), "%d", number);
457    
458     /*
459     * Allocate memory for new data.
460     */
461     - frame->fr_raw_size = pos + 1;
462     + frame->fr_raw_size = strlen(buf) + 1;
463     frame->fr_raw_data = g_malloc(frame->fr_raw_size + 1);
464    
465     /*
466     @@ -342,9 +388,7 @@
467     */
468     *(gint8 *) frame->fr_raw_data = ID3_ENCODING_ISO_8859_1;
469     text = (char *) frame->fr_raw_data + 1;
470     - while (--pos >= 0)
471     - *text++ = buf[pos];
472     - *text = '\0';
473     + strcpy(text, buf);
474    
475     frame->fr_altered = 1;
476     frame->fr_owner->id3_altered = 1;
477     diff -r -U3 bmp-0.9.7.orig/Input/mpg123/id3_frame_url.c bmp-0.9.7/Input/mpg123/id3_frame_url.c
478     --- bmp-0.9.7.orig/Input/mpg123/id3_frame_url.c 2005-02-25 21:45:03.000000000 -0500
479     +++ bmp-0.9.7/Input/mpg123/id3_frame_url.c 2005-02-25 22:15:28.000000000 -0500
480     @@ -48,36 +48,26 @@
481     /* Check if frame is compressed */
482     if (id3_decompress_frame(frame) == -1)
483     return NULL;
484     -
485     - if (frame->fr_desc->fd_id == ID3_WXXX) {
486     +
487     + ID3_FRAME_DEFINE_CURSOR(frame);
488     +
489     + if ( frame->fr_desc->fd_id == ID3_WXXX ) {
490     /*
491     * This is a user defined link frame. Skip the description.
492     */
493     - switch (*(guint8 *) frame->fr_data) {
494     - case ID3_ENCODING_ISO_8859_1:
495     - {
496     - char *text = (char *) frame->fr_data + 1;
497     -
498     - while (*text != 0)
499     - text++;
500     -
501     - return g_strdup(++text);
502     - }
503     - case ID3_ENCODING_UTF16:
504     - {
505     - gint16 *text16 = (gint16 *) ((glong) frame->fr_data + 1);
506     -
507     - while (*text16 != 0)
508     - text16++;
509     -
510     - return g_strdup((char *) (++text16));
511     - }
512     - default:
513     + guint8 encoding;
514     + gsize description_size;
515     +
516     + ID3_FRAME_READ_OR_RETVAL(encoding, NULL);
517     +
518     + description_size = id3_string_size(encoding, cursor, length);
519     + if (description_size == 0)
520     return NULL;
521     - }
522     + cursor += description_size;
523     + length -= description_size;
524     }
525    
526     - return g_strdup((char *) frame->fr_data);
527     + return id3_string_decode(ID3_ENCODING_ISO_8859_1, cursor, length);
528     }
529    
530    
531     @@ -102,8 +92,10 @@
532     if (id3_decompress_frame(frame) == -1)
533     return NULL;
534    
535     - if (*(guint8 *) frame->fr_data == ID3_ENCODING_ISO_8859_1)
536     - return g_strdup((char *) frame->fr_data + 1);
537     - else
538     - return id3_utf16_to_ascii((gint16 *) ((glong) frame->fr_data + 1));
539     + ID3_FRAME_DEFINE_CURSOR(frame);
540     +
541     + guint8 encoding;
542     + ID3_FRAME_READ_OR_RETVAL(encoding, NULL);
543     +
544     + return id3_string_decode(encoding, cursor, length);
545     }
546     diff -r -U3 bmp-0.9.7.orig/Input/mpg123/xmms-id3.h bmp-0.9.7/Input/mpg123/xmms-id3.h
547     --- bmp-0.9.7.orig/Input/mpg123/xmms-id3.h 2005-02-25 21:45:03.000000000 -0500
548     +++ bmp-0.9.7/Input/mpg123/xmms-id3.h 2005-02-25 21:49:22.000000000 -0500
549     @@ -29,6 +29,7 @@
550     #define ID3_H
551    
552     #include <glib.h>
553     +#include <string.h>
554     #include <libbeep/vfs.h>
555    
556     /*
557     @@ -318,6 +319,21 @@
558     #define ID3_WPB ID3_FRAME_ID_22('W', 'P', 'B')
559     #define ID3_WXX ID3_FRAME_ID_22('W', 'X', 'X')
560    
561     +/*
562     + * Handy macros which help us writing more secure length-aware code
563     + * which involves reading the frame's data buffer.
564     + */
565     +
566     +#define ID3_FRAME_DEFINE_CURSOR(frame) \
567     + gsize length = frame->fr_size; \
568     + guint8* cursor = frame->fr_data;
569     +
570     +#define ID3_FRAME_READ_OR_RETVAL(variable, retval) \
571     + if (length < sizeof(variable)) \
572     + return retval; \
573     + memcpy((void*)&variable, (void*)cursor, sizeof(variable)); \
574     + cursor += sizeof(variable); \
575     + length -= sizeof(variable);
576    
577     /*
578     * Prototypes.
579     @@ -343,7 +359,8 @@
580     void id3_frame_clear_data(struct id3_frame *frame);
581    
582     /* From id3_frame_text.c */
583     -char *id3_utf16_to_ascii(void *);
584     +gsize id3_string_size(guint8 encoding, const void* text, gsize max_size);
585     +gchar* id3_string_decode(guint8 encoding, const void* text, gsize max_size);
586     gint8 id3_get_encoding(struct id3_frame *);
587     int id3_set_encoding(struct id3_frame *, gint8);
588     char *id3_get_text(struct id3_frame *);