permit 'read -A/-a arr[idx]' as long as only one element is read;
fix corruption of array indicēs with this construct (LP#1533396)
This commit is contained in:
parent
0141794c2e
commit
1b0e4f54cb
26
funcs.c
26
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 */
|
||||
|
6
sh.h
6
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 <m@mirbsd.org>
|
||||
*
|
||||
* 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 */
|
||||
|
6
var.c
6
var.c
@ -28,7 +28,7 @@
|
||||
#include <sys/sysctl.h>
|
||||
#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
|
||||
|
Loading…
x
Reference in New Issue
Block a user