[clangd] Fix out-of-bounds read in packedLookup (#197021)
The `packedLookup` function doesn't work correctly with byte values over 0x7F (e.g. UTF-8 high bytes) on platforms where `char` is signed (like x86-64). The character is treated as a negative `char`, which gets converted to a negative `int`, which makes `I >> 2` negative, which gives a negative index, and thus an out-of-bounds read. The fix is to change the `int` parameter type to `unsigned char`, to always get the value in the 0x00..0xFF range. The issue has been discovered by the sanitizer buildbot after the #187623 merge, which first introduced tests with non-ASCII source content into the code-completion path.
This commit is contained in:
parent
875e6226aa
commit
943a7da07a
2 changed files with 4 additions and 1 deletions
|
|
@ -145,7 +145,8 @@ constexpr static uint8_t CharRoles[] = {
|
|||
// clang-format on
|
||||
};
|
||||
|
||||
template <typename T> static T packedLookup(const uint8_t *Data, int I) {
|
||||
template <typename T>
|
||||
static T packedLookup(const uint8_t *Data, unsigned char I) {
|
||||
return static_cast<T>((Data[I >> 2] >> ((I & 3) * 2)) & 3);
|
||||
}
|
||||
CharTypeSet calculateRoles(llvm::StringRef Text,
|
||||
|
|
|
|||
|
|
@ -305,6 +305,8 @@ TEST(FuzzyMatch, Segmentation) {
|
|||
returns("+--+---+------"));
|
||||
EXPECT_THAT(segment("t3h PeNgU1N oF d00m!!!!!!!!"), //
|
||||
returns("+-- +-+-+-+ ++ +--- "));
|
||||
EXPECT_THAT(segment("ab🙂cd"), //
|
||||
returns("+-------"));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
|||
Loading…
Reference in a new issue