From 2cd617bc93974ca79ea293e84f6acad6a0df92c8 Mon Sep 17 00:00:00 2001
From: Florian Angerer <florian.angerer@oracle.com>
Date: Fri, 20 Oct 2017 11:35:14 +0200
Subject: [PATCH] Fix: Builting 'charmatch' could not handle empty string.

---
 .../oracle/truffle/r/nodes/builtin/base/CharMatch.java    | 2 +-
 .../src/com/oracle/truffle/r/test/ExpectedTestOutput.test | 8 ++++++++
 .../truffle/r/test/builtins/TestBuiltin_charmatch.java    | 2 ++
 3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CharMatch.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CharMatch.java
index 166b7545ea..ad041d7000 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CharMatch.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CharMatch.java
@@ -43,7 +43,7 @@ public abstract class CharMatch extends RBuiltinNode.Arg3 {
             for (int j = 0; j < table.getLength(); j++) {
                 final String targetString = table.getDataAt(j);
                 int matchLength = 0;
-                while (matchLength < matchString.length() && (matchString.charAt(matchLength) == targetString.charAt(matchLength))) {
+                while (matchLength < matchString.length() && matchLength < targetString.length() && (matchString.charAt(matchLength) == targetString.charAt(matchLength))) {
                     matchLength++;
                 }
                 /*
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
index 3ed70f713c..39b168d623 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
@@ -13751,6 +13751,10 @@ character(0)
 #{charmatch("med", c("mean", "median", "mode"))}
 [1] 2
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_charmatch.testCharMatch#
+#{charmatch('hello', c(''))}
+[1] NA
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_charmatch.testCharMatch#
 #{charmatch(c("ole","ab"),c("ole","ab"))}
 [1] 1 2
@@ -13759,6 +13763,10 @@ character(0)
 #{charmatch(c("ole","ab"),c("ole","ole"))}
 [1]  0 NA
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_charmatch.testCharMatch#
+#{charmatch(c('', 'hello', '[', 'foo', '{', '(', ''), c('[', '(', '{', ''), nomatch = NA)}
+[1]  4 NA  1 NA  3  2  4
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_charmatch.testCharMatch#
 #{charmatch(matrix(c('h','l','e',6),2,2,byrow=T), "hello")}
 [1]  1 NA NA NA
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_charmatch.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_charmatch.java
index cc7da5bc9b..7d3a8d1b3e 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_charmatch.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_charmatch.java
@@ -70,5 +70,7 @@ public class TestBuiltin_charmatch extends TestBase {
         assertEval("{charmatch(c(\"ole\",\"ab\"),c(\"ole\",\"ab\"))}");
         assertEval("{charmatch(c(\"ole\",\"ab\"),c(\"ole\",\"ole\"))}");
         assertEval("{charmatch(matrix(c('h','l','e',6),2,2,byrow=T), \"hello\")}");
+        assertEval("{charmatch('hello', c(''))}");
+        assertEval("{charmatch(c('', 'hello', '[', 'foo', '{', '(', ''), c('[', '(', '{', ''), nomatch = NA)}");
     }
 }
-- 
GitLab