8074297: substring in XSLT returns wrong character if string contains supplementary chars
8076290: JCK test api/xsl/conf/string/string17 starts failing after JDK-8074297

Reviewed-by: joehw
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/BasisLibrary.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/BasisLibrary.java
index 8d05e9e..242e2ff 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/BasisLibrary.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/runtime/BasisLibrary.java
@@ -270,7 +270,7 @@
         if (Double.isNaN(start))
             return(EMPTYSTRING);
 
-        final int strlen = value.length();
+        final int strlen = getStringLength(value);
         int istart = (int)Math.round(start) - 1;
 
         if (istart > strlen)
@@ -278,6 +278,7 @@
         if (istart < 1)
             istart = 0;
         try {
+            istart = value.offsetByCodePoints(0, istart);
             return value.substring(istart);
         } catch (IndexOutOfBoundsException e) {
             runTimeError(RUN_TIME_INTERNAL_ERR, "substring()");
@@ -297,24 +298,30 @@
             return(EMPTYSTRING);
 
         int istart = (int)Math.round(start) - 1;
+        int ilength = (int)Math.round(length);
         final int isum;
         if (Double.isInfinite(length))
             isum = Integer.MAX_VALUE;
         else
-            isum = istart + (int)Math.round(length);
+            isum = istart + ilength;
 
-        final int strlen = value.length();
+        final int strlen = getStringLength(value);
         if (isum < 0 || istart > strlen)
                 return(EMPTYSTRING);
 
-        if (istart < 0)
+        if (istart < 0) {
+            ilength += istart;
             istart = 0;
+        }
 
         try {
-            if (isum > strlen)
+            istart = value.offsetByCodePoints(0, istart);
+            if (isum > strlen) {
                 return value.substring(istart);
-            else
-                return value.substring(istart, isum);
+            } else {
+                int offset = value.offsetByCodePoints(istart, ilength);
+                return value.substring(istart, offset);
+            }
         } catch (IndexOutOfBoundsException e) {
             runTimeError(RUN_TIME_INTERNAL_ERR, "substring()");
             return null;