Skip to content

Commit 2e000c9

Browse files
committed
lex.c: sh_lexopen(): future-proof full reset (re: 0dc0e1a)
When fully resetting the lexer state (mode==0), zero out the complete lexer struct, except for $LINENO-related members. This might prevent future bugs.
1 parent 2010caa commit 2e000c9

2 files changed

Lines changed: 13 additions & 8 deletions

File tree

src/cmd/ksh93/include/version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
#define SH_RELEASE_FORK "93u+m" /* only change if you develop a new ksh93 fork */
2020
#define SH_RELEASE_SVER "1.1.0-alpha" /* semantic version number: https://semver.org */
21-
#define SH_RELEASE_DATE "2024-11-02" /* must be in this format for $((.sh.version)) */
21+
#define SH_RELEASE_DATE "2024-11-03" /* must be in this format for $((.sh.version)) */
2222
#define SH_RELEASE_CPYR "(c) 2020-2024 Contributors to ksh " SH_RELEASE_FORK
2323

2424
/* Scripts sometimes field-split ${.sh.version}, so don't change amount of whitespace. */

src/cmd/ksh93/sh/lex.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -202,13 +202,18 @@ static int lexfill(Lex_t *lp)
202202
Lex_t *sh_lexopen(Lex_t *lp, int mode)
203203
{
204204
if(!lp)
205-
lp = (Lex_t*)sh_newof(0,Lex_t,1,0);
206-
fcnotify(lex_advance,lp);
207-
lp->lex.intest = lp->lex.incase = lp->lex.skipword = lp->comp_assign = lp->comsub = lp->assignok = 0;
205+
lp = sh_newof(0,Lex_t,1,0);
206+
else if(mode)
207+
lp->lex.intest = lp->lex.incase = lp->lex.skipword = lp->comp_assign = lp->comsub = lp->assignok = 0;
208+
else
209+
{ /* full reset: everything except LINENO */
210+
int lastline = lp->lastline, inlineno = lp->inlineno, firstline = lp->firstline;
211+
memset(lp,0,sizeof(Lex_t));
212+
lp->lastline = lastline, lp->inlineno = inlineno, lp->firstline = firstline;
213+
}
208214
lp->lex.reservok = 1;
209-
if(!mode)
210-
memset(&lp->lexd,0,sizeof(struct _shlex_pvt_lexdata_));
211215
lp->lexd.warn = !sh_isoption(SH_DICTIONARY) && sh_isoption(SH_NOEXEC);
216+
fcnotify(lex_advance,lp);
212217
return lp;
213218
}
214219

@@ -2112,8 +2117,6 @@ noreturn void sh_syntax(Lex_t *lp, int special)
21122117
fcclose();
21132118
sh.inlineno = lp->inlineno;
21142119
sh.st.firstline = lp->firstline;
2115-
/* reset lexer state */
2116-
sh_lexopen(lp, 0);
21172120
/* construct error message */
21182121
if (sh_isstate(SH_INTERACTIVE) || sh_isstate(SH_PROFILE))
21192122
sfprintf(sh.strbuf, sh_translate(e_syntaxerror));
@@ -2129,6 +2132,8 @@ noreturn void sh_syntax(Lex_t *lp, int special)
21292132
sfprintf(sh.strbuf, sh_translate(e_unmatched), fmttoken(lp, lp->lasttok));
21302133
else
21312134
sfprintf(sh.strbuf, sh_translate(e_unexpected), fmttoken(lp, lp->token));
2135+
/* reset lexer state */
2136+
sh_lexopen(lp, 0);
21322137
errormsg(SH_DICT, ERROR_exit(SYNBAD), "%s", sfstruse(sh.strbuf));
21332138
UNREACHABLE();
21342139
}

0 commit comments

Comments
 (0)