diff options
author | 2017-07-13 18:49:35 +0100 | |
---|---|---|
committer | 2017-07-13 18:49:35 +0100 | |
commit | a44c44549c8688b0e7257571601625e9eb88cea8 (patch) | |
tree | 994f1496175b29559f2a06c1bc125d7af809300a | |
parent | f6a122c2cdbd871c0073ee5f90449be4fad34dea (diff) |
Fix compressible string check for ctors with `hibyte`.
Only the low 8 bits of the `hibyte` are relevant but we
were checking the whole `hibyte`, erroneously creating
an uncompressed string when the low bits are zero but
high bits are non-zero. String.equals() depends on all
compressible Strings being actually compressed.
Test: Added regression test to 021-string2.
Test: m test-art-host-gtest
Test: testrunner.py --host
Bug: 31040547
Bug: 63661357
Change-Id: I31690b544de928ce9c6f39f3d144d3e2029f38f6
-rw-r--r-- | runtime/mirror/string-inl.h | 1 | ||||
-rw-r--r-- | test/021-string2/src/Main.java | 5 |
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) { |