diff -urN mplayer-1.0_rc4_p20100213/playtreeparser.c mplayer-1.0_rc4_p20100213.new/playtreeparser.c --- mplayer-1.0_rc4_p20100213/playtreeparser.c 2010-01-31 00:24:23.000000000 +0100 +++ mplayer-1.0_rc4_p20100213.new/playtreeparser.c 2010-02-28 03:29:21.000000000 +0100 @@ -45,21 +45,19 @@ #define WHITES " \n\r\t" -static void +static char * strstrip(char* str) { char* i; if (str==NULL) return; - for(i = str ; i[0] != '\0' && strchr(WHITES,i[0]) != NULL; i++) + while (str[0] != '\0' && strchr(WHITES,str[0]) != NULL) + ++str; + i = str + strlen(str); + while (i-- != str && strchr(WHITES,i[0]) != NULL) /* NOTHING */; - if(i[0] != '\0') { - memmove(str,i,strlen(i) + 1); - for(i = str + strlen(str) - 1 ; strchr(WHITES,i[0]) != NULL; i--) - /* NOTHING */; - i[1] = '\0'; - } else - str[0] = '\0'; + i[1] = '\0'; + return str; } static char* @@ -138,6 +136,16 @@ return p->line; } +static char* +play_tree_parser_get_stripped_line(play_tree_parser_t* p) { + char *str; + + str = play_tree_parser_get_line(p); + if (str) + str = strstrip(str); + return str; +} + static void play_tree_parser_reset(play_tree_parser_t* p) { p->iter = p->buffer; @@ -165,10 +173,9 @@ while(1) { if(get_line) { - line = play_tree_parser_get_line(p); + line = play_tree_parser_get_stripped_line(p); if(!line) return NULL; - strstrip(line); if(line[0] == '\0') continue; } @@ -231,40 +238,57 @@ } typedef struct pls_entry { + int number; char* file; char* title; char* length; } pls_entry_t; static int -pls_read_entry(char* line,pls_entry_t** _e,int* _max_entry,char** val) { - int num,max_entry = (*_max_entry); +pls_read_entry(char* line,pls_entry_t ** _e,int* _n_entries,const char *prefix,int prefix_len,char **val) +{ + int num,i,entries = (*_n_entries); pls_entry_t* e = (*_e); char* v; + if(strncasecmp(line,prefix,prefix_len) != 0) + return -1; + + line += prefix_len; + v = pls_entry_get_value(line); if(!v) { mp_msg(MSGT_PLAYTREE,MSGL_ERR,"No value in entry %s\n",line); return 0; } + (*val) = v; num = atoi(line); - if(num < 0) { - num = max_entry+1; - mp_msg(MSGT_PLAYTREE,MSGL_WARN,"No entry index in entry %s\nAssuming %d\n",line,num); - } - if(num > max_entry) { - e = (pls_entry_t*)realloc(e,num*sizeof(pls_entry_t)); - memset(&e[max_entry],0,(num-max_entry)*sizeof(pls_entry_t)); - max_entry = num; + if(num < 1 || num > entries || e[num-1].number != num) { + for(i = 0; i < entries; ++i) { + if (e[i].number == num) + break; + } + if (i == entries) { + e = (pls_entry_t*)realloc(e,(++entries)*sizeof(pls_entry_t)); + memset(&e[i],0,sizeof(pls_entry_t)); + e[i].number = num; + (*_n_entries) = entries; + (*_e) = e; + } + num = i+1; } - (*_e) = e; - (*_max_entry) = max_entry; - (*val) = v; return num; } +static int +cmp_entry_number(const void *a, const void *b) +{ + const pls_entry_t *pa = a, *pb = b; + return (pa->number < pb->number) ? -1 : + (pa->number > pb->number) ? 1 : 0; +} static play_tree_t* parse_pls(play_tree_parser_t* p) { @@ -274,9 +298,8 @@ play_tree_t *list = NULL, *entry = NULL, *last_entry = NULL; mp_msg(MSGT_PLAYTREE,MSGL_V,"Trying Winamp playlist...\n"); - while((line = play_tree_parser_get_line(p))) { - strstrip(line); - if(strlen(line)) + while((line = play_tree_parser_get_stripped_line(p))) { + if(line[0] != '\0') break; } if (!line) @@ -285,52 +308,40 @@ return NULL; mp_msg(MSGT_PLAYTREE,MSGL_V,"Detected Winamp playlist format\n"); play_tree_parser_stop_keeping(p); - line = play_tree_parser_get_line(p); + line = play_tree_parser_get_stripped_line(p); if(!line) return NULL; - strstrip(line); if(strncasecmp(line,"NumberOfEntries",15) == 0) { v = pls_entry_get_value(line); n_entries = atoi(v); - if(n_entries < 0) + if(n_entries <= 0 || n_entries > 100000) /* arbitrary big number */ mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Invalid number of entries: very funny!!!\n"); else mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Playlist claims to have %d entries. Let's see.\n",n_entries); - line = play_tree_parser_get_line(p); + line = play_tree_parser_get_stripped_line(p); } while(line) { - strstrip(line); if(line[0] == '\0') { - line = play_tree_parser_get_line(p); + line = play_tree_parser_get_stripped_line(p); continue; } - if(strncasecmp(line,"File",4) == 0) { - num = pls_read_entry(line+4,&entries,&max_entry,&v); - if(num < 0) - mp_msg(MSGT_PLAYTREE,MSGL_ERR,"No value in entry %s\n",line); - else - entries[num-1].file = strdup(v); - } else if(strncasecmp(line,"Title",5) == 0) { - num = pls_read_entry(line+5,&entries,&max_entry,&v); - if(num < 0) - mp_msg(MSGT_PLAYTREE,MSGL_ERR,"No value in entry %s\n",line); - else - entries[num-1].title = strdup(v); - } else if(strncasecmp(line,"Length",6) == 0) { - num = pls_read_entry(line+6,&entries,&max_entry,&v); - if(num < 0) - mp_msg(MSGT_PLAYTREE,MSGL_ERR,"No value in entry %s\n",line); - else - entries[num-1].length = strdup(v); - } else + if((num = pls_read_entry(line,&entries,&max_entry,"File",4,&v)) > 0) + entries[num-1].file = strdup(v); + else if (num < 0 && ((num = pls_read_entry(line,&entries,&max_entry,"Title",5,&v)) > 0)) + entries[num-1].title = strdup(v); + else if (num < 0 && ((num = pls_read_entry(line,&entries,&max_entry,"Length",6,&v)) > 0)) + entries[num-1].length = strdup(v); + else if (num < 0) mp_msg(MSGT_PLAYTREE,MSGL_WARN,"Unknown entry type %s\n",line); - line = play_tree_parser_get_line(p); + line = play_tree_parser_get_stripped_line(p); } + qsort(entries,max_entry,sizeof(*entries),cmp_entry_number); + for(num = 0; num < max_entry ; num++) { if(entries[num].file == NULL) - mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Entry %d don't have a file !!!!\n",num+1); + mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Entry %d don't have a file !!!!\n",entries[num].number); else { mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Adding entry %s\n",entries[num].file); entry = play_tree_new(); @@ -368,18 +379,16 @@ play_tree_t *list = NULL, *entry = NULL, *last_entry = NULL; mp_msg(MSGT_PLAYTREE,MSGL_V,"Trying reference-ini playlist...\n"); - if (!(line = play_tree_parser_get_line(p))) + if (!(line = play_tree_parser_get_stripped_line(p))) return NULL; - strstrip(line); if(strcasecmp(line,"[Reference]")) return NULL; mp_msg(MSGT_PLAYTREE,MSGL_V,"Detected reference-ini playlist format\n"); play_tree_parser_stop_keeping(p); - line = play_tree_parser_get_line(p); + line = play_tree_parser_get_stripped_line(p); if(!line) return NULL; while(line) { - strstrip(line); if(strncasecmp(line,"Ref",3) == 0) { v = pls_entry_get_value(line+3); if(!v) @@ -396,7 +405,7 @@ last_entry = entry; } } - line = play_tree_parser_get_line(p); + line = play_tree_parser_get_stripped_line(p); } if(!list) return NULL; @@ -411,16 +420,14 @@ play_tree_t *list = NULL, *entry = NULL, *last_entry = NULL; mp_msg(MSGT_PLAYTREE,MSGL_V,"Trying extended m3u playlist...\n"); - if (!(line = play_tree_parser_get_line(p))) + if (!(line = play_tree_parser_get_stripped_line(p))) return NULL; - strstrip(line); if(strcasecmp(line,"#EXTM3U")) return NULL; mp_msg(MSGT_PLAYTREE,MSGL_V,"Detected extended m3u playlist format\n"); play_tree_parser_stop_keeping(p); - while((line = play_tree_parser_get_line(p)) != NULL) { - strstrip(line); + while((line = play_tree_parser_get_stripped_line(p)) != NULL) { if(line[0] == '\0') continue; /* EXTM3U files contain such lines: @@ -464,8 +471,7 @@ mp_msg(MSGT_PLAYTREE,MSGL_V,"Trying smil playlist...\n"); // Check if smil - while((line = play_tree_parser_get_line(p)) != NULL) { - strstrip(line); + while((line = play_tree_parser_get_stripped_line(p)) != NULL) { if(line[0] == '\0') // Ignore empties continue; if (strncasecmp(line,"