From 1b0e4f54cbe25b9801e97c7430ec21f50a3c7cc2 Mon Sep 17 00:00:00 2001 From: tg Date: Thu, 14 Jan 2016 22:49:33 +0000 Subject: [PATCH] =?UTF-8?q?permit=20'read=20-A/-a=20arr[idx]'=20as=20long?= =?UTF-8?q?=20as=20only=20one=20element=20is=20read;=20fix=20corruption=20?= =?UTF-8?q?of=20array=20indic=C4=93s=20with=20this=20construct=20(LP#15333?= =?UTF-8?q?96)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- funcs.c | 26 ++++++++++++++++++++------ sh.h | 6 ++++-- var.c | 6 ++++-- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/funcs.c b/funcs.c index 07bd026..c20519a 100644 --- a/funcs.c +++ b/funcs.c @@ -38,7 +38,7 @@ #endif #endif -__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.289 2016/01/13 17:20:49 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.290 2016/01/14 22:49:31 tg Exp $"); #if HAVE_KILLPG /* @@ -1851,13 +1851,15 @@ c_read(const char **wp) enum { LINES, BYTES, UPTO, READALL } readmode = LINES; char delim = '\n'; size_t bytesleft = 128, bytesread; - struct tbl *vp /* FU gcc */ = NULL, *vq; + struct tbl *vp /* FU gcc */ = NULL, *vq = NULL; char *cp, *allocd = NULL, *xp; const char *ccp; XString xs; size_t xsave = 0; mksh_ttyst tios; bool restore_tios = false; + /* to catch read -aN2 foo[i] */ + bool subarray = false; #if HAVE_SELECT bool hastimeout = false; struct timeval tv, tvlim; @@ -2102,6 +2104,7 @@ c_read(const char **wp) XinitN(xs, 128, ATEMP); if (intoarray) { vp = global(*wp); + subarray = last_lookup_was_array; if (vp->flag & RDONLY) { c_read_splitro: bi_errorf("read-only: %s", *wp); @@ -2110,10 +2113,10 @@ c_read(const char **wp) afree(cp, ATEMP); goto c_read_out; } - /* exporting an array is currently pointless */ - unset(vp, 1); /* counter for array index */ - c = 0; + c = subarray ? arrayindex(vp) : 0; + /* exporting an array is currently pointless */ + unset(vp, subarray ? 0 : 1); } if (!aschars) { /* skip initial IFS whitespace */ @@ -2215,7 +2218,18 @@ c_read(const char **wp) c_read_gotword: Xput(xs, xp, '\0'); if (intoarray) { - vq = arraysearch(vp, c++); + if (subarray) { + /* array element passed, accept first read */ + if (vq) { + bi_errorf("nested arrays not yet supported"); + goto c_read_spliterr; + } + vq = vp; + if (c) + /* [0] doesn't */ + vq->flag |= AINDEX; + } else + vq = arraysearch(vp, c++); } else { vq = global(*wp); /* must be checked before exporting */ diff --git a/sh.h b/sh.h index 5d8c0ac..1fb56ca 100644 --- a/sh.h +++ b/sh.h @@ -10,7 +10,7 @@ /*- * Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, - * 2011, 2012, 2013, 2014, 2015 + * 2011, 2012, 2013, 2014, 2015, 2016 * mirabilos * * Provided that these terms and disclaimer and all copyright notices @@ -175,7 +175,7 @@ #endif #ifdef EXTERN -__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.753 2016/01/13 17:20:52 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.754 2016/01/14 22:49:32 tg Exp $"); #endif #define MKSH_VERSION "R52 2016/01/13" @@ -1186,6 +1186,8 @@ struct tbl { }; EXTERN struct tbl vtemp; +/* set by global() and local() */ +EXTERN bool last_lookup_was_array; /* common flag bits */ #define ALLOC BIT(0) /* val.s has been allocated */ diff --git a/var.c b/var.c index 58551e8..d816eb1 100644 --- a/var.c +++ b/var.c @@ -28,7 +28,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/var.c,v 1.196 2016/01/14 20:21:39 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/var.c,v 1.197 2016/01/14 22:49:33 tg Exp $"); /*- * Variables @@ -295,6 +295,7 @@ global(const char *n) if (special(vn)) vp->flag |= SPECIAL; out: + last_lookup_was_array = array; if (vn != n) afree(vname.rw, ATEMP); return (vp); @@ -345,6 +346,7 @@ local(const char *n, bool copy) if (special(vn)) vp->flag |= SPECIAL; out: + last_lookup_was_array = array; if (vn != n) afree(vname.rw, ATEMP); return (vp); @@ -1486,7 +1488,7 @@ arrayname(const char *str) const char *p; char *rv; - if ((p = cstrchr(str, '[')) == 0) + if (!(p = cstrchr(str, '['))) /* Shouldn't happen, but why worry? */ strdupx(rv, str, ATEMP); else