[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)

Reply via email to