-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix parsing of double parentheses in compound assignments
Problem 1: $ ksh -c 'typeset -Ca arr=((a=ah b=beh c=si))' ksh: syntax error at line 1: `((' unexpected $ ksh -c 'got=$(typeset -Ca arr=((a=ah b=beh c=si)))' ksh: syntax error at line 1: `((' unexpected Problem 2: $ ksh -c 'typeset -a arr=((a b c) 1)' (no output; OK) $ ksh -c 'got=$(typeset -a arr=((a b c) 1)' ksh: syntax error at line 1: `(' unmatched (sh_lex() and comsub() go into a mutual recursion loop here, eventually breaking it because lexd.dolparen wraps around) Root cause for problem 1: sh_lex() fails to take compound assignments into account so that it throws a syntax error on finding ((...)), misinterpreting it as EXPRSYM, which is used for arithmetic commands and expansions. Root cause for problem 2: same as problem 1, plus: at parse time, command substitutions and arithmetic expansions are read without parsing, using lexical analysis only. This is okay for arithmetic expansions, but not for command substitutions: the lexer really needs to know when we're entering a compound assignment. The parser flags this up via comp_assign, but not if we're not using it. We can cleanly fix problem 1 because the parser (parse.c) sets the comp_assign flag to tell the lexer when we're processing a compound assignment. But problem 2 is much harder. The fundamental issue is that the shell language's basic design is so messy that a clean separation between lexical analysis and parsing is not possible; the parser must influence the lexer for both to function properly. But command substitutions currently avoid the parser at parse time, so this bug can only be masked with a workaround. Correctness will not be possible until we completely redesign the way in which the lexer and parser handle command substitutions. src/cmd/ksh93/sh/lex.c: - comsub(): * This misleadingly named function is also used for reading arithmetic expansions. Set a new lexd.dolparen_arithexp flag when it is doing so (save/restore it to make recursion work). * Add a workaround that tries to detect compound assignments without parsing: whenever we encounter =( ... ), assume it is one. This is not correct, but will hopefully do for now... . Upon finding LPAREN=='(', check if it is preceded by '=' and set a new dolparen_eqparen flag to the current level of parentheses if so. . Upon finding LPAREN==')', reset that flag if we're moving below that level. - sh_lex(): * When detecting a double opening parenthesis, avoid misdetecting EXPRSYM (the symbol used for arithmetic commands and expansions) by returning early if the parser has set comp_assign. * For the case when we're lexing from comsub() and the parser is not in use, use the dolparen_eqparen flag instead. For the outer instance of =( ... ) that flag will not be set yet, so to deal correctly with nested compound assignments and ((...)) within compound assignments, we must check both for that flag and direclty for a preceding '='. * Minor refactoring of << (IODOCSYM) detection for legibility. Thanks to @hyenias for the bug report and for all the testing, and to @atheik for help in putting us on the trail to a fix. Resolves: #269
- Loading branch information
Showing
6 changed files
with
91 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters