Skip to content

Commit 970b8d5

Browse files
authored
Merge pull request #970 from camunda/957-remove
fix: List functions handle invalid zero position
2 parents 41be554 + 6bf385f commit 970b8d5

File tree

2 files changed

+64
-23
lines changed

2 files changed

+64
-23
lines changed

src/main/scala/org/camunda/feel/impl/builtin/ListBuiltinFunctions.scala

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -275,20 +275,26 @@ class ListBuiltinFunctions(private val valueMapper: ValueMapper) {
275275
private def sublistFunction =
276276
builtinFunction(
277277
params = List("list", "start"),
278-
invoke = { case List(ValList(list), ValNumber(start)) =>
279-
ValList(list.slice(listIndex(list, start.intValue), list.length))
278+
invoke = {
279+
case List(ValList(_), ValNumber(start)) if start == 0 =>
280+
ValError("start position must be a non-zero number")
281+
case List(ValList(list), ValNumber(start)) =>
282+
ValList(list.slice(listIndex(list, start.intValue), list.length))
280283
}
281284
)
282285

283286
private def sublistFunction3 = builtinFunction(
284287
params = List("list", "start", "length"),
285-
invoke = { case List(ValList(list), ValNumber(start), ValNumber(length)) =>
286-
ValList(
287-
list.slice(
288-
listIndex(list, start.intValue),
289-
listIndex(list, start.intValue) + length.intValue
288+
invoke = {
289+
case List(ValList(_), ValNumber(start), ValNumber(_)) if start == 0 =>
290+
ValError("start position must be a non-zero number")
291+
case List(ValList(list), ValNumber(start), ValNumber(length)) =>
292+
ValList(
293+
list.slice(
294+
listIndex(list, start.intValue),
295+
listIndex(list, start.intValue) + length.intValue
296+
)
290297
)
291-
)
292298
}
293299
)
294300

@@ -325,23 +331,29 @@ class ListBuiltinFunctions(private val valueMapper: ValueMapper) {
325331

326332
private def insertBeforeFunction = builtinFunction(
327333
params = List("list", "position", "newItem"),
328-
invoke = { case List(ValList(list), ValNumber(position), newItem: Val) =>
329-
ValList(
330-
list
331-
.take(listIndex(list, position.intValue)) ++ (newItem :: Nil) ++ list
332-
.drop(listIndex(list, position.intValue))
333-
)
334+
invoke = {
335+
case List(ValList(_), ValNumber(position), _) if position == 0 =>
336+
ValError("position must be a non-zero number")
337+
case List(ValList(list), ValNumber(position), newItem: Val) =>
338+
ValList(
339+
list
340+
.take(listIndex(list, position.intValue)) ++ (newItem :: Nil) ++ list
341+
.drop(listIndex(list, position.intValue))
342+
)
334343
}
335344
)
336345

337346
private def removeFunction = builtinFunction(
338347
params = List("list", "position"),
339-
invoke = { case List(ValList(list), ValNumber(position)) =>
340-
ValList(
341-
list.take(listIndex(list, position.intValue)) ++ list.drop(
342-
listIndex(list, position.intValue + 1)
348+
invoke = {
349+
case List(ValList(_), ValNumber(position)) if position == 0 =>
350+
ValError("position must be a non-zero number")
351+
case List(ValList(list), ValNumber(position)) =>
352+
ValList(
353+
list.take(listIndex(list, position.intValue)) ++ list.drop(
354+
listIndex(list, position.intValue + 1)
355+
)
343356
)
344-
)
345357
}
346358
)
347359

src/test/scala/org/camunda/feel/impl/builtin/BuiltinListFunctionsTest.scala

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,10 @@ package org.camunda.feel.impl.builtin
1818

1919
import org.scalatest.matchers.should.Matchers
2020
import org.scalatest.flatspec.AnyFlatSpec
21-
import org.camunda.feel._
2221
import org.camunda.feel.api.EvaluationFailureType.FUNCTION_INVOCATION_FAILURE
23-
import org.camunda.feel.impl.{EvaluationResultMatchers, FeelEngineTest, FeelIntegrationTest}
24-
import org.camunda.feel.syntaxtree._
22+
import org.camunda.feel.impl.{EvaluationResultMatchers, FeelEngineTest}
2523

2624
import java.time.LocalDate
27-
import scala.math.BigDecimal.int2bigDecimal
2825

2926
/** @author
3027
* Philipp
@@ -257,6 +254,21 @@ class BuiltinListFunctionsTest
257254
evaluateExpression(" sublist([1,2,3], 1, 2) ") should returnResult(List(1, 2))
258255
}
259256

257+
it should "return null if the start position is 0" in {
258+
259+
evaluateExpression(" sublist([1,2,3], 0) ") should (returnNull() and reportFailure(
260+
failureType = FUNCTION_INVOCATION_FAILURE,
261+
failureMessage =
262+
"Failed to invoke function 'sublist': start position must be a non-zero number"
263+
))
264+
265+
evaluateExpression(" sublist([1,2,3], 0, 2) ") should (returnNull() and reportFailure(
266+
failureType = FUNCTION_INVOCATION_FAILURE,
267+
failureMessage =
268+
"Failed to invoke function 'sublist': start position must be a non-zero number"
269+
))
270+
}
271+
260272
"A append() function" should "return list with item appended" in {
261273

262274
evaluateExpression(" append([1,2], 3) ") should returnResult(List(1, 2, 3))
@@ -274,11 +286,28 @@ class BuiltinListFunctionsTest
274286
evaluateExpression(" insert before([1,3],2,2) ") should returnResult(List(1, 2, 3))
275287
}
276288

289+
it should "return null if the position is 0" in {
290+
291+
evaluateExpression(" insert before([1,3],0,2) ") should (returnNull() and reportFailure(
292+
failureType = FUNCTION_INVOCATION_FAILURE,
293+
failureMessage =
294+
"Failed to invoke function 'insert before': position must be a non-zero number"
295+
))
296+
}
297+
277298
"A remove() function" should "return list with item at _ removed" in {
278299

279300
evaluateExpression(" remove([1,1,3],2) ") should returnResult(List(1, 3))
280301
}
281302

303+
it should "return null if the position is 0" in {
304+
305+
evaluateExpression(" remove([1,2,3], 0) ") should (returnNull() and reportFailure(
306+
failureType = FUNCTION_INVOCATION_FAILURE,
307+
failureMessage = "Failed to invoke function 'remove': position must be a non-zero number"
308+
))
309+
}
310+
282311
"A reverse() function" should "reverse the list" in {
283312

284313
evaluateExpression(" reverse([1,2,3]) ") should returnResult(List(3, 2, 1))

0 commit comments

Comments
 (0)