Skip to content

Commit

Permalink
fix: ignore invalid expressions when parsing config.
Browse files Browse the repository at this point in the history
  • Loading branch information
outofcoffee committed Oct 1, 2024
1 parent dece4c6 commit 093e952
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ object ConfigUtil {
val configFile = configRef.file
try {
val rawContents = configFile.readText()
val parsedContents = ExpressionUtil.eval(rawContents, expressionEvaluators, nullifyUnsupported = false)
val parsedContents = ExpressionUtil.eval(rawContents, expressionEvaluators, onUnsupported = ExpressionUtil.UnsupportedBehaviour.IGNORE)

val config = lookupMapper(configFile).readValue(parsedContents, LightweightConfig::class.java)
config.plugin
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,6 @@ object PlaceholderUtil {
evaluators: Map<String, ExpressionEvaluator<*>>,
): String {
val context = mapOf(HttpExpressionEvaluator.HTTP_EXCHANGE_KEY to httpExchange)
return ExpressionUtil.eval(input, evaluators, context, queryProvider, nullifyUnsupported = true)
return ExpressionUtil.eval(input, evaluators, context, queryProvider, onUnsupported = ExpressionUtil.UnsupportedBehaviour.NULLIFY)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,16 @@ object ExpressionUtil {
*/
private val expressionPattern = Pattern.compile("\\$\\{(.+?)}")

enum class UnsupportedBehaviour {
NULLIFY,
IGNORE,
}

data class MatchResult(
val replace: Boolean,
val replacement: String? = null,
)

/**
* Evaluates an expression in the form:
* ```
Expand All @@ -79,7 +89,7 @@ object ExpressionUtil {
evaluators: Map<String, ExpressionEvaluator<*>>,
context: Map<String, Any> = emptyMap(),
queryProvider: QueryProvider? = null,
nullifyUnsupported: Boolean,
onUnsupported: UnsupportedBehaviour,
): String {
val matcher = expressionPattern.matcher(input)
var matched = false
Expand All @@ -88,9 +98,14 @@ object ExpressionUtil {
matched = true
val expression = matcher.group(1)
try {
val result = evalSingle(expression, evaluators, context, queryProvider, nullifyUnsupported)
val result = evalSingle(expression, evaluators, context, queryProvider, onUnsupported)
LOGGER.trace("{}={}", expression, result)
matcher.appendReplacement(sb, result)
if (result.replace) {
matcher.appendReplacement(sb, result.replacement)
} else {
matcher.appendReplacement(sb, "")
sb.append(matcher.group(0))
}
} catch (e: Exception) {
throw RuntimeException("Error evaluating expression: $expression", e)
}
Expand All @@ -108,24 +123,26 @@ object ExpressionUtil {
evaluators: Map<String, ExpressionEvaluator<*>>,
context: Map<String, Any>,
queryProvider: QueryProvider?,
nullifyUnsupported: Boolean,
): String? {
var result: String? = null

onUnsupported: UnsupportedBehaviour,
): MatchResult {
val evaluator = lookupEvaluator(expression, evaluators)
evaluator?.let {
result = loadAndQuery(expression, context, evaluator, queryProvider) ?: ""

return MatchResult(
replace = true,
replacement = loadAndQuery(expression, context, evaluator, queryProvider) ?: ""
)
} ?: run {
if (nullifyUnsupported) {
LOGGER.warn("Unsupported expression: $expression")
result = ""
} else {
// don't replace; should ignore match
result = "\\\${$expression}"
when (onUnsupported) {
UnsupportedBehaviour.IGNORE -> {
LOGGER.trace("Ignoring unsupported expression: $expression")
return MatchResult(replace = false)
}
UnsupportedBehaviour.NULLIFY -> {
LOGGER.warn("Nullifying unsupported expression: $expression")
return MatchResult(replace = true, replacement = "")
}
}
}
return result
}

private fun lookupEvaluator(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class ExpressionUtilTest {
override fun eval(expression: String, context: Map<String, *>) = null
}
),
nullifyUnsupported = true,
onUnsupported = ExpressionUtil.UnsupportedBehaviour.NULLIFY,
)

assertThat(result, equalTo("fallback"))
Expand All @@ -27,8 +27,28 @@ class ExpressionUtilTest {
val result = ExpressionUtil.eval(
input = "\${invalid}",
evaluators = emptyMap(),
nullifyUnsupported = true,
onUnsupported = ExpressionUtil.UnsupportedBehaviour.NULLIFY,
)
assertThat(result, equalTo(""))
}

@Test
fun `ignore invalid expression`() {
val result = ExpressionUtil.eval(
input = "\${some.expression.with:\$inlineDollar}",
evaluators = emptyMap(),
onUnsupported = ExpressionUtil.UnsupportedBehaviour.IGNORE,
)
assertThat(result, equalTo("\${some.expression.with:\$inlineDollar}"))
}

@Test
fun `ignore multiple invalid expressions`() {
val result = ExpressionUtil.eval(
input = "\${some.expression.with:\$inlineDollar} and \${another.expression}",
evaluators = emptyMap(),
onUnsupported = ExpressionUtil.UnsupportedBehaviour.IGNORE,
)
assertThat(result, equalTo("\${some.expression.with:\$inlineDollar} and \${another.expression}"))
}
}

0 comments on commit 093e952

Please sign in to comment.