Bladeren bron

Shell: Allow empty tokens if enclosed in single or double quotes

Previously the shell parser would discard empty tokens. We now allow
them when they are enclosed in quotes (either '' or "")

This means that a command like _echo ""_ will actually pass an empty
string to /bin/echo in argv[1] now.
Andreas Kling 5 jaren geleden
bovenliggende
commit
ed90d39cd7
2 gewijzigde bestanden met toevoegingen van 6 en 5 verwijderingen
  1. 4 4
      Shell/Parser.cpp
  2. 2 1
      Shell/Parser.h

+ 4 - 4
Shell/Parser.cpp

@@ -29,9 +29,9 @@
 #include <unistd.h>
 #include <unistd.h>
 #include <ctype.h>
 #include <ctype.h>
 
 
-void Parser::commit_token()
+void Parser::commit_token(AllowEmptyToken allow_empty)
 {
 {
-    if (m_token.is_empty())
+    if (allow_empty == AllowEmptyToken::No && m_token.is_empty())
         return;
         return;
     if (m_state == InRedirectionPath) {
     if (m_state == InRedirectionPath) {
         m_redirections.last().path = String::copy(m_token);
         m_redirections.last().path = String::copy(m_token);
@@ -239,7 +239,7 @@ Vector<Command> Parser::parse()
             break;
             break;
         case State::InSingleQuotes:
         case State::InSingleQuotes:
             if (ch == '\'') {
             if (ch == '\'') {
-                commit_token();
+                commit_token(AllowEmptyToken::Yes);
                 m_state = State::Free;
                 m_state = State::Free;
                 break;
                 break;
             }
             }
@@ -247,7 +247,7 @@ Vector<Command> Parser::parse()
             break;
             break;
         case State::InDoubleQuotes:
         case State::InDoubleQuotes:
             if (ch == '\"') {
             if (ch == '\"') {
-                commit_token();
+                commit_token(AllowEmptyToken::Yes);
                 m_state = State::Free;
                 m_state = State::Free;
                 break;
                 break;
             }
             }

+ 2 - 1
Shell/Parser.h

@@ -67,7 +67,8 @@ public:
     Vector<Command> parse();
     Vector<Command> parse();
 
 
 private:
 private:
-    void commit_token();
+    enum class AllowEmptyToken { No, Yes };
+    void commit_token(AllowEmptyToken = AllowEmptyToken::No);
     void commit_subcommand();
     void commit_subcommand();
     void commit_command();
     void commit_command();
     void do_pipe();
     void do_pipe();