Bug 17476

Summary: uudecode -i (no overwrite) flag bogus
Product: Base System Reporter: jon <jon>
Component: binAssignee: Sheldon Hearn <sheldonh>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: Unspecified   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
file.diff none

Description jon 2000-03-18 20:00:01 UTC
The -i flag in uudecode has no effect except for printing "not overwritten".
It overwrites the file anyway.  This problem existed since the introduction
of the -i flag in uudecode.

Fix: recommend the following patch: (should work on -STABLE and -CURRENT)
How-To-Repeat: uudecode foo < somefile > foo.uu
touch foo
uudecode -i foo.uu
(uudecode will now tell you "foo" was not overwritten, but overwrite it anyway)
Comment 1 Sheldon Hearn freebsd_committer freebsd_triage 2000-03-20 09:42:38 UTC
Responsible Changed
From-To: freebsd-bugs->sheldonh

I'll take this one. 

Comment 2 Sheldon Hearn 2000-03-20 09:47:26 UTC
On Sat, 18 Mar 2000 14:52:53 EST, Jonathan Chen wrote:

> -		if (iflag && !access(buf, F_OK))
> +		if (iflag && !access(buf, F_OK)) {
>  			(void)fprintf(stderr, "not overwritten: %s\n", buf);
> -		if (!freopen(buf, "w", stdout) ||
> +			freopen("/dev/null", "w", stdout);
> +		} else if (!freopen(buf, "w", stdout) ||
>  		    fchmod(fileno(stdout), mode&0666)) {

Shouldn't we still check the return value of the freopen call in the
iflag case?

Ciao,
Sheldon.
Comment 3 jon 2000-03-22 07:28:03 UTC
On Mon, Mar 20, 2000 at 11:47:26AM +0200, Sheldon Hearn wrote:
> 
> 
> On Sat, 18 Mar 2000 14:52:53 EST, Jonathan Chen wrote:
> 
> > -		if (iflag && !access(buf, F_OK))
> > +		if (iflag && !access(buf, F_OK)) {
> >  			(void)fprintf(stderr, "not overwritten: %s\n", buf);
> > -		if (!freopen(buf, "w", stdout) ||
> > +			freopen("/dev/null", "w", stdout);
> > +		} else if (!freopen(buf, "w", stdout) ||
> >  		    fchmod(fileno(stdout), mode&0666)) {
> 
> Shouldn't we still check the return value of the freopen call in the
> iflag case?

I suppose you can change that line to 
if (freopen("/dev/null", "w", stdout)==NULL) perror("Cannot open /dev/null"), exit(1);

When I originally made the report I figured everyone would have /dev/null
but didn't take into account of chrooted environments and such...  I
suppose a more "elegant" solution might be to jump to a function that just
reads till it sees the end -- but if you do that then you won't be warned
if there's a potential error in the ignored uuencoded file.  Opening
/dev/null just seems to me the easiest and most direct way of skimming over
the file.

-- 
    (o_ 1-2-1-2-1-2-1-2-1-2-1-2-1-2-1-2-1-2-1-2-1-2-1-2-1-2-1-2-1-2 _o)
 \\\_\            Jonathan Chen              jon@spock.org           /_///
 <____) 2 is not equal to 3 -- not even for the largest value of 2. (____>
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Comment 4 Sheldon Hearn 2000-03-22 10:43:00 UTC
On Wed, 22 Mar 2000 02:28:03 EST, Jonathan Chen wrote:

> When I originally made the report I figured everyone would have
> /dev/null but didn't take into account of chrooted environments and
> such...  I suppose a more "elegant" solution might be to jump to a
> function that just reads till it sees the end

Since elegance isn't one of the main attractions of the existing code, I
was thinking something more along the lines of the following. :-)

Ciao,
Sheldon.

Index: uudecode.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/uudecode/uudecode.c,v
retrieving revision 1.13
diff -u -d -r1.13 uudecode.c
--- uudecode.c	1999/08/28 01:07:16	1.13
+++ uudecode.c	2000/03/22 10:39:04
@@ -141,11 +141,11 @@
 	struct passwd *pw;
 	register int n;
 	register char ch, first, *p;
-	int mode, n1;
+	int ignore, mode, n1;
 	char buf[MAXPATHLEN];
 	char buffn[MAXPATHLEN]; /* file name buffer */
 
-	
+	ignore = 0;
 	/* search for header line */
 	do {
 		if (!fgets(buf, sizeof(buf), stdin)) {
@@ -197,9 +197,10 @@
 		; /* print to stdout */
 
 	else {
-		if (iflag && !access(buf, F_OK))
+		if (iflag && !access(buf, F_OK)) {
 			(void)fprintf(stderr, "not overwritten: %s\n", buf);
-		if (!freopen(buf, "w", stdout) ||
+			ignore++;
+		} else if (!freopen(buf, "w", stdout) ||
 		    fchmod(fileno(stdout), mode&0666)) {
 			warn("%s: %s", buf, filename);
 			return(1);
@@ -224,6 +225,9 @@
  	filename, buffn, 1 + ' ', 077 + ' ' + 1); \
         return(1); \
 }
+#define PUTCHAR(c) \
+if (!ignore) \
+	putchar(c)
 
 
 		/*
@@ -239,11 +243,11 @@
                                 	OUT_OF_RANGE
 
 				ch = DEC(p[0]) << 2 | DEC(p[1]) >> 4;
-				putchar(ch);
+				PUTCHAR(ch);
 				ch = DEC(p[1]) << 4 | DEC(p[2]) >> 2;
-				putchar(ch);
+				PUTCHAR(ch);
 				ch = DEC(p[2]) << 6 | DEC(p[3]);
-				putchar(ch);
+				PUTCHAR(ch);
 				
 			}
 			else {
@@ -251,7 +255,7 @@
 					if (!(IS_DEC(*p) && IS_DEC(*(p + 1))))
 	                                	OUT_OF_RANGE
 					ch = DEC(p[0]) << 2 | DEC(p[1]) >> 4;
-					putchar(ch);
+					PUTCHAR(ch);
 				}
 				if (n >= 2) {
 					if (!(IS_DEC(*(p + 1)) && 
@@ -259,14 +263,14 @@
 		                                OUT_OF_RANGE
 
 					ch = DEC(p[1]) << 4 | DEC(p[2]) >> 2;
-					putchar(ch);
+					PUTCHAR(ch);
 				}
 				if (n >= 3) {
 					if (!(IS_DEC(*(p + 2)) && 
 						IS_DEC(*(p + 3))))
 		                                OUT_OF_RANGE
 					ch = DEC(p[2]) << 6 | DEC(p[3]);
-					putchar(ch);
+					PUTCHAR(ch);
 				}
 			}
 	}
Comment 5 jon 2000-03-23 20:41:05 UTC
On Wed, Mar 22, 2000 at 12:43:00PM +0200, Sheldon Hearn wrote:
> 
> On Wed, 22 Mar 2000 02:28:03 EST, Jonathan Chen wrote:
> 
> > When I originally made the report I figured everyone would have
> > /dev/null but didn't take into account of chrooted environments and
> > such...  I suppose a more "elegant" solution might be to jump to a
> > function that just reads till it sees the end
> 
> Since elegance isn't one of the main attractions of the existing code, I
> was thinking something more along the lines of the following. :-)

[snip]

Looks good to me...

-- 
    (o_ 1-2-1-2-1-2-1-2-1-2-1-2-1-2-1-2-1-2-1-2-1-2-1-2-1-2-1-2-1-2 _o)
 \\\_\            Jonathan Chen              jon@spock.org           /_///
 <____) 2 is not equal to 3 -- not even for the largest value of 2. (____>
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Comment 6 Sheldon Hearn freebsd_committer freebsd_triage 2000-03-27 12:49:56 UTC
State Changed
From-To: open->analyzed

Committed in rev 1.14 of src/usr.bin/uudecode/uudecode.c. 
Left in this state as a reminder to MFC later., 
Comment 7 nbm freebsd_committer freebsd_triage 2000-08-06 18:21:09 UTC
State Changed
From-To: analyzed->closed

sheldonh MFC'd this in revision 1.13.2.1 of uudecode.c