diff options
author | Pavel Labath <pavel@labath.sk> | 2019-06-24 09:11:24 +0000 |
---|---|---|
committer | Pavel Labath <pavel@labath.sk> | 2019-06-24 09:11:24 +0000 |
commit | bb6d0b8e7b0d815710a71b8012438a586e986450 (patch) | |
tree | de7159de045cb1aa0028959c42e410061d7a2fed /llvm/lib/Support/DataExtractor.cpp | |
parent | a94c18fc20068b77602c7ef01405e81f1664147f (diff) | |
download | bcm5719-llvm-bb6d0b8e7b0d815710a71b8012438a586e986450.tar.gz bcm5719-llvm-bb6d0b8e7b0d815710a71b8012438a586e986450.zip |
[Support] Fix error handling in DataExtractor::get[US]LEB128
Summary:
These functions are documented as not modifying the offset argument if
the extraction fails (just like other DataExtractor functions). However,
while reviewing D63591 we discovered that this is not the case -- if the
function reaches the end of the data buffer, it will just return the
value parsed until that point and set offset to point to the end of the
buffer.
This fixes the functions to act as advertised, and adds a regression
test.
Reviewers: dblaikie, probinson, bkramer
Subscribers: kristina, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D63645
llvm-svn: 364169
Diffstat (limited to 'llvm/lib/Support/DataExtractor.cpp')
-rw-r--r-- | llvm/lib/Support/DataExtractor.cpp | 28 |
1 files changed, 14 insertions, 14 deletions
diff --git a/llvm/lib/Support/DataExtractor.cpp b/llvm/lib/Support/DataExtractor.cpp index 6328d779b3d..18e1423b546 100644 --- a/llvm/lib/Support/DataExtractor.cpp +++ b/llvm/lib/Support/DataExtractor.cpp @@ -157,12 +157,12 @@ uint64_t DataExtractor::getULEB128(uint32_t *offset_ptr) const { byte = Data[offset++]; result |= uint64_t(byte & 0x7f) << shift; shift += 7; - if ((byte & 0x80) == 0) - break; + if ((byte & 0x80) == 0) { + *offset_ptr = offset; + return result; + } } - - *offset_ptr = offset; - return result; + return 0; } int64_t DataExtractor::getSLEB128(uint32_t *offset_ptr) const { @@ -178,14 +178,14 @@ int64_t DataExtractor::getSLEB128(uint32_t *offset_ptr) const { byte = Data[offset++]; result |= uint64_t(byte & 0x7f) << shift; shift += 7; - if ((byte & 0x80) == 0) - break; + if ((byte & 0x80) == 0) { + // Sign bit of byte is 2nd high order bit (0x40) + if (shift < 64 && (byte & 0x40)) + result |= -(1ULL << shift); + + *offset_ptr = offset; + return result; + } } - - // Sign bit of byte is 2nd high order bit (0x40) - if (shift < 64 && (byte & 0x40)) - result |= -(1ULL << shift); - - *offset_ptr = offset; - return result; + return 0; } |