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
|
||||||
#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
|
#if HAVE_KILLPG
|
||||||
/*
|
/*
|
||||||
@ -1851,13 +1851,15 @@ c_read(const char **wp)
|
|||||||
enum { LINES, BYTES, UPTO, READALL } readmode = LINES;
|
enum { LINES, BYTES, UPTO, READALL } readmode = LINES;
|
||||||
char delim = '\n';
|
char delim = '\n';
|
||||||
size_t bytesleft = 128, bytesread;
|
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;
|
char *cp, *allocd = NULL, *xp;
|
||||||
const char *ccp;
|
const char *ccp;
|
||||||
XString xs;
|
XString xs;
|
||||||
size_t xsave = 0;
|
size_t xsave = 0;
|
||||||
mksh_ttyst tios;
|
mksh_ttyst tios;
|
||||||
bool restore_tios = false;
|
bool restore_tios = false;
|
||||||
|
/* to catch read -aN2 foo[i] */
|
||||||
|
bool subarray = false;
|
||||||
#if HAVE_SELECT
|
#if HAVE_SELECT
|
||||||
bool hastimeout = false;
|
bool hastimeout = false;
|
||||||
struct timeval tv, tvlim;
|
struct timeval tv, tvlim;
|
||||||
@ -2102,6 +2104,7 @@ c_read(const char **wp)
|
|||||||
XinitN(xs, 128, ATEMP);
|
XinitN(xs, 128, ATEMP);
|
||||||
if (intoarray) {
|
if (intoarray) {
|
||||||
vp = global(*wp);
|
vp = global(*wp);
|
||||||
|
subarray = last_lookup_was_array;
|
||||||
if (vp->flag & RDONLY) {
|
if (vp->flag & RDONLY) {
|
||||||
c_read_splitro:
|
c_read_splitro:
|
||||||
bi_errorf("read-only: %s", *wp);
|
bi_errorf("read-only: %s", *wp);
|
||||||
@ -2110,10 +2113,10 @@ c_read(const char **wp)
|
|||||||
afree(cp, ATEMP);
|
afree(cp, ATEMP);
|
||||||
goto c_read_out;
|
goto c_read_out;
|
||||||
}
|
}
|
||||||
/* exporting an array is currently pointless */
|
|
||||||
unset(vp, 1);
|
|
||||||
/* counter for array index */
|
/* counter for array index */
|
||||||
c = 0;
|
c = subarray ? arrayindex(vp) : 0;
|
||||||
|
/* exporting an array is currently pointless */
|
||||||
|
unset(vp, subarray ? 0 : 1);
|
||||||
}
|
}
|
||||||
if (!aschars) {
|
if (!aschars) {
|
||||||
/* skip initial IFS whitespace */
|
/* skip initial IFS whitespace */
|
||||||
@ -2215,7 +2218,18 @@ c_read(const char **wp)
|
|||||||
c_read_gotword:
|
c_read_gotword:
|
||||||
Xput(xs, xp, '\0');
|
Xput(xs, xp, '\0');
|
||||||
if (intoarray) {
|
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 {
|
} else {
|
||||||
vq = global(*wp);
|
vq = global(*wp);
|
||||||
/* must be checked before exporting */
|
/* must be checked before exporting */
|
||||||
|
6
sh.h
6
sh.h
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
* Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||||
* 2011, 2012, 2013, 2014, 2015
|
* 2011, 2012, 2013, 2014, 2015, 2016
|
||||||
* mirabilos <m@mirbsd.org>
|
* mirabilos <m@mirbsd.org>
|
||||||
*
|
*
|
||||||
* Provided that these terms and disclaimer and all copyright notices
|
* Provided that these terms and disclaimer and all copyright notices
|
||||||
@ -175,7 +175,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EXTERN
|
#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
|
#endif
|
||||||
#define MKSH_VERSION "R52 2016/01/13"
|
#define MKSH_VERSION "R52 2016/01/13"
|
||||||
|
|
||||||
@ -1186,6 +1186,8 @@ struct tbl {
|
|||||||
};
|
};
|
||||||
|
|
||||||
EXTERN struct tbl vtemp;
|
EXTERN struct tbl vtemp;
|
||||||
|
/* set by global() and local() */
|
||||||
|
EXTERN bool last_lookup_was_array;
|
||||||
|
|
||||||
/* common flag bits */
|
/* common flag bits */
|
||||||
#define ALLOC BIT(0) /* val.s has been allocated */
|
#define ALLOC BIT(0) /* val.s has been allocated */
|
||||||
|
6
var.c
6
var.c
@ -28,7 +28,7 @@
|
|||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
#endif
|
#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
|
* Variables
|
||||||
@ -295,6 +295,7 @@ global(const char *n)
|
|||||||
if (special(vn))
|
if (special(vn))
|
||||||
vp->flag |= SPECIAL;
|
vp->flag |= SPECIAL;
|
||||||
out:
|
out:
|
||||||
|
last_lookup_was_array = array;
|
||||||
if (vn != n)
|
if (vn != n)
|
||||||
afree(vname.rw, ATEMP);
|
afree(vname.rw, ATEMP);
|
||||||
return (vp);
|
return (vp);
|
||||||
@ -345,6 +346,7 @@ local(const char *n, bool copy)
|
|||||||
if (special(vn))
|
if (special(vn))
|
||||||
vp->flag |= SPECIAL;
|
vp->flag |= SPECIAL;
|
||||||
out:
|
out:
|
||||||
|
last_lookup_was_array = array;
|
||||||
if (vn != n)
|
if (vn != n)
|
||||||
afree(vname.rw, ATEMP);
|
afree(vname.rw, ATEMP);
|
||||||
return (vp);
|
return (vp);
|
||||||
@ -1486,7 +1488,7 @@ arrayname(const char *str)
|
|||||||
const char *p;
|
const char *p;
|
||||||
char *rv;
|
char *rv;
|
||||||
|
|
||||||
if ((p = cstrchr(str, '[')) == 0)
|
if (!(p = cstrchr(str, '[')))
|
||||||
/* Shouldn't happen, but why worry? */
|
/* Shouldn't happen, but why worry? */
|
||||||
strdupx(rv, str, ATEMP);
|
strdupx(rv, str, ATEMP);
|
||||||
else
|
else
|
||||||
|
Loading…
x
Reference in New Issue
Block a user