On Tuesday 05 June 2007 00:32, Denis Vlasenko wrote:
> On Monday 04 June 2007 22:57, Jorgen Cederlof wrote:
> > Hello list,
> > 
> > I encountered a couple of problems with base64 uudecode. It couldn't
> > handle an empty file (term_count needs to be 1 at the beginning of a
> > line to catch the terminating line, which it was for every line but
> > the first) and when the output was supposed to be 3n+1 bytes it wrote
> > an extra junk byte at the end when it encountered the second '='. The
> > patch below should fix both issues.
> 
> Wow. Thanks.
> 
> Can you send a few testcases which you use for testing?

Never mind. Your fix is in svn now, see attached.
If you can test it, that will be great.
--
vda
diff -d -urpN busybox.1/coreutils/uudecode.c busybox.2/coreutils/uudecode.c
--- busybox.1/coreutils/uudecode.c	2007-05-29 23:43:05.000000000 +0200
+++ busybox.2/coreutils/uudecode.c	2007-06-05 01:27:24.000000000 +0200
@@ -70,7 +70,7 @@ static void read_base64(FILE *src_stream
 {
 	static const char base64_table[] =
 		"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n";
-	int term_count = 0;
+	int term_count = 1;
 
 	while (1) {
 		char translated[4];
@@ -86,19 +86,19 @@ static void read_base64(FILE *src_stream
 				if (ch == EOF) {
 					bb_error_msg_and_die("short file");
 				}
-			} while ((table_ptr = strchr(base64_table, ch)) == NULL);
+				table_ptr = strchr(base64_table, ch);
+			} while (table_ptr == NULL);
 
 			/* Convert encoded charcter to decimal */
 			ch = table_ptr - base64_table;
 
 			if (*table_ptr == '=') {
 				if (term_count == 0) {
-					translated[count] = 0;
+					translated[count] = '\0';
 					break;
 				}
 				term_count++;
-			}
-			else if (*table_ptr == '\n') {
+			} else if (*table_ptr == '\n') {
 				/* Check for terminating line */
 				if (term_count == 5) {
 					return;
@@ -113,7 +113,9 @@ static void read_base64(FILE *src_stream
 		}
 
 		/* Merge 6 bit chars to 8 bit */
-	    fputc(translated[0] << 2 | translated[1] >> 4, dst_stream);
+		if (count > 1) {
+			fputc(translated[0] << 2 | translated[1] >> 4, dst_stream);
+		}
 		if (count > 2) {
 			fputc(translated[1] << 4 | translated[2] >> 2, dst_stream);
 		}
@@ -126,19 +128,16 @@ static void read_base64(FILE *src_stream
 int uudecode_main(int argc, char **argv);
 int uudecode_main(int argc, char **argv)
 {
-	FILE *src_stream;
+	FILE *src_stream = stdin;
 	char *outname = NULL;
 	char *line;
 
+	opt_complementary = "?1"; /* 1 argument max */
 	getopt32(argc, argv, "o:", &outname);
+	argv += optind;
 
-	if (optind == argc) {
-		src_stream = stdin;
-	} else if (optind + 1 == argc) {
-		src_stream = xfopen(argv[optind], "r");
-	} else {
-		bb_show_usage();
-	}
+	if (argv[0])
+		src_stream = xfopen(argv[0], "r");
 
 	/* Search for the start of the encoding */
 	while ((line = xmalloc_getline(src_stream)) != NULL) {
@@ -158,6 +157,7 @@ int uudecode_main(int argc, char **argv)
 			continue;
 		}
 
+		/* begin line found. decode and exit */
 		mode = strtoul(line_ptr, NULL, 8);
 		if (outname == NULL) {
 			outname = strchr(line_ptr, ' ');
@@ -166,16 +166,48 @@ int uudecode_main(int argc, char **argv)
 			}
 			outname++;
 		}
-		if (LONE_DASH(outname)) {
-			dst_stream = stdout;
-		} else {
+		dst_stream = stdout;
+		if (NOT_LONE_DASH(outname)) {
 			dst_stream = xfopen(outname, "w");
 			chmod(outname, mode & (S_IRWXU | S_IRWXG | S_IRWXO));
 		}
 		free(line);
 		decode_fn_ptr(src_stream, dst_stream);
-		fclose_if_not_stdin(src_stream);
+		/* fclose_if_not_stdin(src_stream); - redundant */
 		return EXIT_SUCCESS;
 	}
 	bb_error_msg_and_die("no 'begin' line");
 }
+
+/* Test script.
+Put this into an empty dir with busybox binary, an run.
+
+#!/bin/sh
+test -x busybox || { echo "No ./busybox?"; exit; }
+ln -sf busybox uudecode
+ln -sf busybox uuencode
+>A_null
+echo -n A >A
+echo -n AB >AB
+echo -n ABC >ABC
+echo -n ABCD >ABCD
+echo -n ABCDE >ABCDE
+echo -n ABCDEF >ABCDEF
+cat busybox >A_bbox
+for f in A*; do
+    echo uuencode $f
+    ./uuencode    $f <$f >u_$f
+    ./uuencode -m $f <$f >m_$f
+done
+mkdir unpk_u unpk_m 2>/dev/null
+for f in u_*; do
+    ./uudecode <$f -o unpk_u/${f:2}
+    diff -a ${f:2} unpk_u/${f:2} >/dev/null 2>&1
+    echo uudecode $f: $?
+done
+for f in m_*; do
+    ./uudecode <$f -o unpk_m/${f:2}
+    diff -a ${f:2} unpk_m/${f:2} >/dev/null 2>&1
+    echo uudecode $f: $?
+done
+*/
diff -d -urpN busybox.1/coreutils/uuencode.c busybox.2/coreutils/uuencode.c
--- busybox.1/coreutils/uuencode.c	2007-05-29 23:43:05.000000000 +0200
+++ busybox.2/coreutils/uuencode.c	2007-06-05 00:51:01.000000000 +0200
@@ -28,7 +28,7 @@ int uuencode_main(int argc, char **argv)
 	RESERVE_CONFIG_BUFFER(dst_buf, DST_BUF_SIZE + 1);
 
 	tbl = bb_uuenc_tbl_std;
-	if (getopt32(argc, argv, "m") & 1) {
+	if (getopt32(argc, argv, "m")) {
 		tbl = bb_uuenc_tbl_base64;
 	}
 
@@ -37,9 +37,6 @@ int uuencode_main(int argc, char **argv)
 			src_stream = xfopen(argv[optind], "r");
 			xstat(argv[optind], &stat_buf);
 			mode = stat_buf.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
-			if (src_stream == stdout) {
-				puts("NULL");
-			}
 			break;
 		case 1:
 			mode = 0666 & ~umask(0666);
diff -d -urpN busybox.1/include/usage.h busybox.2/include/usage.h
--- busybox.1/include/usage.h	2007-05-30 02:29:31.000000000 +0200
+++ busybox.2/include/usage.h	2007-06-05 01:29:46.000000000 +0200
@@ -3664,20 +3664,19 @@ USE_FEATURE_RUN_PARTS_FANCY("\n	-l	Print
        "[pauses for 1 second]\n"
 
 #define uudecode_trivial_usage \
-       "[FILE]..."
+       "[-o outfile] [infile]"
 #define uudecode_full_usage \
-       "Uudecode a file" \
-       "\n\nOptions:\n" \
-       "	-o FILE	Direct output to FILE"
+       "Uudecode a file\n" \
+       "NB: finds outfile name in uuencoded source unless -o is given"
 #define uudecode_example_usage \
        "$ uudecode -o busybox busybox.uu\n" \
        "$ ls -l busybox\n" \
        "-rwxr-xr-x   1 ams      ams        245264 Jun  7 21:35 busybox\n"
 
 #define uuencode_trivial_usage \
-       "[OPTION] [INFILE] REMOTEFILE"
+       "[-m] [infile] stored_filename"
 #define uuencode_full_usage \
-       "Uuencode a file" \
+       "Uuencode a file to stdout" \
        "\n\nOptions:\n" \
        "	-m	Use base64 encoding per RFC1521"
 #define uuencode_example_usage \
_______________________________________________
busybox mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/busybox

Reply via email to