Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Forward patch from 5.5.2 #594

Merged
merged 6 commits into from
Aug 9, 2023
Merged
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,6 @@ buildNumber.properties

# Binary files
*.class
/dmn-tck-it/dmn-tck-it-python-translator/.venv/
/dmn-tck-it/dmn-tck-it-python-translator/src/scripts.egg-info/
/dmn-tck-it/dmn-tck-it-python-translator/src/UNKNOWN.egg-info/
2 changes: 1 addition & 1 deletion dmn-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@
<dependency>
<groupId>org.fitnesse</groupId>
<artifactId>fitnesse</artifactId>
<version>20211030</version>
<version>20230503</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ private static void addStringFunctions(Environment environment) {
addFunctionDeclaration(environment, "ends with", new BuiltinFunctionType(BOOLEAN, new FormalParameter<>("string", STRING), new FormalParameter<>("match", STRING)));
addFunctionDeclaration(environment, "matches", new BuiltinFunctionType(BOOLEAN, new FormalParameter<>("input", STRING), new FormalParameter<>("pattern", STRING), new FormalParameter<>("flags", STRING, true, false)));
addFunctionDeclaration(environment, "split", new BuiltinFunctionType(STRING_LIST, new FormalParameter<>("string", STRING), new FormalParameter<>("delimiter", STRING)));
addFunctionDeclaration(environment, "string join", new BuiltinFunctionType(STRING, new FormalParameter<>("list", STRING_LIST), new FormalParameter<>("delimiter", STRING, true, false)));
}

private static void addListFunctions(Environment environment) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public abstract class AbstractFEELToJavaVisitor extends AbstractAnalysisVisitor<
FEEL_2_JAVA_FUNCTION.put("lower case", "lowerCase");
FEEL_2_JAVA_FUNCTION.put("upper case", "upperCase");
FEEL_2_JAVA_FUNCTION.put("string length", "stringLength");
FEEL_2_JAVA_FUNCTION.put("string join", "stringJoin");

FEEL_2_JAVA_FUNCTION.put("years and months duration", "yearsAndMonthsDuration");
FEEL_2_JAVA_FUNCTION.put("date and time", "dateAndTime");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,13 @@ public class GoogleJavaFormatter implements JavaFormatter {

static {
try {
setFinalStatic();
JavaFormatterOptions options = JavaFormatterOptions.builder().style(JavaFormatterOptions.Style.GOOGLE).build();
FORMATTER = new Formatter(options);
} catch (Exception e) {
throw new DMNRuntimeException("Cannot set max length in formatter", e);
}
}

static void setFinalStatic() throws Exception {
Field field = JavaFormatterOptions.class.getDeclaredField("DEFAULT_MAX_LINE_LENGTH");
field.setAccessible(true);

Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);

field.set(null, 150);
}

@Override
public String formatSource(String code) {
try {
Expand Down
3 changes: 3 additions & 0 deletions dmn-core/src/main/resources/dmn/1.3/FEELLexer.g4
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,9 @@ NAME:
'ends' WhiteSpace+ 'with'
{ setText("ends with"); }
|
'string' WhiteSpace+ 'join'
{ setText("string join"); }
|
'start' WhiteSpace+ 'position'
{ setText("start position"); }
|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,18 @@ public void testStringFunctions() {
"split(\"John Doe\", \"\\\\s\")",
this.lib.split("John Doe", "\\s"),
this.lib.asList("John", "Doe"));
doExpressionTest(entries, "", "string join([\"a\",\"b\",\"c\"], \"_and_\")",
"FunctionInvocation(Name(string join) -> PositionalParameters(ListLiteral(StringLiteral(\"a\"),StringLiteral(\"b\"),StringLiteral(\"c\")), StringLiteral(\"_and_\")))",
"string",
"stringJoin(asList(\"a\", \"b\", \"c\"), \"_and_\")",
this.lib.stringJoin(this.lib.asList("a", "b", "c"), "_and_"),
"a_and_b_and_c");
doExpressionTest(entries, "", "string join([\"a\",\"b\",\"c\"])",
"FunctionInvocation(Name(string join) -> PositionalParameters(ListLiteral(StringLiteral(\"a\"),StringLiteral(\"b\"),StringLiteral(\"c\"))))",
"string",
"stringJoin(asList(\"a\", \"b\", \"c\"))",
this.lib.stringJoin(this.lib.asList("a", "b", "c")),
"abc");
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@ public void testSimpleName() {
token = checkToken("ends with", NAME, "ends with");
checkPosition(token, 1, 1, 1, 9, 0, 9);

token = checkToken("string join", NAME, "string join");
checkPosition(token, 1, 1, 1, 11, 0, 11);

token = checkToken("list contains", NAME, "list contains");
checkPosition(token, 1, 1, 1, 13, 0, 13);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@
<outputEntry id="_cc1cbffe-d1fe-4646-bc2e-df2bf08cb661-2">
<text>"DECLINE"</text>
</outputEntry>
<annotationEntry>
<text>annotation</text>
</annotationEntry>
</rule>
<rule id="_fbe095b9-b6b8-42f8-b980-3db4fb2dbe12">
<inputEntry id="_fbe095b9-b6b8-42f8-b980-3db4fb2dbe12-0">
Expand Down
3 changes: 3 additions & 0 deletions dmn-core/src/test/resources/dmn/input/1.2/0004-lending.dmn
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@
<outputEntry id="_cc1cbffe-d1fe-4646-bc2e-df2bf08cb661-2">
<text>"DECLINE"</text>
</outputEntry>
<annotationEntry>
<text>annotation</text>
</annotationEntry>
</rule>
<rule id="_fbe095b9-b6b8-42f8-b980-3db4fb2dbe12">
<inputEntry id="_fbe095b9-b6b8-42f8-b980-3db4fb2dbe12-0">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,28 @@ public List<String> split(String string, String delimiter) {
}
}

@Override
public String stringJoin(List<String> list) {
try {
return this.stringLib.stringJoin(list);
} catch (Exception e) {
String message = String.format("stringJoin(%s)", list);
logError(message, e);
return null;
}
}

@Override
public String stringJoin(List<String> list, String delimiter) {
try {
return this.stringLib.stringJoin(list, delimiter);
} catch (Exception e) {
String message = String.format("stringJoin(%s, %s)", list, delimiter);
logError(message, e);
return null;
}
}

//
// Boolean functions
//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ public interface StandardFEELLib<NUMBER, DATE, TIME, DATE_TIME, DURATION> extend

List<String> split(String string, String delimiter);

String stringJoin(List<String> list);

String stringJoin(List<String> list, String delimiter);

//
// Boolean functions
//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class DefaultStringLib implements StringLib {
private static final ThreadLocal<DecimalFormat> DECIMAL_FORMAT = ThreadLocal.withInitial(() -> new DecimalFormat("0.########"));
Expand Down Expand Up @@ -120,6 +122,23 @@ public String substring(String string, Number startPosition) {
return result;
}

@Override
public String stringJoin(List<String> list) {
return stringJoin(list, null);
}

@Override
public String stringJoin(List<String> list, String delimiter) {
if (list == null) {
return null;
}
if (delimiter == null) {
delimiter = "";
}

return list.stream().filter(Objects::nonNull).collect(Collectors.joining(delimiter));
}

@Override
public String substring(String string, Number startPosition, Number length) {
if (string == null || startPosition == null || length == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,8 @@ public interface StringLib {
Boolean matches(String input, String pattern, String flags) throws Exception;

List<String> split(String string, String delimiter);

String stringJoin(List<String> list);

String stringJoin(List<String> list, String delimiter);
}
4 changes: 2 additions & 2 deletions dmn-runtime/src/main/java/com/gs/dmn/runtime/LazyEval.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
*
*/
public final class LazyEval<T> {
protected static final Logger LOGGER = LoggerFactory.getLogger(LazyEval.class);
private static final Logger LOGGER = LoggerFactory.getLogger(LazyEval.class);

private T value;
private boolean isValueSet = false;
Expand All @@ -39,7 +39,7 @@ public T getOrCompute() {
}

private T compute() {
LOGGER.info("Trigger lazy evaluation");
LOGGER.debug("Trigger lazy evaluation");

isValueSet = true;
return value = supplier.get();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ public LoggingEventListener(Logger logger) {

@Override
public void startDRGElement(DRGElement element, Arguments arguments) {
logger.info("Start {} '{}' with inputs '{}'", element.getElementKind().getDisplayName(), element.getName(), arguments);
logger.debug("Start {} '{}' with inputs '{}'", element.getElementKind().getDisplayName(), element.getName(), arguments);
}

@Override
public void endDRGElement(DRGElement element, Arguments arguments, Object output, long duration) {
logger.info("End {} '{}' with output '{}' in {}ms", element.getElementKind().getDisplayName(), element.getName(), output, duration);
logger.debug("End {} '{}' with output '{}' in {}ms", element.getElementKind().getDisplayName(), element.getName(), output, duration);
}

@Override
Expand Down
21 changes: 15 additions & 6 deletions dmn-runtime/src/main/java/com/gs/dmn/serialization/XMLUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/
package com.gs.dmn.serialization;

import com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -23,9 +24,19 @@ public class XMLUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(XMLUtil.class);

public static DocumentBuilderFactory makeDocumentBuilderFactory() {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); // Compliant
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); // compliant
DocumentBuilderFactory dbf = new DocumentBuilderFactoryImpl();

String attribute = null;
try {
attribute = XMLConstants.ACCESS_EXTERNAL_DTD;
dbf.setAttribute(attribute, ""); // Compliant
attribute = XMLConstants.ACCESS_EXTERNAL_SCHEMA;
dbf.setAttribute(attribute, ""); // compliant
} catch (IllegalArgumentException e) {
// This should catch a failed setAttribute feature
LOGGER.debug("IllegalArgumentException was thrown. The attribute '" + attribute
+ "' is probably not supported by your XML processor.");
}
String feature = null;
try {
// This is the PRIMARY defense. If DTDs (doctypes) are disallowed, almost all
Expand All @@ -50,8 +61,6 @@ public static DocumentBuilderFactory makeDocumentBuilderFactory() {
// Disable external DTDs as well
feature = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
dbf.setFeature(feature, false);
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");

// and these as well, per Timothy Morgan's 2014 paper: "XML Schema, DTD, and Entity Attacks"
dbf.setXIncludeAware(false);
Expand All @@ -63,7 +72,7 @@ public static DocumentBuilderFactory makeDocumentBuilderFactory() {
// of service attacks (such as billion laughs or decompression bombs via "jar:") are a risk."
} catch (ParserConfigurationException e) {
// This should catch a failed setFeature feature
LOGGER.info("ParserConfigurationException was thrown. The feature '" + feature
LOGGER.debug("ParserConfigurationException was thrown. The feature '" + feature
+ "' is probably not supported by your XML processor.");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,12 @@ public void testSplit() {
assertNull(getLib().split(null, null));
}

@Test
public void testStringJoin() {
assertNull(getLib().stringJoin(null));
assertNull(getLib().stringJoin(null, null));
}

@Test
public void testAnd() {
assertNull(getLib().and((List) null));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -703,13 +703,30 @@ public void testMatches() {

@Test
public void testSplit() {
assertNull("", getLib().split(null, null));
assertNull("", getLib().split("", ""));
assertNull(getLib().split(null, null));
assertNull(getLib().split("", ""));

assertEquals(getLib().asList("John", "Doe"), getLib().split("John Doe", "\\s"));
assertEquals(getLib().asList("a", "b", "c", "", ""), getLib().split("a;b;c;;", ";"));
}

@Test
public void testStringJoin() {
assertNull(getLib().stringJoin(null));
assertNull(getLib().stringJoin(null, null));

assertEquals("a_and_b_and_c", getLib().stringJoin(makeStringList("a", "b", "c"), "_and_"));
assertEquals("abc", getLib().stringJoin(makeStringList("a", "b", "c"), ""));
assertEquals("abc", getLib().stringJoin(makeStringList("a", "b", "c"), null));
assertEquals( "a", getLib().stringJoin(makeStringList("a"), "X"));
assertEquals("aXc", getLib().stringJoin(makeStringList("a", null, "c"), "X"));
assertEquals("", getLib().stringJoin(makeStringList(), "X"));

assertEquals("abc", getLib().stringJoin(makeStringList("a", "b", "c")));
assertEquals("ac", getLib().stringJoin(makeStringList("a", null, "c")));
assertEquals("", getLib().stringJoin(makeStringList()));
}

//
// Boolean functions
//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1060,6 +1060,14 @@ protected List<NUMBER> makeNumberList(Object... numbers) {
return result;
}

protected List<String> makeStringList(String... strings) {
List<String> result = new ArrayList<>();
for (String str: strings) {
result.add(str);
}
return result;
}

protected DATE makeDate(String literal) {
return getLib().date(literal);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,16 @@ public Boolean matches(String input, String pattern, String flags) throws Except
throw new DMNRuntimeException("Not supported yet");
}

@Override
public String stringJoin(List<String> list) {
throw new DMNRuntimeException("Not supported yet");
}

@Override
public String stringJoin(List<String> list, String delimiter) {
throw new DMNRuntimeException("Not supported yet");
}

@Override
public List<String> split(String string, String delimiter) {
throw new DMNRuntimeException("Not supported yet");
Expand Down
Loading