Package: id3v2 Version: 0.1.12-2 Severity: normal Tags: patch Trying to add a comment to an mp3 that contains a ':' results in undesired behavior, truncating fields and producing odd results (treating embedded ':' as option field delimiters).
Examples: -- jetmore@g3:~$ /usr/bin/id3v2 -c 'From: ripped cd' ~/swap/t.mp3 jetmore@g3:~$ /usr/bin/id3v2 -l ~/swap/t.mp3 | grep COMM COMM (Comments): (From)[]: ripped cd jetmore@g3:~$ /usr/bin/id3v2 -r COMM ~/swap/t.mp3 Deleting Frame COMM in file /home/jetmore/swap/t.mp3 ... jetmore@g3:~$ /usr/bin/id3v2 -c 'SHORT_COMMENT':'From: ripped cd':'lng' ~/swap/t.mp3 jetmore@g3:~$ /usr/bin/id3v2 -l ~/swap/t.mp3 | grep COMM COMM (Comments): (SHORT_COMMENT)[ ri]: From jetmore@g3:~$ /usr/bin/id3v2 -r COMM ~/swap/t.mp3 Deleting Frame COMM in file /home/jetmore/swap/t.mp3 ... jetmore@g3:~$ /usr/bin/id3v2 -c 'SHORT_COMMENT':'From\: ripped cd':'lng' ~/swap/t.mp3 jetmore@g3:~$ /usr/bin/id3v2 -l ~/swap/t.mp3 | grep COMM COMM (Comments): (ID3v1 Comment)[XXX]: ripped cd COMM (Comments): (SHORT_COMMENT)[ ri]: From\ The patch below allows the user to escape the colon with a backslash ("\:" is not treated as a field delimiter). Here are the results: -- jetmore@g3:~/swap/id3v2/id3v2-0.1.12$ ./id3v2 -c 'From: ripped cd' ~/swap/t.mp3 jetmore@g3:~/swap/id3v2/id3v2-0.1.12$ ./id3v2 -l ~/swap/t.mp3 | grep COMM COMM (Comments): (From)[]: ripped cd jetmore@g3:~/swap/id3v2/id3v2-0.1.12$ ./id3v2 -r COMM ~/swap/t.mp3 Deleting Frame COMM in file /home/jetmore/swap/t.mp3 ... jetmore@g3:~/swap/id3v2/id3v2-0.1.12$ ./id3v2 -c 'SHORT_COMMENT':'From\: ripped cd':'lng' ~/swap/t.mp3 jetmore@g3:~/swap/id3v2/id3v2-0.1.12$ ./id3v2 -l ~/swap/t.mp3 | grep COMM COMM (Comments): (SHORT_COMMENT)[lng]: From: ripped cd jetmore@g3:~/swap/id3v2/id3v2-0.1.12$ ./id3v2 -r COMM ~/swap/t.mp3 Deleting Frame COMM in file /home/jetmore/swap/t.mp3 ... jetmore@g3:~/swap/id3v2/id3v2-0.1.12$ ./id3v2 -c 'lots\:of\:colons\:\:\:' ~/swap/t.mp3 jetmore@g3:~/swap/id3v2/id3v2-0.1.12$ ./id3v2 -l ~/swap/t.mp3 | grep COMM COMM (Comments): ()[]: lots:of:colons::: I'm 99% sure this also solves bug #390781 since the USLT option uses the same code. However, I didn't feel comfortable saying it definitely solved it because the use of colons for lyrics is undocumented and I wasn't really sure how it was supposed to work. Definitely works for comments though. I looked at the SF patch mentioned in #390781 but it wasn't very complete. My solution removes the escaping '\' characters before adding and also allows escaped colons in all three option components. This patch is based on 0.1.12-2 with the debian patches, so it should apply cleanly. Thanks! ############################################# --- id3v2-0.1.12.dist/id3v2.cpp 2012-07-17 00:25:08.000000000 -0400 +++ id3v2-0.1.12/id3v2.cpp 2012-07-17 00:33:28.000000000 -0400 @@ -512,29 +512,35 @@ case ID3FID_COMMENT: case ID3FID_UNSYNCEDLYRICS: { - // split the string at the ':' remember if no : then leave - // descrip/lang empty - char *text; - text = strchr(frameList[ii].data, ':'); - if (text == NULL) - { - myFrame->Field(ID3FN_TEXT) = frameList[ii].data; - } else { - *text = '\0'; - text++; - char *lang; - lang = strchr(text, ':'); - if (lang == NULL) - { - myFrame->Field(ID3FN_DESCRIPTION) = frameList[ii].data; - myFrame->Field(ID3FN_TEXT) = text; - } else { - *lang = '\0'; - lang++; - myFrame->Field(ID3FN_DESCRIPTION) = frameList[ii].data; - myFrame->Field(ID3FN_TEXT) = text; - myFrame->Field(ID3FN_LANGUAGE) = lang; + // split the string at the ':' (ignoring "\:" and splitting into no more than 3 pieces + // remember if no ':' then leave descrip/lang empty + char *pieces[3] = { frameList[ii].data, NULL, NULL }; + if (strchr(frameList[ii].data, ':')) { + size_t read_at = 0, inst_at = 0, piece = 0; + unsigned int olen = strlen(frameList[ii].data); + for (read_at = 0; read_at < olen; read_at++, inst_at++) { + if (frameList[ii].data[read_at] == '\\' && frameList[ii].data[read_at+1] == ':') { + read_at++; + } + else if (frameList[ii].data[read_at] == ':' && piece < 2) { + frameList[ii].data[read_at] = '\0'; + pieces[++piece] = frameList[ii].data + inst_at + 1; + } + frameList[ii].data[inst_at] = frameList[ii].data[read_at]; } + frameList[ii].data[inst_at] = '\0'; + } + // fprintf(stdout, "1: %s, 2: %s, 3: %s\n", pieces[0], pieces[1], pieces[2]); + + if (pieces[1] == NULL) { + myFrame->Field(ID3FN_TEXT) = pieces[0]; + } else if (pieces[2] == NULL) { + myFrame->Field(ID3FN_DESCRIPTION) = pieces[0]; + myFrame->Field(ID3FN_TEXT) = pieces[1]; + } else { + myFrame->Field(ID3FN_DESCRIPTION) = pieces[0]; + myFrame->Field(ID3FN_TEXT) = pieces[1]; + myFrame->Field(ID3FN_LANGUAGE) = pieces[2]; } /* debug std::cout << ID3_GetString(myFrame, ID3FN_DESCRIPTION) << std::endl ############################################### -- System Information: Debian Release: wheezy/sid APT prefers testing APT policy: (500, 'testing') Architecture: amd64 (x86_64) Kernel: Linux 3.2.0-2-amd64 (SMP w/4 CPU cores) Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=ANSI_X3.4-1968) (ignored: LC_ALL set to C) Shell: /bin/sh linked to /bin/dash Versions of packages id3v2 depends on: ii libc6 2.13-33 ii libgcc1 1:4.7.1-2 ii libid3-3.8.3c2a 3.8.3-15 ii libstdc++6 4.7.1-2 ii zlib1g 1:1.2.7.dfsg-13 id3v2 recommends no packages. id3v2 suggests no packages. -- no debconf information -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org