--- id3cvs.c 2002-10-21 19:46:14.000000000 -0400 +++ id3.c 2002-10-21 19:35:39.000000000 -0400 @@ -232,38 +232,29 @@ { int minframesize; int size; - int readsize = 0, headerlen; - char *title = NULL; - char *artist = NULL; - char *album = NULL; - char *tracknum = NULL; + int bufferpos = 0, totframelen, framelen; char header[10]; unsigned short int version; - int titlen=0, artistn=0, albumn=0, tracknumn=0; char *buffer = entry->id3v2buf; + char *tracknum = NULL; + int bytesread = 0; + unsigned short int buffersize = (int)sizeof(entry->id3v2buf); - /* 10 = headerlength */ + /* if the id3v2len is not at least 10 bytes, then we don't have enough + * to do anything with */ if(entry->id3v2len < 10) return; - /* Check version */ + /* Get the header and save the version */ lseek(fd, 0, SEEK_SET); if(10 != read(fd, header, 10)) return; version = (unsigned short int)header[3]; - /* Read all frames in the tag */ + /* Get the total size of all of the frames in the tag */ 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 */ if(version > 2) minframesize = 12; @@ -274,89 +265,85 @@ * We must have at least minframesize bytes left for the * remaining frames to be interesting */ - while(size - readsize > minframesize) { - + while(size > minframesize) { /* Read frame header and check length */ if(version > 2) { - memcpy(header, (buffer + readsize), 10); - readsize += 10; - if (version > 3) { - headerlen = UNSYNC(header[4], header[5], + if(10 != read(fd, header, 10)) + return; + /* We now have 10 less bytes of tag remaining */ + size -= 10; + if(version > 3){ + framelen = UNSYNC(header[4], header[5], header[6], header[7]); - } else { + }else{ /* version .3 files don't use synchsafe ints for * size */ - headerlen = BYTES2INT(header[4], header[5], + framelen = BYTES2INT(header[4], header[5], header[6], header[7]); } } else { - memcpy(header, (buffer + readsize), 6); - readsize += 6; - headerlen = (header[3] << 16) + + if(6 != read(fd, header, 6)) + return; + /* We now have 6 less bytes of tag remaining */ + size -= 6; + framelen = (header[3] << 16) + (header[4] << 8) + (header[5]); } - /* Get only the part of the header that is within our buffer */ - if(headerlen > (size-readsize)) - headerlen = (size - readsize); - - /* Check for certain frame headers */ - if(!strncmp(header, "TPE1", strlen("TPE1")) || - !strncmp(header, "TP1", strlen("TP1"))) { - readsize++; - headerlen--; - artist = buffer + readsize; - artistn = headerlen; - unicode_munge(&artist, &artistn); - } - else if(!strncmp(header, "TIT2", strlen("TIT2")) || - !strncmp(header, "TT2", strlen("TT2"))) { - readsize++; - headerlen--; - title = buffer + readsize; - titlen = headerlen; - unicode_munge(&title, &titlen); - } - else if(!strncmp(header, "TALB", strlen("TALB"))) { - readsize++; - headerlen--; - album = buffer + readsize; - albumn = headerlen; - unicode_munge(&album, &albumn); - } - else if(!strncmp(header, "TRCK", strlen("TRCK"))) { - readsize++; - headerlen--; - tracknum = buffer + readsize; - tracknumn = headerlen; - unicode_munge(&tracknum, &tracknumn); - } - - readsize += headerlen; - } - - if(artist) { - entry->artist = artist; - artist[artistn]=0; - } + /* Save the total length of the current frame */ + totframelen = framelen; - if(title) { - entry->title = title; - title[titlen]=0; - } + if(framelen == 0) + return; - if(album) { - entry->album = album; - album[albumn]=0; - } + /* Get only the part of the frame that is within our buffer */ + else if(framelen >= buffersize - bufferpos) + framelen = ((buffersize-1) - bufferpos); - if(tracknum) { - tracknum[tracknumn] = 0; + /* Check for certain frame headers */ + if(!strncmp(header, "TPE1", 4) || + !strncmp(header, "TP1", 3)) { + bytesread = read(fd, (buffer + bufferpos), framelen); + entry->artist = buffer + bufferpos; + unicode_munge(&entry->artist, &bytesread); + entry->artist[bytesread + 1] = '\0'; + bufferpos += (bytesread + 2); + size -= bytesread; + } + else if(!strncmp(header, "TIT2", 4) || + !strncmp(header, "TT2", 3)) { + bytesread = read(fd, (buffer + bufferpos), framelen); + entry->title = buffer + bufferpos; + unicode_munge(&entry->title, &bytesread); + entry->title[bytesread + 1] = '\0'; + bufferpos += (bytesread + 2); + size -= bytesread; + } + else if(!strncmp(header, "TALB", 4)) { + bytesread = read(fd, (buffer + bufferpos), framelen); + entry->album = buffer + bufferpos; + unicode_munge(&entry->album, &bytesread); + entry->album[bytesread + 1] = '\0'; + bufferpos += (bytesread + 2); + size -= bytesread; + } + else if(!strncmp(header, "TRCK", 4)) { + bytesread = read(fd, (buffer + bufferpos), framelen); + tracknum = buffer + bufferpos; + unicode_munge(&tracknum, &bytesread); + tracknum[bytesread + 1] = '\0'; entry->tracknum = atoi(tracknum); + bufferpos += (bytesread + 1); + size -= bytesread; + } else { + size -= totframelen; + lseek(fd, totframelen, SEEK_CUR); + } } } + /* * Calculates the size of the ID3v2 tag. *