From 0141794c2eae3434199aee545679b2eb8ace91d0 Mon Sep 17 00:00:00 2001 From: tg Date: Thu, 14 Jan 2016 22:30:43 +0000 Subject: [PATCH] correctly handle nested ADELIM parsing: ADELIM doubles as CSUBST (LP#1453827) --- eval.c | 13 ++++--------- tree.c | 21 +++++++++++++++++---- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/eval.c b/eval.c index 44d4c55..ba89e79 100644 --- a/eval.c +++ b/eval.c @@ -2,7 +2,7 @@ /*- * Copyright (c) 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 @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.178 2015/12/12 22:24:07 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.179 2016/01/14 22:30:43 tg Exp $"); /* * string expansion @@ -437,8 +437,6 @@ expand( beg = wdcopy(sp, ATEMP); mid = beg + (wdscan(sp, ADELIM) - sp); stg = beg + (wdscan(sp, CSUBST) - sp); - if (mid >= stg) - goto unwind_substsyn; mid[-2] = EOS; if (mid[-1] == /*{*/'}') { sp += mid - beg - 1; @@ -446,9 +444,8 @@ expand( } else { end = mid + (wdscan(mid, ADELIM) - mid); - if (end >= stg || - /* more than max delimiters */ - end[-1] != /*{*/ '}') + if (end[-1] != /*{*/ '}') + /* more than max delimiters */ goto unwind_substsyn; end[-2] = EOS; sp += end - beg - 1; @@ -488,8 +485,6 @@ expand( s = wdcopy(sp, ATEMP); p = s + (wdscan(sp, ADELIM) - sp); d = s + (wdscan(sp, CSUBST) - sp); - if (p >= d) - goto unwind_substsyn; p[-2] = EOS; if (p[-1] == /*{*/'}') d = NULL; diff --git a/tree.c b/tree.c index edc3d02..7a7df5d 100644 --- a/tree.c +++ b/tree.c @@ -2,7 +2,7 @@ /*- * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, - * 2011, 2012, 2013, 2015 + * 2011, 2012, 2013, 2015, 2016 * mirabilos * * Provided that these terms and disclaimer and all copyright notices @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.79 2015/12/12 19:08:58 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.80 2016/01/14 22:30:43 tg Exp $"); #define INDENT 8 @@ -318,6 +318,10 @@ wdvarput(struct shf *shf, const char *wp, int quotelevel, int opmode) case EOS: return (--wp); case ADELIM: + if (*wp == /*{*/'}') { + ++wp; + goto wdvarput_csubst; + } case CHAR: c = *wp++; shf_putc(c, shf); @@ -383,8 +387,10 @@ wdvarput(struct shf *shf, const char *wp, int quotelevel, int opmode) wp = wdvarput(shf, wp, 0, opmode); break; case CSUBST: - if (*wp++ == '}') + if (*wp++ == '}') { + wdvarput_csubst: shf_putc('}', shf); + } return (wp); case OPAT: shf_putchar(*wp++, shf); @@ -581,8 +587,10 @@ wdscan(const char *wp, int c) case EOS: return (wp); case ADELIM: - if (c == ADELIM) + if (c == ADELIM && nest == 0) return (wp + 1); + if (*wp == /*{*/'}') + goto wdscan_csubst; /* FALLTHROUGH */ case CHAR: case QCHAR: @@ -604,6 +612,7 @@ wdscan(const char *wp, int c) ; break; case CSUBST: + wdscan_csubst: wp++; if (c == CSUBST && nest == 0) return (wp); @@ -807,6 +816,10 @@ dumpwdvar_i(struct shf *shf, const char *wp, int quotelevel) shf_puts("EOS", shf); return (--wp); case ADELIM: + if (*wp == /*{*/'}') { + shf_puts("]ADELIM(})", shf); + return (wp + 1); + } shf_puts("ADELIM=", shf); if (0) case CHAR: