From 65f438e56b88843fd91287ca60b2e5bdd3af9cb7 Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Tue, 11 Apr 2017 19:16:44 +0200 Subject: SI-9915 Utf8_info are modified UTF8 Adapted from scalac commit 3c5990ce5839f4bdfca8fed7f2c415a72f6a8bd8 by Som Snytt: Use DataInputStream.readUTF to read CONSTANT_Utf8_info. This fixes reading embedded null char and supplementary chars. --- .../tools/dotc/core/classfile/ClassfileParser.scala | 8 ++++++-- tests/run/t9915/C_1.java | 20 ++++++++++++++++++++ tests/run/t9915/Test_2.scala | 12 ++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 tests/run/t9915/C_1.java create mode 100644 tests/run/t9915/Test_2.scala diff --git a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala index bebc4ab2c..9415c047f 100644 --- a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala +++ b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala @@ -7,7 +7,7 @@ import Contexts._, Symbols._, Types._, Names._, StdNames._, NameOps._, Scopes._, import SymDenotations._, unpickleScala2.Scala2Unpickler._, Constants._, Annotations._, util.Positions._ import NameKinds.{ModuleClassName, DefaultGetterName} import ast.tpd._ -import java.io.{ File, IOException } +import java.io.{ ByteArrayInputStream, DataInputStream, File, IOException } import java.lang.Integer.toHexString import scala.collection.{ mutable, immutable } import scala.collection.mutable.{ ListBuffer, ArrayBuffer } @@ -935,12 +935,16 @@ class ClassfileParser( case null => val start = starts(index) if (in.buf(start).toInt != CONSTANT_UTF8) errorBadTag(start) - val name = termName(in.buf, start + 3, in.getChar(start + 1)) + val len = in.getChar(start + 1).toInt + val name = termName(fromMUTF8(in.buf, start + 1, len + 2)) values(index) = name name } } + private def fromMUTF8(bytes: Array[Byte], offset: Int, len: Int): String = + new DataInputStream(new ByteArrayInputStream(bytes, offset, len)).readUTF + /** Return the name found at given index in the constant pool, with '/' replaced by '.'. */ def getExternalName(index: Int): SimpleTermName = { if (index <= 0 || len <= index) diff --git a/tests/run/t9915/C_1.java b/tests/run/t9915/C_1.java new file mode 100644 index 000000000..4269cf74e --- /dev/null +++ b/tests/run/t9915/C_1.java @@ -0,0 +1,20 @@ +/* + * javac: -encoding UTF-8 + */ +public class C_1 { + public static final String NULLED = "X\000ABC"; + public static final String SUPPED = "𐒈𐒝𐒑𐒛𐒐𐒘𐒕𐒖"; + + public String nulled() { + return C_1.NULLED; + } + public String supped() { + return C_1.SUPPED; + } + public int nulledSize() { + return C_1.NULLED.length(); + } + public int suppedSize() { + return C_1.SUPPED.length(); + } +} diff --git a/tests/run/t9915/Test_2.scala b/tests/run/t9915/Test_2.scala new file mode 100644 index 000000000..afed667cc --- /dev/null +++ b/tests/run/t9915/Test_2.scala @@ -0,0 +1,12 @@ + +object Test extends App { + val c = new C_1 + assert(c.nulled == "X\u0000ABC") // "X\000ABC" + assert(c.supped == "𐒈𐒝𐒑𐒛𐒐𐒘𐒕𐒖") + + assert(C_1.NULLED == "X\u0000ABC") // "X\000ABC" + assert(C_1.SUPPED == "𐒈𐒝𐒑𐒛𐒐𐒘𐒕𐒖") + + assert(C_1.NULLED.size == "XYABC".size) + assert(C_1.SUPPED.codePointCount(0, C_1.SUPPED.length) == 8) +} -- cgit v1.2.3