1
0
Fork 0
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:
Linus Nielsen Feltzing 2002-10-28 23:00:57 +00:00
parent 8857d47b5a
commit be8ae1c0e2

View file

@ -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); entry->tracknum = atoi(tracknum);
bufferpos += bytesread + 1;
size -= bytesread;
} }
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);
} }
} }