[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#610591: cdtool: cdown gets confused with multi-line titles and tracks



Package: cdtool
Version: 2.1.8-release-1
Severity: normal
Tags: patch


The 'cdown' tool in the cdtool package gets mildly confused when
looking up a CD if it gets a multi-line reply for any one entry in
that CD's description.  For example the 'DTITLE' response can look
like:

   DTITLE=the artist / the first part of the album title that goes
   DTITLE=on and on and takes two lines

This will confuse 'cdown' (which expect DTITLE to occur just once).
'cdown' has a similar problem with TTITLE entries, which can span
multiple lines, too

For a specific freeddb entry with both problems, see
	http://www.freedb.org/freedb/misc/aa101a0d

I have a very hacky patchy (see below) that 'fixes' the problem.  I've
only tested it on this one sample, so its not ready to be put back.  I
can clean the patch up, but figured I'd wait for some feedback.

Upstream seems to be offline (the URLs in the README are stale), so I
haven't tried pushing the patch there yet.


-- System Information:
Debian Release: 5.0.6
  APT prefers stable
  APT policy: (500, 'stable')
Architecture: i386 (i686)

Kernel: Linux 2.6.26-2-686 (SMP w/1 CPU core)
Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968)
Shell: /bin/sh linked to /bin/bash

Versions of packages cdtool depends on:
ii  libc6                       2.7-18lenny6 GNU C Library: Shared libraries

cdtool recommends no packages.

cdtool suggests no packages.

-- debconf information:
  cdtool/unknown_audiocd_device:

-- Patch:

diff -du cdtool-2.1.8.ORIG/cdown.c cdtool-2.1.8/cdown.c
--- cdtool-2.1.8.ORIG/cdown.c	2005-10-17 12:11:59.000000000 -0700
+++ cdtool-2.1.8/cdown.c	2011-01-20 00:57:08.000000000 -0800
@@ -27,6 +27,9 @@
 
 /* CHANGELOG
  *
+ * 0.7	        Modification by Patrick Tullmann
+ *              Handle wrap-around entries (e.g., http://www.freedb.org/freedb/misc/aa101a0d)
+ *
  * 0.6          Modifications by Max Vozeler
  *              Relicensed under the GNU GPL with Byron's permission.
  *
@@ -71,6 +74,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>
+#include <ctype.h>
 #include <errno.h>
 #include <netdb.h>
 #include <unistd.h>
@@ -448,7 +452,11 @@
 void readinfo(char *categ, char *discid) {
   char *message;
   char *firstword;
-  char *cdtitle;
+  char artist[1024];
+  char cdname[1024];
+  char trktitle[64][1024];
+  int maxtrk = -1;
+  int i;
 
   netprintf(sock, "cddb read %s %s\n", categ, discid);
   message = getline();
@@ -466,29 +474,82 @@
       return;
     printf ("%s\r\n", message);
   }
+
+  // Start with empty names
+  memset(artist, 0, sizeof(artist));
+  memset(cdname, 0, sizeof(cdname));
+  artist[0] = '\0';
+  cdname[0] = '\0';
+  for (i = 0; i < 64; i++) {
+    memset(&(trktitle[i][0]), 0, sizeof(trktitle[i]));
+  }
+  
   do {
     message = getline();
     firstword = strchr(message, '=');
     if (firstword != NULL) {
-      *firstword = '\0';
+      *firstword = '\0';                              /* split message at 'firstword' (overwrite '=') */
+      firstword++; // skip the '\0' 
+
+      /*
+       * Only care about DTITLE and TTITLE entries.  DTITLE gets
+       * parsed at first '/' into artist / album.
+       *
+       * Entries can be split on multiple lines:
+       *
+       *   DTITLE=Kanye West / My Beautiful Dark Twisted Fantasy [US, B0014695-02
+       *   DTITLE=]
+       */
+
       if (strcmp(message, "DTITLE") == 0) {
-        cdtitle = strchr(firstword+1, '/');
-	if (cdtitle == NULL) {
-	  cdtitle = firstword+1;
+	if (cdname[0] == '\0') {
+	  // Still parsing artists name
+	  char* tmpname = strchr(firstword, '/');
+	  if (tmpname == NULL) {
+	    strcat(artist, tmpname);	    // XXX overflow
+	  } else {
+	    *tmpname = ' '; // replace '/' with ' '
+	    while (tmpname > firstword && isspace(*tmpname)) --tmpname; // eat trailing spaces at the end of artist
+	    ++tmpname; // preserve the non-space
+	    *tmpname = '\0'; // truncate artist name
+	    ++tmpname;
+
+	    // Save artist onto cd title
+	    strcat(artist, firstword);// XXX overflow
+
+	    // Remainder is cdname:
+	    while (isspace(*tmpname)) ++tmpname; // eat leading space at front of tmpname
+
+	    // Save 
+	    strcat(cdname, tmpname);// XXX overflow
+	  }
 	} else {
-	  *cdtitle = ' ';
-	  while(*--cdtitle == ' ') ;
-	  *++cdtitle = '\0';
-	  while (*++cdtitle == ' ') ;
+	  // DTITLE entry is just more cdname:
+	  strcat(cdname, firstword);
 	}
-        printf("cdname %s\n", cdtitle);
-	printf("artist %s\n", firstword+1);
+
       } else if (strncmp(message, "TTITLE", 6) == 0) {
-        printf("track %s\n", firstword+1);
+	int tnum = atoi(message+6);
+	if (tnum < 0 || tnum > 64) {
+	  fprintf(stderr, "Illegal track number in: %s\n", message);
+	}
+	strcat(&(trktitle[tnum][0]), firstword);// XXX overflow
+
+	if (tnum > maxtrk) {
+	  maxtrk = tnum;
+	}
       }
     }
 /*    printf("%s\n", message);*/
   } while (strcmp(message, ".") != 0);
+
+
+  printf("cdname %s\n", cdname);
+  printf("artist %s\n", artist);
+  for (i = 0; i < maxtrk; i++) {
+    printf("track %s\n", trktitle[i]);
+  }
+
   printf("\n");
 }
 



Reply to: