Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: camunda/feel-scala
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 1.17.8
Choose a base ref
...
head repository: camunda/feel-scala
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 1.17.9
Choose a head ref
  • 8 commits
  • 3 files changed
  • 2 contributors

Commits on Sep 4, 2024

  1. [maven-release-plugin] prepare for next development iteration

    github-actions[release]@users.noreply.github.com committed Sep 4, 2024
    Copy the full SHA
    bfabc22 View commit details
  2. Merge pull request #920 from camunda/release-1.17.8

    [Release] 1.17.8
    saig0 authored Sep 4, 2024
    Copy the full SHA
    2f35172 View commit details

Commits on Sep 25, 2024

  1. refactor: Use parameterized test case

    (cherry picked from commit c8b01bd)
    saig0 authored and github-actions[bot] committed Sep 25, 2024
    Copy the full SHA
    d390f40 View commit details
  2. refactor: Combine test cases

    (cherry picked from commit 58efca9)
    saig0 authored and github-actions[bot] committed Sep 25, 2024
    Copy the full SHA
    70acc1a View commit details
  3. test: Verify string literal with regex characters

    (cherry picked from commit 544c038)
    saig0 authored and github-actions[bot] committed Sep 25, 2024
    Copy the full SHA
    66979c1 View commit details
  4. fix: Handle escape sequences

    Correct the handling of escape sequences in string literals.
    
    Don't replace escape sequences in regex expressions, for example, \r or \n. In the parser, these sequences start with \\. Same for \s, don't replace it with a whitespace, since this is also a part of a regex.
    
    Handle \\ to avoid that the sequence is escaped and returned as \\\\.
    
    (cherry picked from commit d266e80)
    saig0 authored and github-actions[bot] committed Sep 25, 2024
    Copy the full SHA
    c7d2f1e View commit details
  5. Merge pull request #932 from camunda/backport-930-to-1.17

    [Backport 1.17] fix: Handle escape and regex characters
    saig0 authored Sep 25, 2024
    Copy the full SHA
    2a4ea4c View commit details

Commits on Sep 26, 2024

  1. [maven-release-plugin] prepare release 1.17.9

    github-actions[release]@users.noreply.github.com committed Sep 26, 2024
    Copy the full SHA
    c4315e3 View commit details
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@

<groupId>org.camunda.feel</groupId>
<artifactId>feel-engine</artifactId>
<version>1.17.8</version>
<version>1.17.9</version>
<name>FEEL Scala Engine</name>

<properties>
@@ -508,7 +508,7 @@
<scm>
<connection>scm:git:https://${env.GITHUB_TOKEN_USR}:${env.GITHUB_TOKEN_PSW}@github.com/camunda/feel-scala.git</connection>
<developerConnection>scm:git:https://${env.GITHUB_TOKEN_USR}:${env.GITHUB_TOKEN_PSW}@github.com/camunda/feel-scala.git</developerConnection>
<tag>1.17.8</tag>
<tag>1.17.9</tag>
<url>https://github.com/camunda/feel-scala</url>
</scm>

26 changes: 10 additions & 16 deletions src/main/scala/org/camunda/feel/impl/parser/FeelParser.scala
Original file line number Diff line number Diff line change
@@ -694,22 +694,16 @@ object FeelParser {
}.getOrElse(ConstNull)
}

// replace escaped character with the provided replacement
private def translateEscapes(input: String): String = {
val escapeMap = Map(
"\\b" -> "\b",
"\\t" -> "\t",
"\\n" -> "\n",
"\\f" -> "\f",
"\\r" -> "\r",
"\\\"" -> "\"",
"\\'" -> "'",
"\\s" -> " "
// Add more escape sequences as needed
)

escapeMap.foldLeft(input) { case (result, (escape, replacement)) =>
result.replace(escape, replacement)
}
// replace all escape sequences
input
.replaceAll("(?<!\\\\)\\\\n", "\n") // new line
.replaceAll("(?<!\\\\)\\\\r", "\r") // carriage return
.replaceAll("(?<!\\\\)\\\\t", "\t") // tab
.replaceAll("(?<!\\\\)\\\\b", "\b") // backspace
.replaceAll("(?<!\\\\)\\\\f", "\f") // form feed
.replaceAll("(?<!\\\\)\\\\'", "'") // single quote
.replaceAll("(?<!\\\\)\\\\\"", "\"") // double quote
.replaceAll("\\\\\\\\", "\\\\") // backslash (for regex characters)
}
}
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@ import org.camunda.feel.impl.{EvaluationResultMatchers, FeelEngineTest, FeelInte
import org.camunda.feel.syntaxtree._
import org.scalatest.matchers.should.Matchers
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.prop.TableDrivenPropertyChecks

import scala.collection.immutable.Map

@@ -30,7 +31,8 @@ class InterpreterStringExpressionTest
extends AnyFlatSpec
with Matchers
with FeelEngineTest
with EvaluationResultMatchers {
with EvaluationResultMatchers
with TableDrivenPropertyChecks {

"A string" should "concatenates to another String" in {

@@ -80,40 +82,59 @@ class InterpreterStringExpressionTest
evaluateExpression(""" "a" != null """) should returnResult(true)
}

it should "return not escaped characters" in {

evaluateExpression(""" "Hello\nWorld" """) should returnResult("Hello\nWorld")
evaluateExpression(" x ", Map("x" -> "Hello\nWorld")) should returnResult("Hello\nWorld")
private val escapeSequences = Table(
("Character", "Expected", "Display name"),
('\n', '\n', "new line"),
('\r', '\r', "carriage return"),
('\t', '\t', "tab"),
('\b', '\b', "backspace"),
('\f', '\f', "form feed"),
('\'', '\'', "single quote"),
("\\\"", '"', "double quote"),
("\\\\", '\\', "backslash")
)

evaluateExpression(""" "Hello\rWorld" """) should returnResult("Hello\rWorld")
evaluateExpression(" x ", Map("x" -> "Hello\rWorld")) should returnResult("Hello\rWorld")
it should "contains an escape sequence" in {
forEvery(escapeSequences) { (character, expected, _) =>
val expectedString = s"a $expected b"

evaluateExpression(""" "Hello\'World" """) should returnResult("Hello\'World")
evaluateExpression(" x ", Map("x" -> "Hello\'World")) should returnResult("Hello\'World")
evaluateExpression(s" \"a $character b\" ") should returnResult(expectedString)
evaluateExpression("char", Map("char" -> expectedString)) should returnResult(expectedString)
}
}

evaluateExpression(""" "Hello\tWorld" """) should returnResult("Hello\tWorld")
evaluateExpression(" x ", Map("x" -> "Hello\tWorld")) should returnResult("Hello\tWorld")
private val unicodeCharacters = Table(
("Character", "Display name"),
('\u269D', "\\u269D"),
("\\U101EF", "\\U101EF")
)

evaluateExpression(""" "Hello\"World" """) should returnResult("Hello\"World")
evaluateExpression(" x ", Map("x" -> "Hello\"World")) should returnResult("Hello\"World")
it should "contains unicode characters" in {
forEvery(unicodeCharacters) { (character, _) =>
evaluateExpression(s" \"a $character b\" ") should returnResult(s"a $character b")
}
}

List(
" \' ",
" \\ ",
" \n ",
" \r ",
" \t ",
""" \u269D """,
""" \U101EF """
private val regexCharacters = Table(
("Character", "Display name"),
("\\s", "\\s"),
("\\S", "\\S"),
("\\d", "\\d"),
("\\w", "\\w"),
("\\R", "\\R"),
("\\h", "\\h"),
("\\v", "\\v"),
("\\\n", "\\n"),
("\\\r", "\\r")
)
.foreach { notEscapeChar =>
it should s"contains a not escape sequence ($notEscapeChar)" in {

evaluateExpression(s""" "a $notEscapeChar b" """) should returnResult(
s"""a $notEscapeChar b"""
)
}
it should "contains a regex character" in {
forEvery(regexCharacters) { (character, _) =>
val expectedString = s"a $character b"

evaluateExpression(s" \"a $character b\" ") should returnResult(expectedString)
evaluateExpression("char", Map("char" -> expectedString)) should returnResult(expectedString)
}
}

}