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: