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

Bug#682992: marked as done (unblock: mksh/40.9.20120630-2)



Your message dated Wed, 29 Aug 2012 21:13:00 +0100
with message-id <1346271180.29555.15.camel@jacala.jungle.funky-badger.org>
and subject line Re: Bug#682992: unblock: mksh/40.9.20120630-2
has caused the Debian Bug report #682992,
regarding unblock: mksh/40.9.20120630-2
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
682992: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=682992
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Please unblock package mksh

This is a resend of <Pine.BSM.4.64L.1207240952130.30311@herc.mirbsd.org>
as requested in the d-d-a mail of today.

unblock mksh/40.9.20120630-2

Hi,

after getting negative responses, I decided to start a wheezy
maintenance branch and only cherry-pick the important fixes.
The attached diff has been cleaned off "RCS ID" and other
version numbering only noise from comments, and diffs the
patched source + debian/ not the quilt patches, for easier
review.

The package's otherwise in a good shape, built everywhere,
I've been using the new version for a while, etc. (and even
the klibc version is safe, as longjmp is never passed 0).

Changes:

* Fix CONSERVATIVE_FDS: the definition was missing in one
  case and silently ignored in another due to use of the
  macro before its implicit definition; also add this fact
  to the lksh(1) manpage

* Correct a regression wrt. tab completion, at least two
  other bugs in the same code, and the same bug class in
  similar code (e.g. inline-expansion with Esc+*) that
  could lead to unrelated input on the current command
  line being overwritten (and sanitise int into size_t,
  for 64-bit cleanliness), upstream bug LP#1025843


-- System Information:
Debian Release: wheezy/sid
  APT prefers unreleased
  APT policy: (500, 'unreleased'), (500, 'unstable')
Architecture: m68k

Kernel: Linux 3.2.0-2-atari
Locale: LANG=C, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/mksh-static
--- mksh-40.9.20120630-1/Build.sh	2012-06-28 20:18:21.000000000 +0000
+++ mksh-40.9.20120630-2/Build.sh	2012-07-24 09:54:20.000000000 +0000
@@ -414,6 +414,7 @@ else
 	check_categories="$check_categories shell:legacy-yes"
 	add_cppflags -DMKSH_LEGACY_MODE
 	HAVE_PERSISTENT_HISTORY=0
+	HAVE_ISSET_MKSH_CONSERVATIVE_FDS=1	# from sh.h
 fi
 
 if test x"$srcdir" = x"."; then
--- mksh-40.9.20120630-1/debian/changelog	2012-06-30 17:34:53.000000000 +0000
+++ mksh-40.9.20120630-2/debian/changelog	2012-07-20 23:33:59.000000000 +0000
@@ -1,3 +1,14 @@
+mksh (40.9.20120630-2) unstable; urgency=low
+
+  * The “kutweer” upload
+  * Apply cherry-picked fixes from mksh CVS (branch mksh-wheezy):
+    - [tg] Fix CONSERVATIVE_FDS use-before-definition bug
+    - [tg] Correct a regression when tab-completing (LP#1025843) and fix
+      bugs in the same code wrt. completion display and other expansions
+  * Document use of CONSERVATIVE_FDS in lksh manpage
+
+ -- Thorsten Glaser <tg@mirbsd.de>  Fri, 20 Jul 2012 23:32:37 +0000
+
 mksh (40.9.20120630-1) unstable; urgency=low
 
   * The “GC2TDN7” upload
--- mksh-40.9.20120630-1/debian/lksh.1	2012-06-30 17:25:00.000000000 +0000
+++ mksh-40.9.20120630-2/debian/lksh.1	2012-07-20 23:34:00.000000000 +0000
@@ -223,6 +223,9 @@ but might work on 32-bit and 64-bit
 .Vt long
 types
 .Pc .
+.It
+.Nm
+only offers the traditional ten file descriptors to scripts.
 .El
 .Sh SEE ALSO
 .Xr mksh 1
@@ -262,4 +265,8 @@ or the
 IRC channel at
 .Pa irc.freenode.net
 .Pq Port 6697 SSL, 6667 unencrypted
-if you need any further quirks.
+if you need any further quirks or assistance,
+and consider migrating your legacy scripts to work with
+.Nm mksh
+instead of requiring
+.Nm .
--- mksh-40.9.20120630-1/edit.c	2012-05-05 17:33:19.000000000 +0000
+++ mksh-40.9.20120630-2/edit.c	2012-07-24 09:54:20.000000000 +0000
@@ -76,6 +76,8 @@ static int x_do_comment(char *, ssize_t,
 static void x_print_expansions(int, char *const *, bool);
 static int x_cf_glob(int *, const char *, int, int, int *, int *, char ***);
 static size_t x_longest_prefix(int, char *const *);
+static void x_glob_hlp_add_qchar(char *);
+static void x_glob_hlp_rem_qchar(char *);
 static int x_basename(const char *, const char *);
 static void x_free_words(int, char **);
 static int x_escape(const char *, size_t, int (*)(const char *, size_t));
@@ -281,50 +283,78 @@ x_print_expansions(int nwords, char * co
 		XPfree(l);
 }
 
-/**
- * Do file globbing:
- *	- appends * to (copy of) str if no globbing chars found
- *	- does expansion, checks for no match, etc.
- *	- sets *wordsp to array of matching strings
- *	- returns number of matching strings
+/*
+ * Convert backslash-escaped string to QCHAR-escaped
+ * string useful for globbing; loses QCHAR unless it
+ * can squeeze in, eg. by previous loss of backslash
  */
-static int
-x_file_glob(int flags MKSH_A_UNUSED, char *toglob, char ***wordsp)
+static void
+x_glob_hlp_add_qchar(char *cp)
 {
-	char ch, **words;
-	int nwords, i = 0, idx = 0;
-	bool escaping;
-	XPtrV w;
-	struct source *s, *sold;
+	char ch, *dp = cp;
+	bool escaping = false;
 
-	/* remove all escaping backward slashes */
-	escaping = false;
-	while ((ch = toglob[i++])) {
+	while ((ch = *cp++)) {
 		if (ch == '\\' && !escaping) {
 			escaping = true;
 			continue;
 		}
-		if (escaping) {
+		if (escaping || (ch == QCHAR && (cp - dp) > 1)) {
 			/*
 			 * empirically made list of chars to escape
-			 * for globbing; ASCII 0x02 probably too as
-			 * that's what QCHAR is, but...
+			 * for globbing as well as QCHAR itself
 			 */
 			switch (ch) {
+			case QCHAR:
 			case '$':
 			case '*':
 			case '?':
 			case '[':
 			case '\\':
 			case '`':
-				toglob[idx++] = QCHAR;
+				*dp++ = QCHAR;
 				break;
 			}
 			escaping = false;
 		}
-		toglob[idx++] = ch;
+		*dp++ = ch;
 	}
-	toglob[idx] = '\0';
+	*dp = '\0';
+}
+
+/*
+ * Unescape a QCHAR-escaped string
+ */
+static void
+x_glob_hlp_rem_qchar(char *cp)
+{
+	char ch, *dp = cp;
+
+	while ((ch = *cp++)) {
+		if (ch == QCHAR && !(ch = *cp++))
+			break;
+		*dp++ = ch;
+	}
+	*dp = '\0';
+}
+
+/**
+ * Do file globbing:
+ *	- appends * to (copy of) str if no globbing chars found
+ *	- does expansion, checks for no match, etc.
+ *	- sets *wordsp to array of matching strings
+ *	- returns number of matching strings
+ */
+static int
+x_file_glob(int flags MKSH_A_UNUSED, char *toglob, char ***wordsp)
+{
+	char **words;
+	int nwords;
+	XPtrV w;
+	struct source *s, *sold;
+
+	/* remove all escaping backward slashes */
+	x_glob_hlp_add_qchar(toglob);
 
 	/*
 	 * Convert "foo*" (toglob) to an array of strings (words)
@@ -350,13 +380,7 @@ x_file_glob(int flags MKSH_A_UNUSED, cha
 		struct stat statb;
 
 		/* Drop all QCHAR from toglob for strcmp below */
-		i = 0;
-		idx = 0;
-		while ((ch = toglob[i++])) {
-			if (ch != QCHAR)
-				toglob[idx++] = ch;
-		}
-		toglob[idx] = '\0';
+		x_glob_hlp_rem_qchar(toglob);
 
 		/*
 		 * Check if globbing failed (returned glob pattern),
@@ -915,9 +939,9 @@ static int holdlen;		/* length of holdbu
 static bool prompt_redraw;	/* false if newline forced after prompt */
 
 static int x_ins(const char *);
-static void x_delete(int, int);
-static int x_bword(void);
-static int x_fword(int);
+static void x_delete(size_t, bool);
+static size_t x_bword(void);
+static size_t x_fword(bool);
 static void x_goto(char *);
 static void x_bs3(char **);
 static int x_size_str(char *);
@@ -949,6 +973,7 @@ static int x_fold_case(int);
 #endif
 static char *x_lastcp(void);
 static void do_complete(int, Comp_type);
+static size_t x_nb2nc(size_t);
 
 static int unget_char = -1;
 
@@ -1067,6 +1092,17 @@ static struct x_defbindings const x_defb
 #endif
 };
 
+static size_t
+x_nb2nc(size_t nb)
+{
+	char *cp;
+	size_t nc = 0;
+
+	for (cp = xcp; cp < (xcp + nb); ++nc)
+		cp += utf_ptradj(cp);
+	return (nc);
+}
+
 #ifdef MKSH_SMALL
 static void x_modified(void);
 static void
@@ -1329,7 +1365,7 @@ x_ins(const char *s)
 static int
 x_del_back(int c MKSH_A_UNUSED)
 {
-	int i = 0;
+	ssize_t i = 0;
 
 	if (xcp == xbuf) {
 		x_e_putc2(7);
@@ -1346,7 +1382,7 @@ static int
 x_del_char(int c MKSH_A_UNUSED)
 {
 	char *cp, *cp2;
-	int i = 0;
+	ssize_t i = 0;
 
 	cp = xcp;
 	while (i < x_arg) {
@@ -1367,9 +1403,9 @@ x_del_char(int c MKSH_A_UNUSED)
 
 /* Delete nc chars to the right of the cursor (including cursor position) */
 static void
-x_delete(int nc, int push)
+x_delete(size_t nc, bool push)
 {
-	int i, nb, nw;
+	size_t i, nb, nw;
 	char *cp;
 
 	if (nc == 0)
@@ -1453,21 +1489,21 @@ x_mv_bword(int c MKSH_A_UNUSED)
 static int
 x_mv_fword(int c MKSH_A_UNUSED)
 {
-	x_fword(1);
+	x_fword(true);
 	return (KSTD);
 }
 
 static int
 x_del_fword(int c MKSH_A_UNUSED)
 {
-	x_delete(x_fword(0), true);
+	x_delete(x_fword(false), true);
 	return (KSTD);
 }
 
-static int
+static size_t
 x_bword(void)
 {
-	int nc = 0, nb = 0;
+	size_t nb = 0;
 	char *cp = xcp;
 
 	if (cp == xbuf) {
@@ -1485,16 +1521,14 @@ x_bword(void)
 		}
 	}
 	x_goto(cp);
-	for (cp = xcp; cp < (xcp + nb); ++nc)
-		cp += utf_ptradj(cp);
-	return (nc);
+	return (x_nb2nc(nb));
 }
 
-static int
-x_fword(int move)
+static size_t
+x_fword(bool move)
 {
-	int nc = 0;
-	char *cp = xcp, *cp2;
+	size_t nc;
+	char *cp = xcp;
 
 	if (cp == xep) {
 		x_e_putc2(7);
@@ -1506,8 +1540,7 @@ x_fword(int move)
 		while (cp != xep && !is_mfs(*cp))
 			cp++;
 	}
-	for (cp2 = xcp; cp2 < cp; ++nc)
-		cp2 += utf_ptradj(cp2);
+	nc = x_nb2nc(cp - xcp);
 	if (move)
 		x_goto(cp);
 	return (nc);
@@ -2195,20 +2228,18 @@ x_meta2(int c MKSH_A_UNUSED)
 static int
 x_kill(int c MKSH_A_UNUSED)
 {
-	int col = xcp - xbuf;
-	int lastcol = xep - xbuf;
-	int ndel;
-
-	if (x_arg_defaulted)
-		x_arg = lastcol;
-	else if (x_arg > lastcol)
-		x_arg = lastcol;
-	ndel = x_arg - col;
-	if (ndel < 0) {
-		x_goto(xbuf + x_arg);
-		ndel = -ndel;
-	}
-	x_delete(ndel, true);
+	size_t col = xcp - xbuf;
+	size_t lastcol = xep - xbuf;
+	size_t ndel, narg;
+
+	if (x_arg_defaulted || (narg = x_arg) > lastcol)
+		narg = lastcol;
+	if (narg < col) {
+		x_goto(xbuf + narg);
+		ndel = col - narg;
+	} else
+		ndel = narg - col;
+	x_delete(x_nb2nc(ndel), true);
 	return (KSTD);
 }
 
@@ -2256,7 +2287,7 @@ x_meta_yank(int c MKSH_A_UNUSED)
 	}
 	len = strlen(killstack[killtp]);
 	x_goto(xcp - len);
-	x_delete(len, false);
+	x_delete(x_nb2nc(len), false);
 	do {
 		if (killtp == 0)
 			killtp = KILLSIZE - 1;
@@ -2576,7 +2607,7 @@ x_set_mark(int c MKSH_A_UNUSED)
 static int
 x_kill_region(int c MKSH_A_UNUSED)
 {
-	int rsize;
+	size_t rsize;
 	char *xr;
 
 	if (xmp == NULL) {
@@ -2591,7 +2622,7 @@ x_kill_region(int c MKSH_A_UNUSED)
 		xr = xmp;
 	}
 	x_goto(xr);
-	x_delete(rsize, true);
+	x_delete(x_nb2nc(rsize), true);
 	xmp = xr;
 	return (KSTD);
 }
@@ -2684,7 +2715,7 @@ x_expand(int c MKSH_A_UNUSED)
 		return (KSTD);
 	}
 	x_goto(xbuf + start);
-	x_delete(end - start, false);
+	x_delete(x_nb2nc(end - start), false);
 
 	i = 0;
 	while (i < nwords) {
@@ -2708,7 +2739,7 @@ do_complete(
 {
 	char **words;
 	int start, end, nlen, olen, nwords;
-	bool completed = false;
+	bool completed;
 
 	nwords = x_cf_glob(&flags, xbuf, xep - xbuf, xcp - xbuf,
 	    &start, &end, &words);
@@ -2726,14 +2757,47 @@ do_complete(
 	}
 	olen = end - start;
 	nlen = x_longest_prefix(nwords, words);
-	/* always complete */
-	x_goto(xbuf + start);
-	x_delete(olen, false);
-	x_escape(words[0], nlen, x_do_ins);
-	x_adjust();
-	/* check if we did add something */
-	if (xcp - (xbuf + start) > olen)
+	if (nwords == 1 || (flags & XCF_IS_SUBGLOB)) {
+		/*
+		 * always complete the expansion of parameter and
+		 * homedir substitution as well as single matches
+		 */
 		completed = true;
+	} else {
+		char *unescaped;
+
+		/* make a copy of the original string part and... */
+		strndupx(unescaped, xbuf + start, olen, ATEMP);
+		/* ... convert it from backslash-escaped via QCHAR-escaped... */
+		x_glob_hlp_add_qchar(unescaped);
+		/* ... to unescaped, for comparison with the matches */
+		x_glob_hlp_rem_qchar(unescaped);
+		/*
+		 * match iff entire original string is part of the
+		 * longest prefix, implying the latter is at least
+		 * the same size (after unescaping)
+		 */
+		completed = !strncmp(words[0], unescaped, strlen(unescaped));
+
+		afree(unescaped, ATEMP);
+	}
+	if (type == CT_COMPLIST && nwords > 1) {
+		/*
+		 * print expansions, since we didn't get back
+		 * just a single match
+		 */
+		x_print_expansions(nwords, words,
+		    tobool(flags & XCF_IS_COMMAND));
+	}
+	if (completed) {
+		/* expand on the command line */
+		xmp = NULL;
+		xcp = xbuf + start;
+		xep -= olen;
+		memmove(xcp, xcp + olen, xep - xcp + 1);
+		x_escape(words[0], nlen, x_do_ins);
+	}
+	x_adjust();
 	/*
 	 * append a space if this is a single non-directory match
 	 * and not a parameter or homedir substitution
@@ -2741,15 +2805,7 @@ do_complete(
 	if (nwords == 1 && words[0][nlen - 1] != '/' &&
 	    !(flags & XCF_IS_SUBGLOB)) {
 		x_ins(" ");
-		completed = true;
 	}
-	if (type == CT_COMPLIST && !completed) {
-		x_print_expansions(nwords, words,
-		    tobool(flags & XCF_IS_COMMAND));
-		completed = true;
-	}
-	if (completed)
-		x_redraw(0);
 
 	x_free_words(nwords, words);
 }
--- mksh-40.9.20120630-1/sh.h	2012-06-28 20:18:25.000000000 +0000
+++ mksh-40.9.20120630-2/sh.h	2012-07-24 09:54:20.000000000 +0000
@@ -412,15 +412,6 @@ extern int wcwidth(__WCHAR_TYPE__);
 #define BIT(i)		(1 << (i))
 #define NELEM(a)	(sizeof(a) / sizeof((a)[0]))
 
-/* these shall be smaller than 100 */
-#ifdef MKSH_CONSERVATIVE_FDS
-#define NUFILE		32	/* Number of user-accessible files */
-#define FDBASE		10	/* First file usable by Shell */
-#else
-#define NUFILE		56	/* Number of user-accessible files */
-#define FDBASE		24	/* First file usable by Shell */
-#endif
-
 /*
  * Make MAGIC a char that might be printed to make bugs more obvious, but
  * not a char that is used often. Also, can't use the high bit as it causes
@@ -545,6 +536,9 @@ im_sorry_dave(void)
 #ifndef MKSH_NO_CMDLINE_EDITING
 #define MKSH_NO_CMDLINE_EDITING	/* defined */
 #endif
+#ifndef MKSH_CONSERVATIVE_FDS
+#define MKSH_CONSERVATIVE_FDS	/* defined */
+#endif
 #undef MKSH_S_NOVI
 #define MKSH_S_NOVI		1
 #endif
@@ -569,6 +563,15 @@ im_sorry_dave(void)
 #define MKSH_UNEMPLOYED		1
 #endif
 
+/* these shall be smaller than 100 */
+#ifdef MKSH_CONSERVATIVE_FDS
+#define NUFILE		32	/* Number of user-accessible files */
+#define FDBASE		10	/* First file usable by Shell */
+#else
+#define NUFILE		56	/* Number of user-accessible files */
+#define FDBASE		24	/* First file usable by Shell */
+#endif
+
 /*
  * simple grouping allocator
  */

--- End Message ---
--- Begin Message ---
On Fri, 2012-07-27 at 19:49 +0000, Thorsten Glaser wrote:
> Please unblock package mksh
[...]
> after getting negative responses, I decided to start a wheezy
> maintenance branch and only cherry-pick the important fixes.
> The attached diff has been cleaned off "RCS ID" and other
> version numbering only noise from comments, and diffs the
> patched source + debian/ not the quilt patches, for easier
> review.

Well, you say "quilt patches".  Apparently you actually mean

 patches/debian-changes |  523 +++++++++++++++++++++++++++++++++++++++++++++++++

> * Fix CONSERVATIVE_FDS: the definition was missing in one
>   case and silently ignored in another due to use of the
>   macro before its implicit definition; also add this fact
>   to the lksh(1) manpage

Please don't assume that we know what CONSERVATIVE_FDS is. :-p

> * Correct a regression wrt. tab completion, at least two
>   other bugs in the same code, and the same bug class in
>   similar code (e.g. inline-expansion with Esc+*) that
>   could lead to unrelated input on the current command
>   line being overwritten (and sanitise int into size_t,
>   for 64-bit cleanliness), upstream bug LP#1025843

That's not the most pleasant diff in the world to read.  I've assumed it
works, as I'm not installing mksh just to check it. :)

Unblocked.

Regards,

Adam

--- End Message ---

Reply to: