forked from len0rd/rockbox
Now reads the tags frame by frame, to avoid missing frames when there are large blobs in the tag. This fixes bug #623510.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2768 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
8857d47b5a
commit
be8ae1c0e2
1 changed files with 58 additions and 75 deletions
129
firmware/id3.c
129
firmware/id3.c
|
|
@ -232,38 +232,28 @@ static void setid3v2title(int fd, struct mp3entry *entry)
|
||||||
{
|
{
|
||||||
int minframesize;
|
int minframesize;
|
||||||
int size;
|
int size;
|
||||||
int readsize = 0, headerlen;
|
int bufferpos = 0, totframelen, framelen;
|
||||||
char *title = NULL;
|
|
||||||
char *artist = NULL;
|
|
||||||
char *album = NULL;
|
|
||||||
char *tracknum = NULL;
|
|
||||||
char header[10];
|
char header[10];
|
||||||
unsigned short int version;
|
unsigned short int version;
|
||||||
int titlen=0, artistn=0, albumn=0, tracknumn=0;
|
|
||||||
char *buffer = entry->id3v2buf;
|
char *buffer = entry->id3v2buf;
|
||||||
|
char *tracknum = NULL;
|
||||||
|
int bytesread = 0;
|
||||||
|
int buffersize = sizeof(entry->id3v2buf);
|
||||||
|
|
||||||
/* 10 = headerlength */
|
/* Bail out if the tag is shorter than 10 bytes */
|
||||||
if(entry->id3v2len < 10)
|
if(entry->id3v2len < 10)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Check version */
|
/* Read the ID3 tag version from the header */
|
||||||
lseek(fd, 0, SEEK_SET);
|
lseek(fd, 0, SEEK_SET);
|
||||||
if(10 != read(fd, header, 10))
|
if(10 != read(fd, header, 10))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
version = (unsigned short int)header[3];
|
version = (unsigned short int)header[3];
|
||||||
|
|
||||||
/* Read all frames in the tag */
|
/* Get the total ID3 tag size */
|
||||||
size = entry->id3v2len - 10;
|
size = entry->id3v2len - 10;
|
||||||
|
|
||||||
if(size >= (int)sizeof(entry->id3v2buf))
|
|
||||||
size = sizeof(entry->id3v2buf)-1;
|
|
||||||
|
|
||||||
if(size != read(fd, buffer, size))
|
|
||||||
return;
|
|
||||||
|
|
||||||
*(buffer + size) = '\0';
|
|
||||||
|
|
||||||
/* Set minimum frame size according to ID3v2 version */
|
/* Set minimum frame size according to ID3v2 version */
|
||||||
if(version > 2)
|
if(version > 2)
|
||||||
minframesize = 12;
|
minframesize = 12;
|
||||||
|
|
@ -274,86 +264,79 @@ static void setid3v2title(int fd, struct mp3entry *entry)
|
||||||
* We must have at least minframesize bytes left for the
|
* We must have at least minframesize bytes left for the
|
||||||
* remaining frames to be interesting
|
* remaining frames to be interesting
|
||||||
*/
|
*/
|
||||||
while(size - readsize > minframesize) {
|
while(size > minframesize) {
|
||||||
|
|
||||||
/* Read frame header and check length */
|
/* Read frame header and check length */
|
||||||
if(version > 2) {
|
if(version > 2) {
|
||||||
memcpy(header, (buffer + readsize), 10);
|
if(10 != read(fd, header, 10))
|
||||||
readsize += 10;
|
return;
|
||||||
|
/* Adjust for the 10 bytes we read */
|
||||||
|
size -= 10;
|
||||||
|
|
||||||
if (version > 3) {
|
if (version > 3) {
|
||||||
headerlen = UNSYNC(header[4], header[5],
|
framelen = UNSYNC(header[4], header[5],
|
||||||
header[6], header[7]);
|
header[6], header[7]);
|
||||||
} else {
|
} else {
|
||||||
/* version .3 files don't use synchsafe ints for
|
/* version .3 files don't use synchsafe ints for
|
||||||
* size */
|
* size */
|
||||||
headerlen = BYTES2INT(header[4], header[5],
|
framelen = BYTES2INT(header[4], header[5],
|
||||||
header[6], header[7]);
|
header[6], header[7]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
memcpy(header, (buffer + readsize), 6);
|
if(6 != read(fd, header, 6))
|
||||||
readsize += 6;
|
return;
|
||||||
headerlen = (header[3] << 16) +
|
/* Adjust for the 6 bytes we read */
|
||||||
(header[4] << 8) +
|
size -= 6;
|
||||||
(header[5]);
|
|
||||||
|
framelen = BYTES2INT(0, header[3], header[4], header[5]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get only the part of the header that is within our buffer */
|
/* Keep track of the total size */
|
||||||
if(headerlen > (size-readsize))
|
totframelen += framelen;
|
||||||
headerlen = (size - readsize);
|
|
||||||
|
if(framelen == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* If the frame is larger than the remaining buffer space we try
|
||||||
|
to read as much as would fit in the buffer */
|
||||||
|
if(framelen >= buffersize - bufferpos)
|
||||||
|
framelen = buffersize - bufferpos - 1;
|
||||||
|
|
||||||
/* Check for certain frame headers */
|
/* Check for certain frame headers */
|
||||||
if(!strncmp(header, "TPE1", strlen("TPE1")) ||
|
if(!strncmp(header, "TPE1", strlen("TPE1")) ||
|
||||||
!strncmp(header, "TP1", strlen("TP1"))) {
|
!strncmp(header, "TP1", strlen("TP1"))) {
|
||||||
readsize++;
|
bytesread = read(fd, buffer + bufferpos, framelen);
|
||||||
headerlen--;
|
entry->artist = buffer + bufferpos;
|
||||||
artist = buffer + readsize;
|
unicode_munge(&entry->artist, &bytesread);
|
||||||
artistn = headerlen;
|
entry->artist[bytesread + 1] = '\0';
|
||||||
unicode_munge(&artist, &artistn);
|
bufferpos += bytesread + 2;
|
||||||
|
size -= bytesread;
|
||||||
}
|
}
|
||||||
else if(!strncmp(header, "TIT2", strlen("TIT2")) ||
|
else if(!strncmp(header, "TIT2", strlen("TIT2")) ||
|
||||||
!strncmp(header, "TT2", strlen("TT2"))) {
|
!strncmp(header, "TT2", strlen("TT2"))) {
|
||||||
readsize++;
|
bytesread = read(fd, buffer + bufferpos, framelen);
|
||||||
headerlen--;
|
entry->title = buffer + bufferpos;
|
||||||
title = buffer + readsize;
|
unicode_munge(&entry->title, &bytesread);
|
||||||
titlen = headerlen;
|
entry->title[bytesread + 1] = '\0';
|
||||||
unicode_munge(&title, &titlen);
|
bufferpos += bytesread + 2;
|
||||||
|
size -= bytesread;
|
||||||
}
|
}
|
||||||
else if(!strncmp(header, "TALB", strlen("TALB"))) {
|
else if(!strncmp(header, "TALB", strlen("TALB"))) {
|
||||||
readsize++;
|
bytesread = read(fd, buffer + bufferpos, framelen);
|
||||||
headerlen--;
|
entry->album = buffer + bufferpos;
|
||||||
album = buffer + readsize;
|
unicode_munge(&entry->album, &bytesread);
|
||||||
albumn = headerlen;
|
entry->album[bytesread + 1] = '\0';
|
||||||
unicode_munge(&album, &albumn);
|
bufferpos += bytesread + 2;
|
||||||
|
size -= bytesread;
|
||||||
}
|
}
|
||||||
else if(!strncmp(header, "TRCK", strlen("TRCK"))) {
|
else if(!strncmp(header, "TRCK", strlen("TRCK"))) {
|
||||||
readsize++;
|
bytesread = read(fd, buffer + bufferpos, framelen);
|
||||||
headerlen--;
|
tracknum = buffer + bufferpos;
|
||||||
tracknum = buffer + readsize;
|
unicode_munge(&tracknum, &bytesread);
|
||||||
tracknumn = headerlen;
|
tracknum[bytesread + 1] = '\0';
|
||||||
unicode_munge(&tracknum, &tracknumn);
|
|
||||||
}
|
|
||||||
|
|
||||||
readsize += headerlen;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(artist) {
|
|
||||||
entry->artist = artist;
|
|
||||||
artist[artistn]=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(title) {
|
|
||||||
entry->title = title;
|
|
||||||
title[titlen]=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(album) {
|
|
||||||
entry->album = album;
|
|
||||||
album[albumn]=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(tracknum) {
|
|
||||||
tracknum[tracknumn] = 0;
|
|
||||||
entry->tracknum = atoi(tracknum);
|
entry->tracknum = atoi(tracknum);
|
||||||
|
bufferpos += bytesread + 1;
|
||||||
|
size -= bytesread;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue