From ad70c6dbd0fd621d3650d486eb8a6c3e9edecb82 Mon Sep 17 00:00:00 2001 From: Pekka Laiho Date: Tue, 16 Jun 2020 20:15:57 +0700 Subject: [PATCH] handle special characters in strings --- README.md | 4 ---- src/Reader.php | 9 +++++++-- src/Tokenizer.php | 7 +++++-- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 24447ed..0fb0c54 100644 --- a/README.md +++ b/README.md @@ -275,10 +275,6 @@ odd? | Return true if the argument is odd number (1, 3, 5, ...). The project is easy to extend because it is trivial to add new functions whether the implementation is defined on the PHP or Lisp side. If the language ends up being used in the future, first plans are to add support for JSON serialization and a HTTP client. -## Known issues - -Special characters such as `\"`, `\n` or `\r` are not handled/escaped correctly in strings yet. - ## License [MIT](https://choosealicense.com/licenses/mit/) diff --git a/src/Reader.php b/src/Reader.php index 663359a..feaca86 100644 --- a/src/Reader.php +++ b/src/Reader.php @@ -77,8 +77,13 @@ class Reader } elseif ($a === 'null') { return null; } elseif (substr($a, 0, 1) === '"') { - // string - return substr($a, 1, strlen($a) - 2); + // string, handle special characters + $a = substr($a, 1, -1); + $a = str_replace("\\\\", chr(0x7f), $a); + $a = str_replace("\\n", "\n", $a); + $a = str_replace("\\r", "\r", $a); + $a = str_replace("\\\"", "\"", $a); + return str_replace(chr(0x7f), "\\", $a); } elseif (is_numeric($a)) { if (filter_var($a, FILTER_VALIDATE_INT) !== false) { return intval($a); diff --git a/src/Tokenizer.php b/src/Tokenizer.php index b4dfe3d..5afaa2b 100644 --- a/src/Tokenizer.php +++ b/src/Tokenizer.php @@ -30,8 +30,11 @@ class Tokenizer // Stop at first double quote if ($c == '"') { - $addCurrent(); - $isString = false; + // If previous character is not a backslash + if (strlen($current) < 2 || substr($current, -2, 1) != "\\") { + $addCurrent(); + $isString = false; + } } } elseif ($isComment) { // Comments stop at first newline