aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--shell/ash.c105
1 files changed, 55 insertions, 50 deletions
diff --git a/shell/ash.c b/shell/ash.c
index eca4ab98c..ab13021a3 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -2700,8 +2700,8 @@ SIT(int c, int syntax)
} else
#endif
{
- if ((unsigned char)c >= (unsigned char)(CTLESC)
- && (unsigned char)c <= (unsigned char)(CTLQUOTEMARK)
+ if ((unsigned char)c >= CTLESC
+ && (unsigned char)c <= CTLQUOTEMARK
) {
return CCTL;
}
@@ -5302,7 +5302,7 @@ ash_arith(const char *s)
#define EXP_WORD 0x80 /* expand word in parameter expansion */
#define EXP_QWORD 0x100 /* expand word in quoted parameter expansion */
/*
- * _rmescape() flags
+ * rmescape() flags
*/
#define RMESCAPE_ALLOC 0x1 /* Allocate a new string */
#define RMESCAPE_GLOB 0x2 /* Add backslashes for glob */
@@ -5356,7 +5356,7 @@ esclen(const char *start, const char *p)
{
size_t esc = 0;
- while (p > start && *--p == CTLESC) {
+ while (p > start && (unsigned char)*--p == CTLESC) {
esc++;
}
return esc;
@@ -5372,13 +5372,13 @@ rmescapes(char *str, int flag)
char *p, *q, *r;
unsigned inquotes;
- int notescaped;
- int globbing;
+ unsigned protect_against_glob;
+ unsigned globbing;
p = strpbrk(str, qchars);
- if (!p) {
+ if (!p)
return str;
- }
+
q = p;
r = str;
if (flag & RMESCAPE_ALLOC) {
@@ -5397,28 +5397,33 @@ rmescapes(char *str, int flag)
q = (char *)memcpy(q, str, len) + len;
}
}
+
inquotes = (flag & RMESCAPE_QUOTED) ^ RMESCAPE_QUOTED;
globbing = flag & RMESCAPE_GLOB;
- notescaped = globbing;
+ protect_against_glob = globbing;
while (*p) {
if (*p == CTLQUOTEMARK) {
+// TODO: if no RMESCAPE_QUOTED in flags, inquotes never becomes 0
+// (alternates between RMESCAPE_QUOTED and ~RMESCAPE_QUOTED). Is it ok?
+// Note: both inquotes and protect_against_glob only affect whether
+// CTLESC,<ch> gets converted to <ch> or to \<ch>
inquotes = ~inquotes;
p++;
- notescaped = globbing;
+ protect_against_glob = globbing;
continue;
}
if (*p == '\\') {
/* naked back slash */
- notescaped = 0;
+ protect_against_glob = 0;
goto copy;
}
if (*p == CTLESC) {
p++;
- if (notescaped && inquotes && *p != '/') {
+ if (protect_against_glob && inquotes && *p != '/') {
*q++ = '\\';
}
}
- notescaped = globbing;
+ protect_against_glob = globbing;
copy:
*q++ = *p++;
}
@@ -5541,13 +5546,13 @@ removerecordregions(int endoff)
}
static char *
-exptilde(char *startp, char *p, int flag)
+exptilde(char *startp, char *p, int flags)
{
char c;
char *name;
struct passwd *pw;
const char *home;
- int quotes = flag & (EXP_FULL | EXP_CASE);
+ int quotes = flags & (EXP_FULL | EXP_CASE);
int startloc;
name = p + 1;
@@ -5559,7 +5564,7 @@ exptilde(char *startp, char *p, int flag)
case CTLQUOTEMARK:
return startp;
case ':':
- if (flag & EXP_VARTILDE)
+ if (flags & EXP_VARTILDE)
goto done;
break;
case '/':
@@ -5774,7 +5779,7 @@ expari(int quotes)
#endif
/* argstr needs it */
-static char *evalvar(char *p, int flag, struct strlist *var_str_list);
+static char *evalvar(char *p, int flags, struct strlist *var_str_list);
/*
* Perform variable and command substitution. If EXP_FULL is set, output CTLESC
@@ -5786,7 +5791,7 @@ static char *evalvar(char *p, int flag, struct strlist *var_str_list);
* for correct expansion of "B=$A" word.
*/
static void
-argstr(char *p, int flag, struct strlist *var_str_list)
+argstr(char *p, int flags, struct strlist *var_str_list)
{
static const char spclchars[] ALIGN1 = {
'=',
@@ -5804,42 +5809,44 @@ argstr(char *p, int flag, struct strlist *var_str_list)
};
const char *reject = spclchars;
int c;
- int quotes = flag & (EXP_FULL | EXP_CASE | EXP_REDIR); /* do CTLESC */
- int breakall = flag & EXP_WORD;
+ int quotes = flags & (EXP_FULL | EXP_CASE | EXP_REDIR); /* do CTLESC */
+ int breakall = flags & EXP_WORD;
int inquotes;
size_t length;
int startloc;
- if (!(flag & EXP_VARTILDE)) {
+ if (!(flags & EXP_VARTILDE)) {
reject += 2;
- } else if (flag & EXP_VARTILDE2) {
+ } else if (flags & EXP_VARTILDE2) {
reject++;
}
inquotes = 0;
length = 0;
- if (flag & EXP_TILDE) {
+ if (flags & EXP_TILDE) {
char *q;
- flag &= ~EXP_TILDE;
+ flags &= ~EXP_TILDE;
tilde:
q = p;
- if (*q == CTLESC && (flag & EXP_QWORD))
+ if (*q == CTLESC && (flags & EXP_QWORD))
q++;
if (*q == '~')
- p = exptilde(p, q, flag);
+ p = exptilde(p, q, flags);
}
start:
startloc = expdest - (char *)stackblock();
for (;;) {
length += strcspn(p + length, reject);
- c = p[length];
- if (c && (!(c & 0x80)
+ c = (unsigned char) p[length];
+ if (c) {
+ if (!(c & 0x80)
#if ENABLE_SH_MATH_SUPPORT
- || c == CTLENDARI
+ || c == CTLENDARI
#endif
- )) {
- /* c == '=' || c == ':' || c == CTLENDARI */
- length++;
+ ) {
+ /* c == '=' || c == ':' || c == CTLENDARI */
+ length++;
+ }
}
if (length > 0) {
int newloc;
@@ -5857,11 +5864,11 @@ argstr(char *p, int flag, struct strlist *var_str_list)
case '\0':
goto breakloop;
case '=':
- if (flag & EXP_VARTILDE2) {
+ if (flags & EXP_VARTILDE2) {
p--;
continue;
}
- flag |= EXP_VARTILDE2;
+ flags |= EXP_VARTILDE2;
reject++;
/* fall through */
case ':':
@@ -5880,15 +5887,13 @@ argstr(char *p, int flag, struct strlist *var_str_list)
goto breakloop;
case CTLQUOTEMARK:
/* "$@" syntax adherence hack */
- if (
- !inquotes &&
- !memcmp(p, dolatstr, 4) &&
- (p[4] == CTLQUOTEMARK || (
- p[4] == CTLENDVAR &&
- p[5] == CTLQUOTEMARK
- ))
+ if (!inquotes
+ && memcmp(p, dolatstr, 4) == 0
+ && ( p[4] == CTLQUOTEMARK
+ || (p[4] == CTLENDVAR && p[5] == CTLQUOTEMARK)
+ )
) {
- p = evalvar(p + 1, flag, /* var_str_list: */ NULL) + 1;
+ p = evalvar(p + 1, flags, /* var_str_list: */ NULL) + 1;
goto start;
}
inquotes = !inquotes;
@@ -5904,10 +5909,10 @@ argstr(char *p, int flag, struct strlist *var_str_list)
length++;
goto addquote;
case CTLVAR:
- p = evalvar(p, flag, var_str_list);
+ p = evalvar(p, flags, var_str_list);
goto start;
case CTLBACKQ:
- c = 0;
+ c = '\0';
case CTLBACKQ|CTLQUOTE:
expbackq(argbackq->n, c, quotes);
argbackq = argbackq->next;
@@ -6452,7 +6457,7 @@ varvalue(char *name, int varflags, int flags, struct strlist *var_str_list)
* input string.
*/
static char *
-evalvar(char *p, int flag, struct strlist *var_str_list)
+evalvar(char *p, int flags, struct strlist *var_str_list)
{
char varflags;
char subtype;
@@ -6463,7 +6468,7 @@ evalvar(char *p, int flag, struct strlist *var_str_list)
int startloc;
ssize_t varlen;
- varflags = *p++;
+ varflags = (unsigned char) *p++;
subtype = varflags & VSTYPE;
quoted = varflags & VSQUOTE;
var = p;
@@ -6472,7 +6477,7 @@ evalvar(char *p, int flag, struct strlist *var_str_list)
p = strchr(p, '=') + 1;
again:
- varlen = varvalue(var, varflags, flag, var_str_list);
+ varlen = varvalue(var, varflags, flags, var_str_list);
if (varflags & VSNUL)
varlen--;
@@ -6485,8 +6490,8 @@ evalvar(char *p, int flag, struct strlist *var_str_list)
vsplus:
if (varlen < 0) {
argstr(
- p, flag | EXP_TILDE |
- (quoted ? EXP_QWORD : EXP_WORD),
+ p, flags | EXP_TILDE |
+ (quoted ? EXP_QWORD : EXP_WORD),
var_str_list
);
goto end;
@@ -6558,7 +6563,7 @@ evalvar(char *p, int flag, struct strlist *var_str_list)
patloc = expdest - (char *)stackblock();
if (0 == subevalvar(p, /* str: */ NULL, patloc, subtype,
startloc, varflags,
- /* quotes: */ flag & (EXP_FULL | EXP_CASE),
+ /* quotes: */ flags & (EXP_FULL | EXP_CASE),
var_str_list)
) {
int amount = expdest - (