Skip to content

Commit

Permalink
cs, crystal, es6: Detect more unterminated strings.
Browse files Browse the repository at this point in the history
Specifically, correctly handle invalid strings that nonetheless end with
a '"' character, by using the full string-matching regexp to check that
a string token is valid.
  • Loading branch information
bjh21 committed May 15, 2019
1 parent 4ad84d2 commit 320807c
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 12 deletions.
4 changes: 2 additions & 2 deletions crystal/reader.cr
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,11 @@ class Reader
when token == "true" then true
when token == "false" then false
when token == "nil" then nil
when token[0] == '"'
parse_error "expected '\"', got EOF" if token[-1] != '"'
when token =~ /^"(?:\\.|[^\\"])*"$/
token[1..-2].gsub(/\\(.)/, {"\\\"" => "\"",
"\\n" => "\n",
"\\\\" => "\\"})
when token[0] == '"' then parse_error "expected '\"', got EOF"
when token[0] == ':' then "\u029e#{token[1..-1]}"
else Mal::Symbol.new token
end
Expand Down
11 changes: 5 additions & 6 deletions cs/reader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public static List<string> tokenize(string str) {

public static MalVal read_atom(Reader rdr) {
string token = rdr.next();
string pattern = @"(^-?[0-9]+$)|(^-?[0-9][0-9.]*$)|(^nil$)|(^true$)|(^false$)|^("".*)|:(.*)|(^[^""]*$)";
string pattern = @"(^-?[0-9]+$)|(^-?[0-9][0-9.]*$)|(^nil$)|(^true$)|(^false$)|(^""(?:[\\].|[^\\""])*""$)|(^"".*$)|:(.*)|(^[^""]*$)";
Regex regex = new Regex(pattern);
Match match = regex.Match(token);
//Console.WriteLine("token: ^" + token + "$");
Expand All @@ -70,19 +70,18 @@ public static MalVal read_atom(Reader rdr) {
return Mal.types.False;
} else if (match.Groups[6].Value != String.Empty) {
string str = match.Groups[6].Value;
if (str[str.Length-1] != '"') {
throw new ParseError("expected '\"', got EOF");
}
str = str.Substring(1, str.Length-2)
.Replace("\\\\", "\u029e")
.Replace("\\\"", "\"")
.Replace("\\n", "\n")
.Replace("\u029e", "\\");
return new Mal.types.MalString(str);
} else if (match.Groups[7].Value != String.Empty) {
return new Mal.types.MalString("\u029e" + match.Groups[7].Value);
throw new ParseError("expected '\"', got EOF");
} else if (match.Groups[8].Value != String.Empty) {
return new Mal.types.MalSymbol(match.Groups[8].Value);
return new Mal.types.MalString("\u029e" + match.Groups[8].Value);
} else if (match.Groups[9].Value != String.Empty) {
return new Mal.types.MalSymbol(match.Groups[9].Value);
} else {
throw new ParseError("unrecognized '" + match.Groups[0] + "'");
}
Expand Down
7 changes: 3 additions & 4 deletions es6/reader.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,11 @@ function read_atom (reader) {
return parseInt(token,10) // integer
} else if (token.match(/^-?[0-9][0-9.]*$/)) {
return parseFloat(token,10) // float
} else if (token[0] === "\"") {
if (token.slice(-1) !== "\"") {
throw new Error("expected '\"', got EOF");
}
} else if (token.match(/^"(?:\\.|[^\\"])*"$/)) {
return token.slice(1,token.length-1)
.replace(/\\(.)/g, (_, c) => c === "n" ? "\n" : c)
} else if (token[0] === "\"") {
throw new Error("expected '\"', got EOF");
} else if (token[0] === ":") {
return _keyword(token.slice(1))
} else if (token === "nil") {
Expand Down

0 comments on commit 320807c

Please sign in to comment.