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

Reply via email to