Skip to content

Commit

Permalink
JEXL-415: fix handling of deferred/immediate characters not followed …
Browse files Browse the repository at this point in the history
…by curly bracket;
  • Loading branch information
Henri Biestro committed Nov 18, 2023
1 parent cadef16 commit b2431dd
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 51 deletions.
104 changes: 53 additions & 51 deletions src/main/java/org/apache/commons/jexl3/internal/TemplateEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -838,8 +838,10 @@ TemplateExpression parseExpression(final JexlInfo info, final String expr, final
} else {
// revert to CONST
strb.append(immediateChar);
strb.append(c);
state = ParseState.CONST;
// 'unread' the current character
column -= 1;
continue;
}
break;
case DEFERRED0: // #
Expand All @@ -854,8 +856,10 @@ TemplateExpression parseExpression(final JexlInfo info, final String expr, final
} else {
// revert to CONST
strb.append(deferredChar);
strb.append(c);
state = ParseState.CONST;
// 'unread' the current character
column -= 1;
continue;
}
break;
case IMMEDIATE1: // ${...
Expand Down Expand Up @@ -884,59 +888,57 @@ TemplateExpression parseExpression(final JexlInfo info, final String expr, final
break;
case DEFERRED1: // #{...
// skip inner strings (for '}')

// nested immediate in deferred; need to balance count of '{' & '}'

// closing '}'
switch (c) {
case '"':
case '\'':
strb.append(c);
column = StringParser.readString(strb, expr, column + 1, c);
continue;
case '{':
if (expr.charAt(column - 1) == immediateChar) {
inner1 += 1;
strb.deleteCharAt(strb.length() - 1);
nested = true;
} else {
deferred1 += 1;
strb.append(c);
}
continue;
case '}':
// balance nested immediate
if (deferred1 > 0) {
deferred1 -= 1;
strb.append(c);
} else if (inner1 > 0) {
inner1 -= 1;
} else {
// materialize the nested/deferred expr
final String src = strb.toString();
TemplateExpression dexpr;
if (nested) {
dexpr = new NestedExpression(
expr.substring(inested, column + 1),
jexl.parse(info.at(lineno, column), noscript, src, scope),
null);
} else {
dexpr = new DeferredExpression(
strb.toString(),
jexl.parse(info.at(lineno, column), noscript, src, scope),
null);
case '"':
case '\'':
strb.append(c);
column = StringParser.readString(strb, expr, column + 1, c);
continue;
case '{':
if (expr.charAt(column - 1) == immediateChar) {
inner1 += 1;
strb.deleteCharAt(strb.length() - 1);
nested = true;
} else {
deferred1 += 1;
strb.append(c);
}
continue;
case '}':
// balance nested immediate
if (deferred1 > 0) {
deferred1 -= 1;
strb.append(c);
} else if (inner1 > 0) {
inner1 -= 1;
} else {
// materialize the nested/deferred expr
final String src = strb.toString();
TemplateExpression dexpr;
if (nested) {
dexpr = new NestedExpression(
expr.substring(inested, column + 1),
jexl.parse(info.at(lineno, column), noscript, src, scope),
null);
} else {
dexpr = new DeferredExpression(
strb.toString(),
jexl.parse(info.at(lineno, column), noscript, src, scope),
null);
}
builder.add(dexpr);
strb.delete(0, Integer.MAX_VALUE);
nested = false;
state = ParseState.CONST;
}
break;
default:
// do buildup expr
column = append(strb, expr, column, c);
break;
}
builder.add(dexpr);
strb.delete(0, Integer.MAX_VALUE);
nested = false;
state = ParseState.CONST;
}
break;
default:
// do buildup expr
column = append(strb, expr, column, c);
break;
}
break;
case ESCAPE:
if (c == deferredChar) {
Expand Down
23 changes: 23 additions & 0 deletions src/test/java/org/apache/commons/jexl3/Issues400Test.java
Original file line number Diff line number Diff line change
Expand Up @@ -303,4 +303,27 @@ public void test413d() {
Assert.assertTrue(xvar.getMessage().contains("const"));
}
}

@Test
public void test415() {
final JexlBuilder builder = new JexlBuilder().features(new JexlFeatures().constCapture(true));
final JexlEngine jexl = builder.create();
JexlScript script;
Object result;
script = jexl.createScript("`#${c}`", "c");
result = script.execute(null, 42);
Assert.assertEquals("#42",result.toString() );
script = jexl.createScript("`$${c}`", "c");
result = script.execute(null, 42);
Assert.assertEquals("$42",result.toString() );
script = jexl.createScript("`$#{c}`", "c");
result = script.execute(null, 42);
Assert.assertEquals("$42",result.toString() );
script = jexl.createScript("`##{c}`", "c");
result = script.execute(null, 42);
Assert.assertEquals("#42",result.toString() );
script = jexl.createScript("`--##{c}`", "c");
result = script.execute(null, 42);
Assert.assertEquals("--#42",result.toString() );
}
}

0 comments on commit b2431dd

Please sign in to comment.