Skip to content

Commit

Permalink
fix IFS='\' issues, found by edualbus (Eduardo A. Bustamante López <d…
Browse files Browse the repository at this point in the history
…ualbus@gmail.com>)
  • Loading branch information
mirabilos committed Apr 11, 2015
1 parent 4ee3269 commit 3c5c5d0
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 9 deletions.
62 changes: 61 additions & 1 deletion check.t
@@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/check.t,v 1.687 2015/03/20 23:37:52 tg Exp $
# $MirOS: src/bin/mksh/check.t,v 1.688 2015/04/11 21:18:45 tg Exp $
# -*- mode: sh -*-
#-
# Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
Expand Down Expand Up @@ -4842,6 +4842,66 @@ expected-stdout:
1a:
2: x[A B]
---
name: read-IFS-2
description:
Complex tests, IFS either colon (IFS-NWS) or backslash (tricky)
stdin:
n=0
showargs() { print -nr "$1"; shift; for s_arg in "$@"; do print -nr -- " [$s_arg]"; done; print; }
(IFS=\\ a=\<\\\>; showargs 3 $a)
(IFS=: b=\<:\>; showargs 4 $b)
print -r '<\>' | (IFS=\\ read f g; showargs 5 "$f" "$g")
print -r '<\\>' | (IFS=\\ read f g; showargs 6 "$f" "$g")
print '<\\\n>' | (IFS=\\ read f g; showargs 7 "$f" "$g")
print -r '<\>' | (IFS=\\ read f; showargs 8 "$f")
print -r '<\\>' | (IFS=\\ read f; showargs 9 "$f")
print '<\\\n>' | (IFS=\\ read f; showargs 10 "$f")
print -r '<\>' | (IFS=\\ read -r f g; showargs 11 "$f" "$g")
print -r '<\\>' | (IFS=\\ read -r f g; showargs 12 "$f" "$g")
print '<\\\n>' | (IFS=\\ read -r f g; showargs 13 "$f" "$g")
print -r '<\>' | (IFS=\\ read -r f; showargs 14 "$f")
print -r '<\\>' | (IFS=\\ read -r f; showargs 15 "$f")
print '<\\\n>' | (IFS=\\ read -r f; showargs 16 "$f")
print -r '<:>' | (IFS=: read f g; showargs 17 "$f" "$g")
print -r '<::>' | (IFS=: read f g; showargs 18 "$f" "$g")
print '<:\n>' | (IFS=: read f g; showargs 19 "$f" "$g")
print -r '<:>' | (IFS=: read f; showargs 20 "$f")
print -r '<::>' | (IFS=: read f; showargs 21 "$f")
print '<:\n>' | (IFS=: read f; showargs 22 "$f")
print -r '<:>' | (IFS=: read -r f g; showargs 23 "$f" "$g")
print -r '<::>' | (IFS=: read -r f g; showargs 24 "$f" "$g")
print '<:\n>' | (IFS=: read -r f g; showargs 25 "$f" "$g")
print -r '<:>' | (IFS=: read -r f; showargs 26 "$f")
print -r '<::>' | (IFS=: read -r f; showargs 27 "$f")
print '<:\n>' | (IFS=: read -r f; showargs 28 "$f")
expected-stdout:
3 [<] [>]
4 [<] [>]
5 [<] [>]
6 [<] [>]
7 [<>] []
8 [<>]
9 [<\>]
10 [<>]
11 [<] [>]
12 [<] [\>]
13 [<] []
14 [<\>]
15 [<\\>]
16 [<]
17 [<] [>]
18 [<] [:>]
19 [<] []
20 [<:>]
21 [<::>]
22 [<]
23 [<] [>]
24 [<] [:>]
25 [<] []
26 [<:>]
27 [<::>]
28 [<]
---
name: read-ksh-1
description:
If no var specified, REPLY is used
Expand Down
24 changes: 16 additions & 8 deletions funcs.c
Expand Up @@ -38,7 +38,7 @@
#endif
#endif

__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.266 2015/03/20 21:01:41 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.267 2015/04/11 21:18:47 tg Exp $");

#if HAVE_KILLPG
/*
Expand Down Expand Up @@ -1821,9 +1821,10 @@ int
c_read(const char **wp)
{
#define is_ifsws(c) (ctype((c), C_IFS) && ctype((c), C_IFSWS))
int c, fd = 0, rv = 0, lastparm = 0;
int c, fd = 0, rv = 0;
bool savehist = false, intoarray = false, aschars = false;
bool rawmode = false, expanding = false;
bool lastparmmode = false, lastparmused = false;
enum { LINES, BYTES, UPTO, READALL } readmode = LINES;
char delim = '\n';
size_t bytesleft = 128, bytesread;
Expand Down Expand Up @@ -2127,7 +2128,7 @@ c_read(const char **wp)
}

if (!intoarray && wp[1] == NULL)
lastparm = 1;
lastparmmode = true;

c_read_splitlast:
/* copy until IFS character */
Expand All @@ -2152,16 +2153,23 @@ c_read(const char **wp)
}
xsave = Xsavepos(xs, xp);
/* copy word delimiter: IFSWS+IFS,IFSWS */
expanding = false;
while (bytesread) {
char ch;

ch = *ccp;
if (!ctype(ch, C_IFS))
break;
Xcheck(xs, xp);
Xput(xs, xp, ch);
if (lastparmmode && !expanding && !rawmode && ch == '\\') {
expanding = true;
} else {
Xcheck(xs, xp);
Xput(xs, xp, ch);
}
++ccp;
--bytesread;
if (expanding)
continue;
if (!ctype(ch, C_IFSWS))
break;
}
Expand All @@ -2172,12 +2180,12 @@ c_read(const char **wp)
--bytesread;
}
/* if no more parameters, rinse and repeat */
if (lastparm && bytesread) {
++lastparm;
if (lastparmmode && bytesread) {
lastparmused = true;
goto c_read_splitlast;
}
/* get rid of the delimiter unless we pack the rest */
if (lastparm < 2)
if (!lastparmused)
xp = Xrestpos(xs, xp, xsave);
c_read_gotword:
Xput(xs, xp, '\0');
Expand Down

0 comments on commit 3c5c5d0

Please sign in to comment.