From adwood@earthlink.net  Wed Aug 13 07:45:31 2003
Return-Path: <adwood@earthlink.net>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id E093937B401
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 13 Aug 2003 07:45:31 -0700 (PDT)
Received: from user242.net686.va.sprint-hsd.net (user242.net686.va.sprint-hsd.net [65.41.107.242])
	by mx1.FreeBSD.org (Postfix) with SMTP id 2340D43F93
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 13 Aug 2003 07:45:31 -0700 (PDT)
	(envelope-from adwood@earthlink.net)
Received: (qmail 44585 invoked by uid 1001); 13 Aug 2003 06:03:44 -0000
Message-Id: <20030813060344.44584.qmail@lichen.forest.org>
Date: 13 Aug 2003 06:03:44 -0000
From: Anthony Wood <adwood@earthlink.net>
Reply-To: Anthony Wood <adwood@earthlink.net>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: cdcontrol play tr m:s.f interface is partially broken
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         55546
>Category:       bin
>Synopsis:       [patch] cdcontrol(1) play tr m:s.f interface is partially broken
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Aug 13 07:50:07 PDT 2003
>Closed-Date:    
>Last-Modified:  Sun Mar 20 20:40:01 UTC 2011
>Originator:     Anthony Wood
>Release:        FreeBSD 4.8-STABLE i386
>Organization:
>Environment:
System: FreeBSD lichen.forest.org 4.8-STABLE FreeBSD 4.8-STABLE #0: Fri Jul 18 18:31:24 EDT 2003 root@user56.net688.va.sprint-hsd.net:/usr/obj/usr/src/sys/LICHEN i386

Standard 4-STABLE system.

	
>Description:
The 'play tr m:s.f ...' interface is broken, such that cdcontrol
sometimes rejects a minute:second offset improperly, saying that
'Track x is not that long.'  Other times, when it should reject
the request (eg, 'play 12 35:0'), an Input/Output error occurs
instead.

>How-To-Repeat:
 [Note: 5.x has a fix for a separate (track - 1) problem that is
  necessary to reproduce in exactly the way shown here.]

cdcontrol> info
Starting track = 1, ending track = 19, TOC size = 162 bytes
track     start  duration   block  length   type
-------------------------------------------------
    1   0:02.00   3:17.18       0   14793  audio
    2   3:19.18   3:54.25   14793   17575  audio
    3   7:13.43   2:43.55   32368   12280  audio
    4   9:57.23   3:40.45   44648   16545  audio
    5  13:37.68   2:03.74   61193    9299  audio
    6  15:41.67   3:06.58   70492   14008  audio
    7  18:48.50   2:25.66   84500   10941  audio
    8  21:14.41   3:09.23   95441   14198  audio
    9  24:23.64   6:36.19  109639   29719  audio
   10  31:00.08   4:56.49  139358   22249  audio
   11  35:56.57   4:48.60  161607   21660  audio
   12  40:45.42   2:43.60  183267   12285  audio
[...]
cdcontrol> play 1 0:30
Track 1 is not that long.
cdcontrol> play 11 30:00
cdcontrol: Input/output error

>Fix:

The bug is in function play(), at label Play_Relative_Addresses,
where the msf.(minute|second|frame) fields taken out of toc_buffer[]
are treated as if they were the duration of each track, when in
fact they are the cumulative *start* of each track.  To convert to
duration, which is needed to range check the 'play track m:s.f'
command, something like happens in prtrack() needs to happen.
That is, pull the msf for this and the next track, convert both
to lba, subtract, and convert back to msf.

This is probably an easy bug to fix, except for the 13 different
invocation varieties allowed.


>Release-Note:
>Audit-Trail:

From: "Tatsuki Makino" <tatsuki_makino@hotmail.com>
To: <bug-followup@FreeBSD.org>,
	<adwood@earthlink.net>
Cc: <dwmalone@FreeBSD.org>
Subject: Re: bin/55546: cdcontrol(1) play tr m:s.f interface is partially broken
Date: Thu, 3 Feb 2011 08:45:59 +0900

 This is a multi-part message in MIME format.
 
 ------=_NextPart_000_0005_01CBC37E.C7B45150
 Content-Type: text/plain;
 	format=flowed;
 	charset="iso-2022-jp";
 	reply-type=original
 Content-Transfer-Encoding: 7bit
 
 This is a patch for fixing this problem.
 This patch is created for CVS Revision 1.48.8.1. But it can use to 1.53. 
 ------=_NextPart_000_0005_01CBC37E.C7B45150
 Content-Type: application/octet-stream;
 	name="patch-cdcontrol.c.bz2"
 Content-Transfer-Encoding: base64
 Content-Disposition: attachment;
 	filename="patch-cdcontrol.c.bz2"
 
 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
 
 ------=_NextPart_000_0005_01CBC37E.C7B45150--
 

From: Alexander Best <arundel@freebsd.org>
To: bug-followup@freebsd.org
Cc:  
Subject: Re: bin/55546: cdcontrol(1) play tr m:s.f interface is partially broken
Date: Sun, 20 Mar 2011 20:39:06 +0000

 --82I3+IH0IqGh5yIs
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 
 this issue is still present in 9.0 (r219727).
 
 i've attached the patch again, because the initial patch didn't apply cleanly,
 due to several changes made to cdcontrol since 2003 (year the initial patch was
 submitted).
 
 it would be nice somebody can take a look at this patch after all these years.
 
 cheers.
 alex
 
 -- 
 a13x
 
 --82I3+IH0IqGh5yIs
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: attachment; filename="cdcontrol.patch"
 
 diff --git a/usr.sbin/cdcontrol/cdcontrol.c b/usr.sbin/cdcontrol/cdcontrol.c
 index 526f599..e001c74 100644
 --- a/usr.sbin/cdcontrol/cdcontrol.c
 +++ b/usr.sbin/cdcontrol/cdcontrol.c
 @@ -29,6 +29,11 @@
   * 		the uchar storing the volume (256 -> 0, -20 -> 236, ...).
   * 		Version 2.0.2
   *
 + * 03-Feb-2011	Tatsuki Makino <tatsuki_makino@hotmail.com>
 + * 		Fixed an ability to specify addresses relative to the
 + * 		beginning of a track.
 + * 		Version 2.0.3
 + *
   */
  
  #include <sys/cdefs.h>
 @@ -52,7 +57,7 @@ __FBSDID("$FreeBSD$");
  #include <unistd.h>
  #include <vis.h>
  
 -#define VERSION "2.0.2"
 +#define VERSION "2.0.3"
  
  #define ASTS_INVALID	0x00  /* Audio status byte not valid */
  #define ASTS_PLAYING	0x11  /* Audio play operation in progress */
 @@ -523,6 +528,7 @@ int play (char *arg)
  		unsigned tr1, tr2;
  		unsigned m1, m2, s1, s2, f1, f2;
  		unsigned char tm, ts, tf;
 +		unsigned int lba1, lba2, tlba;
  
  		tr2 = m2 = s2 = f2 = f1 = 0;
  		if (8 == sscanf (arg, "%d %d:%d.%d %d %d:%d.%d",
 @@ -589,118 +595,108 @@ int play (char *arg)
  		goto Try_Absolute_Timed_Addresses;
  
  Play_Relative_Addresses:
 -		if (! tr1)
 +		if (!tr1) {
  			tr1 = 1;
 -		else if (tr1 > n)
 +		} else if (tr1 > n) {
  			tr1 = n;
 +		}
 +		--tr1;
  
 -		tr1--;
 -
 +		/*
 +		 * XXX: need check tr1 == toc_buffer[tr1].track ?
 +		 */
  		if (msf) {
  			tm = toc_buffer[tr1].addr.msf.minute;
  			ts = toc_buffer[tr1].addr.msf.second;
  			tf = toc_buffer[tr1].addr.msf.frame;
 -		} else
 -			lba2msf(ntohl(toc_buffer[tr1].addr.lba),
 -				&tm, &ts, &tf);
 -		if ((m1 > tm)
 -		    || ((m1 == tm)
 -		    && ((s1 > ts)
 -		    || ((s1 == ts)
 -		    && (f1 > tf))))) {
 -			printf ("Track %d is not that long.\n", tr1);
 -			return (0);
 +			tlba = msf2lba(tm, ts, tf);
 +		} else {
 +			tlba = ntohl(toc_buffer[tr1].addr.lba);
  		}
  
 -		f1 += tf;
 -		if (f1 >= 75) {
 -			s1 += f1 / 75;
 -			f1 %= 75;
 -		}
 +		lba1 = msf2lba((u_char)m1, (u_char)s1, (u_char)f1) + 150 + tlba;
  
 -		s1 += ts;
 -		if (s1 >= 60) {
 -			m1 += s1 / 60;
 -			s1 %= 60;
 +		if (lba1 < tlba) {
 +			printf("Track %d is not that long.\n", tr1 + 1);
 +			return 0;
  		}
  
 -		m1 += tm;
 -
 -		if (! tr2) {
 -			if (m2 || s2 || f2) {
 -				tr2 = tr1;
 -				f2 += f1;
 -				if (f2 >= 75) {
 -					s2 += f2 / 75;
 -					f2 %= 75;
 -				}
 -
 -				s2 += s1;
 -				if (s2 > 60) {
 -					m2 += s2 / 60;
 -					s2 %= 60;
 -				}
 +		if (msf) {
 +			tm = toc_buffer[tr1 + 1].addr.msf.minute;
 +			ts = toc_buffer[tr1 + 1].addr.msf.second;
 +			tf = toc_buffer[tr1 + 1].addr.msf.frame;
 +			tlba = msf2lba(tm, ts, tf);
 +		} else {
 +			tlba = ntohl(toc_buffer[tr1 + 1].addr.lba);
 +		}
  
 -				m2 += m1;
 +		if (lba1 > tlba) {
 +			if ((tr1 + 1) == n) {
 +				printf("The playing time of the disc is not that long.\n");
  			} else {
 -				tr2 = n;
 -				if (msf) {
 -					m2 = toc_buffer[n].addr.msf.minute;
 -					s2 = toc_buffer[n].addr.msf.second;
 -					f2 = toc_buffer[n].addr.msf.frame;
 -				} else {
 -					lba2msf(ntohl(toc_buffer[n].addr.lba),
 -						&tm, &ts, &tf);
 -					m2 = tm;
 -					s2 = ts;
 -					f2 = tf;
 -				}
 +				printf("Track %d is not that long.\n", tr1 + 1);
  			}
 +			return 0;
 +		}
 +
 +		if (!tr2) {
 +			tr2 = tr1 + 1;
  		} else if (tr2 > n) {
  			tr2 = n;
 -			m2 = s2 = f2 = 0;
 +		}
 +		--tr2;
 +
 +		if (msf) {
 +			tm = toc_buffer[tr2].addr.msf.minute;
 +			ts = toc_buffer[tr2].addr.msf.second;
 +			tf = toc_buffer[tr2].addr.msf.frame;
 +			tlba = msf2lba(tm, ts, tf);
  		} else {
 -			if (m2 || s2 || f2)
 -				tr2--;
 -			if (msf) {
 -				tm = toc_buffer[tr2].addr.msf.minute;
 -				ts = toc_buffer[tr2].addr.msf.second;
 -				tf = toc_buffer[tr2].addr.msf.frame;
 -			} else
 -				lba2msf(ntohl(toc_buffer[tr2].addr.lba),
 -					&tm, &ts, &tf);
 -			f2 += tf;
 -			if (f2 >= 75) {
 -				s2 += f2 / 75;
 -				f2 %= 75;
 -			}
 +			tlba = ntohl(toc_buffer[tr2].addr.lba);
 +		}
  
 -			s2 += ts;
 -			if (s2 > 60) {
 -				m2 += s2 / 60;
 -				s2 %= 60;
 -			}
 +		if (m2 || s2 || f2) {
 +			lba2 = msf2lba((u_char)m2, (u_char)s2, (u_char)f2) + 150 + tlba;
 +		} else if (msf) {
 +			tm = toc_buffer[tr2 + 1].addr.msf.minute;
 +			ts = toc_buffer[tr2 + 1].addr.msf.second;
 +			tf = toc_buffer[tr2 + 1].addr.msf.frame;
 +			lba2 = msf2lba(tm, ts, tf);
 +		} else {
 +			lba2 = ntohl(toc_buffer[tr2 + 1].addr.lba);
 +		}
  
 -			m2 += tm;
 +		if (lba2 < tlba) {
 +			printf("Track %d is not that long.\n", tr2 + 1);
 +			return 0;
  		}
  
  		if (msf) {
 -			tm = toc_buffer[n].addr.msf.minute;
 -			ts = toc_buffer[n].addr.msf.second;
 -			tf = toc_buffer[n].addr.msf.frame;
 -		} else
 -			lba2msf(ntohl(toc_buffer[n].addr.lba),
 -				&tm, &ts, &tf);
 -		if ((tr2 < n)
 -		    && ((m2 > tm)
 -		    || ((m2 == tm)
 -		    && ((s2 > ts)
 -		    || ((s2 == ts)
 -		    && (f2 > tf)))))) {
 -			printf ("The playing time of the disc is not that long.\n");
 -			return (0);
 +			tm = toc_buffer[tr2 + 1].addr.msf.minute;
 +			ts = toc_buffer[tr2 + 1].addr.msf.second;
 +			tf = toc_buffer[tr2 + 1].addr.msf.frame;
 +			tlba = msf2lba(tm, ts, tf);
 +		} else {
 +			tlba = ntohl(toc_buffer[tr2 + 1].addr.lba);
  		}
 -		return (play_msf (m1, s1, f1, m2, s2, f2));
 +
 +		if (lba2 > tlba) {
 +			if ((tr2 + 1) == n) {
 +				printf("The playing time of the disc is not that long.\n");
 +			} else {
 +				printf("Track %d is not that long.\n", tr2 + 1);
 +			}
 +			return 0;
 +		}
 +
 +		if (lba1 > lba2) {
 +			/* swap */
 +			lba1 ^= lba2;
 +			lba2 ^= lba1;
 +			lba1 ^= lba2;
 +		}
 +
 +		return play_blocks(lba1, lba2 - lba1);
  
  Try_Absolute_Timed_Addresses:
  		if (6 != sscanf (arg, "%d:%d.%d%d:%d.%d",
 
 --82I3+IH0IqGh5yIs--
>Unformatted:
