Skip to content

Commit

Permalink
Add get_string_data to DexIdx and use in DexLoader
Browse files Browse the repository at this point in the history
Summary: Do not preload DexString instances when checking type ids by using the new method.

Reviewed By: thezhangwei

Differential Revision: D67782728

fbshipit-source-id: 2ad71d9114f6e21137ceb0ebe48a27ddc135fd9a
  • Loading branch information
agampe authored and facebook-github-bot committed Jan 6, 2025
1 parent 3f868ec commit 1ba83c7
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 11 deletions.
17 changes: 12 additions & 5 deletions libredex/DexIdx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ DexMethodHandle* DexIdx::get_methodhandleidx_fromdex(uint32_t mhidx) {
}
}

const DexString* DexIdx::get_stringidx_fromdex(uint32_t stridx) {
std::string_view DexIdx::get_string_data(uint32_t stridx,
uint32_t* utfsize) const {
redex_assert(stridx < m_string_ids_size);
uint32_t stroff = m_string_ids[stridx].offset;
// Bounds check is conservative. May incorrectly reject short strings
Expand All @@ -125,17 +126,23 @@ const DexString* DexIdx::get_stringidx_fromdex(uint32_t stridx) {
const uint8_t* dstr = m_dexbase + stroff;
/* Strip off uleb128 size encoding */

uint32_t utfsize = read_uleb128(&dstr);
uint32_t utfsize_local = read_uleb128(&dstr);
if (utfsize != nullptr) {
*utfsize = utfsize_local;
}
// Find null terminator.
auto null_cur = dstr;
while (*null_cur != '\0' && null_cur < m_dexbase + get_file_size()) {
++null_cur;
}
always_assert_type_log(null_cur < m_dexbase + get_file_size(), INVALID_DEX,
"Missing null terminator");

auto ret = DexString::make_string(
std::string_view((const char*)dstr, null_cur - dstr));
return std::string_view((const char*)dstr, null_cur - dstr);
}
const DexString* DexIdx::get_stringidx_fromdex(uint32_t stridx) {
uint32_t utfsize;
auto str_data = get_string_data(stridx, &utfsize);
auto ret = DexString::make_string(str_data);
always_assert_type_log(
ret->length() == utfsize,
INVALID_DEX,
Expand Down
1 change: 1 addition & 0 deletions libredex/DexIdx.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class DexIdx {
public:
explicit DexIdx(const dex_header* dh);

std::string_view get_string_data(uint32_t stridx, uint32_t* utfsize) const;
const DexString* get_stringidx(uint32_t stridx) {
always_assert_type_log(
stridx < m_string_ids_size, RedexError::INVALID_DEX,
Expand Down
11 changes: 5 additions & 6 deletions libredex/DexLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,12 +255,11 @@ void validate_type_ids_table(DexIdx* idx, const dex_header* dh) {
always_assert_type_log(type_id.string_idx < str_size, INVALID_DEX,
"Type index out of bounds");

// This will preload the string, but otherwise we duplicate some nontrivial
// decode checking.
auto* dex_str = idx->get_stringidx(type_id.string_idx);
always_assert_type_log(type::is_valid(dex_str->str()), INVALID_DEX,
"%s is not a valid type descriptor",
dex_str->c_str());
// Don't preload the string, just check the plain data.
auto dex_str =
idx->get_string_data(type_id.string_idx, /*utfsize=*/nullptr);
always_assert_type_log(type::is_valid(dex_str), INVALID_DEX,
"%s is not a valid type descriptor", dex_str.data());
}
}

Expand Down

0 comments on commit 1ba83c7

Please sign in to comment.