From 52435bd28703a667ac6a637717f50462941ac531 Mon Sep 17 00:00:00 2001
From: stepan <stepan.sindelar@oracle.com>
Date: Fri, 10 Feb 2017 12:28:02 +0100
Subject: [PATCH] Fix index out of bounds in CastSymbolNode when the vector is
 empty

---
 .../truffle/r/nodes/unary/CastSymbolNode.java  | 18 ++++++++++++++----
 .../com/oracle/truffle/r/runtime/RError.java   |  1 +
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastSymbolNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastSymbolNode.java
index 58cd32ecd1..b8cc2b7251 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastSymbolNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastSymbolNode.java
@@ -85,27 +85,37 @@ public abstract class CastSymbolNode extends CastBaseNode {
         return RDataFactory.createSymbolInterned(value);
     }
 
-    @Specialization
+    @Specialization(guards = "value.getLength() > 0")
     protected RSymbol doStringVector(RStringVector value) {
         // Only element 0 interpreted
         return doString(value.getDataAt(0));
     }
 
-    @Specialization
+    @Specialization(guards = "value.getLength() > 0")
     protected RSymbol doIntegerVector(RIntVector value) {
         return doInteger(value.getDataAt(0));
     }
 
-    @Specialization
+    @Specialization(guards = "value.getLength() > 0")
     protected RSymbol doDoubleVector(RDoubleVector value) {
         return doDouble(value.getDataAt(0));
     }
 
-    @Specialization
+    @Specialization(guards = "value.getLength() > 0")
     protected RSymbol doLogicalVector(RLogicalVector value) {
         return doLogical(value.getDataAt(0));
     }
 
+    @Specialization(guards = "vector.getLength() == 0")
+    @TruffleBoundary
+    protected RSymbol doEmptyVector(RAbstractVector vector) {
+        if (vector instanceof RList) {
+            throw RError.error(this, RError.Message.INVALID_TYPE_LENGTH, "symbol", 0);
+        } else {
+            throw RError.error(this, Message.INVALID_DATA_OF_TYPE_TOO_SHORT, vector.getRType().getName(), 0);
+        }
+    }
+
     @TruffleBoundary
     private static RSymbol asSymbol(String s) {
         return RDataFactory.createSymbolInterned(s);
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java
index 58bc36b5d7..c4bc15ba7f 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java
@@ -236,6 +236,7 @@ public final class RError extends RuntimeException {
          */
         GENERIC("%s"),
         TOO_SHORT("'%s' is too short"),
+        INVALID_DATA_OF_TYPE_TOO_SHORT("invalid data of mode '%s' (too short)"),
         VECTOR_SIZE_TOO_LARGE("vector size specified is too large"),
         ARG_RECYCYLED("an argument will be fractionally recycled"),
         LENGTH_GT_1("the condition has length > 1 and only the first element will be used"),
-- 
GitLab