]> granicus.if.org Git - llvm/commitdiff
[Support] Fix error handling in DataExtractor::get[US]LEB128
authorPavel Labath <pavel@labath.sk>
Mon, 24 Jun 2019 09:11:24 +0000 (09:11 +0000)
committerPavel Labath <pavel@labath.sk>
Mon, 24 Jun 2019 09:11:24 +0000 (09:11 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@364169 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Support/DataExtractor.cpp
unittests/Support/DataExtractorTest.cpp

index 6328d779b3d21f51a22842593ac1dc22d2fe5c04..18e1423b54637027288363fba82e0557e8fc2ecd 100644 (file)
@@ -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;
 }
index 5663dad5cb6594914514b007e5569f6519f6f8b9..9726a74d81f28d80cbc8a49aaa43f342173fd2d1 100644 (file)
@@ -116,4 +116,14 @@ TEST(DataExtractorTest, LEB128) {
   EXPECT_EQ(8U, offset);
 }
 
+TEST(DataExtractorTest, LEB128_error) {
+  DataExtractor DE(StringRef("\x81"), false, 8);
+  uint32_t Offset = 0;
+  EXPECT_EQ(0U, DE.getULEB128(&Offset));
+  EXPECT_EQ(0U, Offset);
+
+  Offset = 0;
+  EXPECT_EQ(0U, DE.getSLEB128(&Offset));
+  EXPECT_EQ(0U, Offset);
+}
 }