Browse Source

Shell: Disallow non-bareword nodes as part of a heredoc key

Found by oss-fuzz:
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=33854
Ali Mohammad Pur 4 years ago
parent
commit
f1d49d391e
1 changed files with 12 additions and 4 deletions
  1. 12 4
      Userland/Shell/Parser.cpp

+ 12 - 4
Userland/Shell/Parser.cpp

@@ -1943,10 +1943,14 @@ RefPtr<AST::Node> Parser::parse_heredoc_initiation_record()
 
 
     // StringLiteral | bareword
     // StringLiteral | bareword
     if (auto bareword = parse_bareword()) {
     if (auto bareword = parse_bareword()) {
-        if (bareword->is_syntax_error())
-            syntax_error_node = bareword->syntax_error_node();
-        else
-            record.end = static_cast<AST::BarewordLiteral*>(bareword.ptr())->text();
+        if (!bareword->is_bareword()) {
+            syntax_error_node = create<AST::SyntaxError>(String::formatted("Expected a bareword or a quoted string, not {}", bareword->class_name()));
+        } else {
+            if (bareword->is_syntax_error())
+                syntax_error_node = bareword->syntax_error_node();
+            else
+                record.end = static_cast<AST::BarewordLiteral*>(bareword.ptr())->text();
+        }
 
 
         record.interpolate = true;
         record.interpolate = true;
     } else if (peek() == '\'') {
     } else if (peek() == '\'') {
@@ -1981,6 +1985,10 @@ bool Parser::parse_heredoc_entries()
     // Try to parse heredoc entries, as reverse recorded in the initiation records
     // Try to parse heredoc entries, as reverse recorded in the initiation records
     for (auto& record : m_heredoc_initiations) {
     for (auto& record : m_heredoc_initiations) {
         auto rule_start = push_start();
         auto rule_start = push_start();
+        if (m_rule_start_offsets.size() > max_allowed_nested_rule_depth) {
+            record.node->set_is_syntax_error(*create<AST::SyntaxError>(String::formatted("Expression nested too deep (max allowed is {})", max_allowed_nested_rule_depth)));
+            continue;
+        }
         bool found_key = false;
         bool found_key = false;
         if (!record.interpolate) {
         if (!record.interpolate) {
             // Since no interpolation is allowed, just read lines until we hit the key
             // Since no interpolation is allowed, just read lines until we hit the key