formula backslash escaping
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user