tdenniston / bish

Bish is a language that compiles to Bash. It's designed to give shell scripting a more comfortable and modern feel.
MIT License
1.48k stars 36 forks source link

Backticks leak into arbitrary command execution #74

Open Artoria2e5 opened 5 years ago

Artoria2e5 commented 5 years ago

Try:

println("`a` b c")

You will get a commnad-not-found for a, because it actually tried to run it.


I tried to work this around by implementing the magical POSIX quote:

void CodeGen_Bash::output_escaped_string(const std::string &s) {
    stream << "'";
    std::ptrdiff_t current, previous = 0;
    current = s.find("'");
    while (current != std::string::npos) {
        stream << s.substr(previous, current - previous) << "'\''";
        previous = current + 1;
        current = s.find("'", previous);
    }
    stream << s.substr(previous, current - previous);
    stream << "'";
}

...combined with disabling the \ keeping behavior in Parser for quoted strings to handle cases like \$ -> literal $, and not enabling the escape for the ExternCall code path. The problem is it also kills legit backslashes like \n.

I tried changing the backslash handling for the lexer as well, but it is too late in midnight for my brain to come up with a sensible solution. Basically I want the new scan_until to:

  1. discard all backslashes that do escape some token
  2. have backslashes self-escape; that is n backslashes turn into n/2 in the actual string
  3. have the boolean parameter decide how to handle the lone odd slash

1 requires rewriting the lookahead part to resemble something like:

find token match
if found_preliminary
  if escape
    emit n / 2 [result += std::string(backslashes / 2, '\\');]
    n %= 2
  else
    break away from while

But I am just too tired to try it.

adamasantares commented 3 years ago

@Artoria2e5 hey how are you? Could you check it? https://github.com/tdenniston/bish/issues/78