[SYSTEMML-2472] Fix robustness parsing of named function arguments This patch fixes robustness issues on parsing named function arguments, specifically, if the value is a literal which contains the delimiter '='. In this case, the last argument is remainder was used as a data type value which either crashes directly or might cause crashes on value parsing.
Project: http://git-wip-us.apache.org/repos/asf/systemml/repo Commit: http://git-wip-us.apache.org/repos/asf/systemml/commit/252e4983 Tree: http://git-wip-us.apache.org/repos/asf/systemml/tree/252e4983 Diff: http://git-wip-us.apache.org/repos/asf/systemml/diff/252e4983 Branch: refs/heads/master Commit: 252e498394536c496d4d27292d95f35ee043dc69 Parents: e90af57 Author: Matthias Boehm <[email protected]> Authored: Mon Jul 30 13:33:29 2018 -0700 Committer: Matthias Boehm <[email protected]> Committed: Mon Jul 30 14:36:14 2018 -0700 ---------------------------------------------------------------------- .../cp/FunctionCallCPInstruction.java | 3 +- .../sysml/runtime/io/IOUtilFunctions.java | 6 ++++ .../functions/misc/FunctionPotpourriTest.java | 7 ++++ .../misc/FunPotpourriNamedArgsQuotedAssign.dml | 37 ++++++++++++++++++++ 4 files changed, 52 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/systemml/blob/252e4983/src/main/java/org/apache/sysml/runtime/instructions/cp/FunctionCallCPInstruction.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/runtime/instructions/cp/FunctionCallCPInstruction.java b/src/main/java/org/apache/sysml/runtime/instructions/cp/FunctionCallCPInstruction.java index 5666d4f..cd741fe 100644 --- a/src/main/java/org/apache/sysml/runtime/instructions/cp/FunctionCallCPInstruction.java +++ b/src/main/java/org/apache/sysml/runtime/instructions/cp/FunctionCallCPInstruction.java @@ -37,6 +37,7 @@ import org.apache.sysml.runtime.controlprogram.context.ExecutionContext; import org.apache.sysml.runtime.controlprogram.context.ExecutionContextFactory; import org.apache.sysml.runtime.instructions.Instruction; import org.apache.sysml.runtime.instructions.InstructionUtils; +import org.apache.sysml.runtime.io.IOUtilFunctions; public class FunctionCallCPInstruction extends CPInstruction { private final String _functionName; @@ -77,7 +78,7 @@ public class FunctionCallCPInstruction extends CPInstruction { List<String> funArgNames = new ArrayList<>(); List<String> boundOutputNames = new ArrayList<>(); for (int i = 0; i < numInputs; i++) { - String[] nameValue = parts[5 + i].split("="); + String[] nameValue = IOUtilFunctions.splitByFirst(parts[5 + i], "="); boundInputs[i] = new CPOperand(nameValue[1]); funArgNames.add(nameValue[0]); boundInputNames.add(boundInputs[i].getName()); http://git-wip-us.apache.org/repos/asf/systemml/blob/252e4983/src/main/java/org/apache/sysml/runtime/io/IOUtilFunctions.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/runtime/io/IOUtilFunctions.java b/src/main/java/org/apache/sysml/runtime/io/IOUtilFunctions.java index 18f0e54..4d7e133 100644 --- a/src/main/java/org/apache/sysml/runtime/io/IOUtilFunctions.java +++ b/src/main/java/org/apache/sysml/runtime/io/IOUtilFunctions.java @@ -333,6 +333,12 @@ public class IOUtilFunctions return numTokens; } + public static String[] splitByFirst(String str, String delim) { + int pos = str.indexOf(delim); + return new String[]{str.substring(0, pos), + str.substring(pos+1, str.length())}; + } + public static FileFormatPropertiesMM readAndParseMatrixMarketHeader(String filename) throws DMLRuntimeException { String[] header = readMatrixMarketHeader(filename); return FileFormatPropertiesMM.parse(header[0]); http://git-wip-us.apache.org/repos/asf/systemml/blob/252e4983/src/test/java/org/apache/sysml/test/integration/functions/misc/FunctionPotpourriTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/sysml/test/integration/functions/misc/FunctionPotpourriTest.java b/src/test/java/org/apache/sysml/test/integration/functions/misc/FunctionPotpourriTest.java index 36ce70a..68e8f00 100644 --- a/src/test/java/org/apache/sysml/test/integration/functions/misc/FunctionPotpourriTest.java +++ b/src/test/java/org/apache/sysml/test/integration/functions/misc/FunctionPotpourriTest.java @@ -44,6 +44,7 @@ public class FunctionPotpourriTest extends AutomatedTestBase private final static String TEST_NAME14 = "FunPotpourriDefaultArgMatrix"; private final static String TEST_NAME15 = "FunPotpourriDefaultArgScalarMatrix1"; private final static String TEST_NAME16 = "FunPotpourriDefaultArgScalarMatrix2"; + private final static String TEST_NAME17 = "FunPotpourriNamedArgsQuotedAssign"; private final static String TEST_DIR = "functions/misc/"; private final static String TEST_CLASS_DIR = TEST_DIR + FunctionPotpourriTest.class.getSimpleName() + "/"; @@ -67,6 +68,7 @@ public class FunctionPotpourriTest extends AutomatedTestBase addTestConfiguration( TEST_NAME14, new TestConfiguration(TEST_CLASS_DIR, TEST_NAME14, new String[] { "R" }) ); addTestConfiguration( TEST_NAME15, new TestConfiguration(TEST_CLASS_DIR, TEST_NAME15, new String[] { "R" }) ); addTestConfiguration( TEST_NAME16, new TestConfiguration(TEST_CLASS_DIR, TEST_NAME16, new String[] { "R" }) ); + addTestConfiguration( TEST_NAME17, new TestConfiguration(TEST_CLASS_DIR, TEST_NAME17, new String[] { "R" }) ); } @Test @@ -159,6 +161,11 @@ public class FunctionPotpourriTest extends AutomatedTestBase runFunctionTest( TEST_NAME16, false ); } + @Test + public void testFunctionNamedArgsQuotedAssign() { + runFunctionTest( TEST_NAME17, false ); + } + private void runFunctionTest(String testName, boolean error) { TestConfiguration config = getTestConfiguration(testName); loadTestConfiguration(config); http://git-wip-us.apache.org/repos/asf/systemml/blob/252e4983/src/test/scripts/functions/misc/FunPotpourriNamedArgsQuotedAssign.dml ---------------------------------------------------------------------- diff --git a/src/test/scripts/functions/misc/FunPotpourriNamedArgsQuotedAssign.dml b/src/test/scripts/functions/misc/FunPotpourriNamedArgsQuotedAssign.dml new file mode 100644 index 0000000..446d949 --- /dev/null +++ b/src/test/scripts/functions/misc/FunPotpourriNamedArgsQuotedAssign.dml @@ -0,0 +1,37 @@ +#------------------------------------------------------------- +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +#------------------------------------------------------------- + +debug = function (String msg){ + verbosePrint("INFO: " + msg) +} + +warning = function (String msg) { + print("WARNING: " + msg) +} + +verbosePrint = function (String msg){ + verbose = ifdef($verbose, FALSE) + if (verbose) + print(msg) +} + +p = ifdef($p, 2) +debug ("p= " + p)
