summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/mirror/string-inl.h1
-rw-r--r--test/021-string2/src/Main.java5
2 files changed, 6 insertions, 0 deletions
diff --git a/runtime/mirror/string-inl.h b/runtime/mirror/string-inl.h
index 75606391ad..84587c871c 100644
--- a/runtime/mirror/string-inl.h
+++ b/runtime/mirror/string-inl.h
@@ -251,6 +251,7 @@ inline String* String::AllocFromByteArray(Thread* self, int32_t byte_length,
Handle<ByteArray> array, int32_t offset,
int32_t high_byte, gc::AllocatorType allocator_type) {
const uint8_t* const src = reinterpret_cast<uint8_t*>(array->GetData()) + offset;
+ high_byte &= 0xff; // Extract the relevant bits before determining `compressible`.
const bool compressible =
kUseStringCompression && String::AllASCII<uint8_t>(src, byte_length) && (high_byte == 0);
const int32_t length_with_flag = String::GetFlaggedCount(byte_length, compressible);
diff --git a/test/021-string2/src/Main.java b/test/021-string2/src/Main.java
index 194f4a1a7d..3b81d8e623 100644
--- a/test/021-string2/src/Main.java
+++ b/test/021-string2/src/Main.java
@@ -700,6 +700,11 @@ public class Main {
$noinline$constNonAsciiString35Equals("\u0440123456789012345678901234567890123x"));
Assert.assertFalse(
$noinline$constNonAsciiString35Equals("01234567890123456789012345678901234"));
+
+ // Regression test for incorrectly creating an uncompressed string when the
+ // string should be compressed. Only the low 8 bits are relevant but the whole
+ // `hibyte` was erroneously tested. Bug: 63661357
+ Assert.assertTrue("A".equals(new String(new byte[] { (byte)'A' }, /* hibyte */ 0x100)));
}
public static boolean $noinline$equalsConstString0(String s) {