Handle shift by 32 explicitly.
Looks like it worked before due to undefined behavior always returning
0. But not anymore.
Test: 836-32768classes
Bug: 220821265
Change-Id: Iaaefc0d3237cf3b6bf50798097b98a8004089d7c
diff --git a/libdexfile/dex/type_lookup_table.cc b/libdexfile/dex/type_lookup_table.cc
index 4d20e04..eaa35f5 100644
--- a/libdexfile/dex/type_lookup_table.cc
+++ b/libdexfile/dex/type_lookup_table.cc
@@ -107,7 +107,7 @@
return dex::kDexNoIndex;
}
// Look for the partial hash match first, even if traversing the wrong bucket's chain.
- uint32_t compared_hash_bits = (hash << mask_bits_) >> (2 * mask_bits_);
+ uint32_t compared_hash_bits = static_cast<uint64_t>(hash << mask_bits_) >> (2 * mask_bits_);
while (compared_hash_bits != entry->GetHashBits(mask_bits_)) {
if (entry->IsLast(mask_bits_)) {
return dex::kDexNoIndex;
diff --git a/libdexfile/dex/type_lookup_table.h b/libdexfile/dex/type_lookup_table.h
index a668e62..6619c84 100644
--- a/libdexfile/dex/type_lookup_table.h
+++ b/libdexfile/dex/type_lookup_table.h
@@ -147,7 +147,7 @@
uint32_t GetHashBits(uint32_t mask_bits) const {
DCHECK_LE(mask_bits, 16u);
- return data_ >> (2u * mask_bits);
+ return static_cast<uint64_t>(data_) >> (2u * mask_bits);
}
static uint32_t GetMask(uint32_t mask_bits) {
diff --git a/test/836-32768classes/classes.dex b/test/836-32768classes/classes.dex
new file mode 100644
index 0000000..c3c4c49
--- /dev/null
+++ b/test/836-32768classes/classes.dex
Binary files differ
diff --git a/test/836-32768classes/expected-stderr.txt b/test/836-32768classes/expected-stderr.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/836-32768classes/expected-stderr.txt
diff --git a/test/836-32768classes/expected-stdout.txt b/test/836-32768classes/expected-stdout.txt
new file mode 100644
index 0000000..980a0d5
--- /dev/null
+++ b/test/836-32768classes/expected-stdout.txt
@@ -0,0 +1 @@
+Hello World!
diff --git a/test/836-32768classes/info.txt b/test/836-32768classes/info.txt
new file mode 100644
index 0000000..7eabe62
--- /dev/null
+++ b/test/836-32768classes/info.txt
@@ -0,0 +1,2 @@
+Regression test for a dex file with 32768 classes. We used to rely on undefined
+shift behavior in the type lookup table code.