formula backslash escaping

This commit is contained in:
Yuri Kuznetsov
2024-04-24 13:22:22 +03:00
parent eba3138d16
commit ddf904fa0f
3 changed files with 106 additions and 12 deletions
@@ -30,7 +30,6 @@
namespace Espo\Core\Formula\Functions;
use Espo\Core\Formula\Exceptions\Error;
use Espo\Core\Formula\ArgumentList;
class ValueType extends BaseFunction
@@ -41,12 +40,6 @@ class ValueType extends BaseFunction
throw new Error("Bad value.");
}
$value = $args[0]->getData();
if (is_string($value)) {
$value = str_replace("\\n", "\n", $value);
}
return $value;
return $args[0]->getData();
}
}
+55 -4
View File
@@ -1002,10 +1002,7 @@ class Parser
$expression[0] === "'" && $expression[strlen($expression) - 1] === "'" ||
$expression[0] === "\"" && $expression[strlen($expression) - 1] === "\""
) {
$subExpression = substr($expression, 1, strlen($expression) - 2);
$subExpression = str_replace(["\\\\", "\\\""], ["\\", "\""], $subExpression);
return new Value($subExpression);
return new Value(self::stripStringSlashes($expression));
}
if ($expression[0] === "$") {
@@ -1290,4 +1287,58 @@ class Parser
return $argumentList;
}
static private function stripStringSlashes(string $expression): string
{
$string = substr($expression, 1, strlen($expression) - 2);
/** @var array{bool, string}[] $tokens */
$tokens = [];
$stripList = ["\\\\", "\\\"", "\\n", "\\t", "\\r"];
$replaceList = ["\\", "\"", "\n", "\t", "\r"];
$k = 0;
for ($i = 0; $i < strlen($string); $i++) {
$part = substr($string, $i, 2);
if (in_array($part, $stripList)) {
$len = strlen($part);
$before = substr($string, $k, $i - $k);
if (strlen($before)) {
$tokens[] = [false, $before];
}
$tokens[] = [true, $part];
$i += $len - 1;
$k = $i + 1;
}
if ($i >= strlen($string) - 1) {
$after = substr($string, $k);
if (strlen($after)) {
$tokens[] = [false, $after];
}
}
}
$result = '';
foreach ($tokens as $token) {
if (!$token[0]) {
$result .= $token[1];
continue;
}
$result .= str_replace($stripList, $replaceList, $token[1]);
}
return $result;
}
}
@@ -1449,4 +1449,54 @@ class EvaluatorTest extends \PHPUnit\Framework\TestCase
$this->assertEquals("\"", $result);
}
public function testStrings3(): void
{
$expression = '"\\n"';
/** @noinspection PhpUnhandledExceptionInspection */
$result = $this->evaluator->process($expression);
$this->assertEquals("\n", $result);
}
public function testStrings4(): void
{
$expression = '"\\\\n"';
/** @noinspection PhpUnhandledExceptionInspection */
$result = $this->evaluator->process($expression);
$this->assertEquals("\\n", $result);
}
public function testStrings5(): void
{
$expression = '"test\\\\nest\\\\nest"';
/** @noinspection PhpUnhandledExceptionInspection */
$result = $this->evaluator->process($expression);
$this->assertEquals("test\\nest\\nest", $result);
}
public function testStrings6(): void
{
$expression = '"\\n\\\\test"';
/** @noinspection PhpUnhandledExceptionInspection */
$result = $this->evaluator->process($expression);
$this->assertEquals("\n\\test", $result);
}
public function testStrings7(): void
{
$expression = '"\\n\\\\test\\n"';
/** @noinspection PhpUnhandledExceptionInspection */
$result = $this->evaluator->process($expression);
$this->assertEquals("\n\\test\n", $result);
}
}