Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -310,15 +310,23 @@ protected static void appendFilterScript(StringBuilder builder, Filter filter) t
builder.append("function doFilter() { phase[0] = 'filter'; return (");

// call each of the above functions in a big boolean expression
boolean firstRule = true;
for (ListIterator<Rule> iter = enabledElements.listIterator(); iter.hasNext();) {
Rule rule = iter.next();
String operator = "";

if (Objects.equals(rule.getOperator(), Rule.Operator.AND)) {
operator = " && ";
} else if (Objects.equals(rule.getOperator(), Rule.Operator.OR)) {
operator = " || ";
// The first enabled rule has nothing to combine with, so its operator is never
// emitted. Otherwise a disabled first step leaves the next enabled rule's AND/OR
// as a leading operator, producing invalid JavaScript (e.g. "return ( && ...)")
// that fails to compile on deploy. See OpenIntegrationEngine/engine#76.
if (!firstRule) {
if (Objects.equals(rule.getOperator(), Rule.Operator.AND)) {
operator = " && ";
} else if (Objects.equals(rule.getOperator(), Rule.Operator.OR)) {
operator = " || ";
}
}
firstRule = false;

builder.append(operator + "(filterRule" + iter.nextIndex() + "() == true)");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
package com.mirth.connect.server.builders;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.Arrays;
Expand Down Expand Up @@ -225,4 +227,27 @@ public void testNestedIteratorsOuterDisabled() throws ScriptBuilderException {

assertEquals(scriptEmpty, scriptInnerDisabled);
}

@Test
public void testFilterDisabledFirstRuleNoLeadingOperator() throws ScriptBuilderException {
// A disabled first step followed by an enabled rule whose operator is AND must not emit
// the AND as a leading operator in doFilter(); that would be invalid JavaScript and the
// channel would fail to deploy. See OpenIntegrationEngine/engine#76.
Filter filter = new Filter();
Rule disabledFirst = new RuleBuilderRule();
disabledFirst.setEnabled(false);
Rule enabledWithAnd = new RuleBuilderRule();
enabledWithAnd.setOperator(Rule.Operator.AND);
Rule enabledWithAnd2 = new RuleBuilderRule();
enabledWithAnd2.setOperator(Rule.Operator.AND);
filter.setElements(new ArrayList<>(Arrays.asList(disabledFirst, enabledWithAnd, enabledWithAnd2)));

StringBuilder builder = new StringBuilder();
JavaScriptBuilder.appendFilterScript(builder, filter);
String script = builder.toString();

assertFalse("doFilter() must not start with a leading operator: " + script,
script.contains("return ( &&") || script.contains("return ( ||"));
assertTrue(script.contains("return ((filterRule1() == true)"));
}
}
Loading