diff options
author | Narayan Kamath <narayan@google.com> | 2015-08-28 12:59:48 +0100 |
---|---|---|
committer | Narayan Kamath <narayan@google.com> | 2015-09-02 12:37:49 +0100 |
commit | c609c31fb56ae434caa2d0153cd0a2f74a715071 (patch) | |
tree | 956db0c13d966667726bafcda1e7c6ccc5abcf45 /libutils/tests | |
parent | d239dbb2578ca70cb4cd44b78a0295bdd8af0e36 (diff) | |
download | system_core-c609c31fb56ae434caa2d0153cd0a2f74a715071.zip system_core-c609c31fb56ae434caa2d0153cd0a2f74a715071.tar.gz system_core-c609c31fb56ae434caa2d0153cd0a2f74a715071.tar.bz2 |
libutils: Fix integer overflows in VectorImpl.
Use external/safe-iop to check for overflows on arithmetic
operations.
Also remove an unnecessary copy of Vector/SharedBuffer from
codeflinger and use the copy from libutils instead.
Note that some of the unit tests are somewhat useless due to
test-runner limitations : gtest's ability to filter on abort message
doesn't work when combined with messages formatted by android's logging
system.
bug: 22953624
Change-Id: I46b1ae8ca1f3a010be13aca36a091e76a97a7b70
Diffstat (limited to 'libutils/tests')
-rw-r--r-- | libutils/tests/Android.mk | 8 | ||||
-rw-r--r-- | libutils/tests/Vector_test.cpp | 75 |
2 files changed, 83 insertions, 0 deletions
diff --git a/libutils/tests/Android.mk b/libutils/tests/Android.mk index 7cfad89..d4a45fd 100644 --- a/libutils/tests/Android.mk +++ b/libutils/tests/Android.mk @@ -38,3 +38,11 @@ LOCAL_SHARED_LIBRARIES := \ libutils \ include $(BUILD_NATIVE_TEST) + +include $(CLEAR_VARS) + +LOCAL_MODULE := libutils_tests_host +LOCAL_SRC_FILES := Vector_test.cpp +LOCAL_STATIC_LIBRARIES := libutils liblog + +include $(BUILD_HOST_NATIVE_TEST) diff --git a/libutils/tests/Vector_test.cpp b/libutils/tests/Vector_test.cpp index d29c054..09914bd 100644 --- a/libutils/tests/Vector_test.cpp +++ b/libutils/tests/Vector_test.cpp @@ -71,5 +71,80 @@ TEST_F(VectorTest, CopyOnWrite_CopyAndAddElements) { EXPECT_EQ(other[3], 5); } +// TODO: gtest isn't capable of parsing Abort messages formatted by +// Android (fails differently on host and target), so we always need to +// use an empty error message for death tests. +TEST_F(VectorTest, SetCapacity_Overflow) { + Vector<int> vector; + EXPECT_DEATH(vector.setCapacity(SIZE_MAX / sizeof(int) + 1), ""); +} + +TEST_F(VectorTest, SetCapacity_ShrinkBelowSize) { + Vector<int> vector; + vector.add(1); + vector.add(2); + vector.add(3); + vector.add(4); + + vector.setCapacity(8); + ASSERT_EQ(8, vector.capacity()); + vector.setCapacity(2); + ASSERT_EQ(8, vector.capacity()); +} + +// NOTE: All of the tests below are useless because of the "TODO" above. +// We have no way of knowing *why* the process crashed. Given that we're +// inserting a NULL array, we'll fail with a SIGSEGV eventually. We need +// the ability to make assertions on the abort message to make sure we're +// failing for the right reasons. +TEST_F(VectorTest, _grow_OverflowSize) { + Vector<int> vector; + vector.add(1); + + // Checks that the size calculation (not the capacity calculation) doesn't + // overflow : the size here will be (1 + SIZE_MAX). + // + // EXPECT_DEATH(vector.insertArrayAt(NULL, 0, SIZE_MAX), "new_size_overflow"); + EXPECT_DEATH(vector.insertArrayAt(NULL, 0, SIZE_MAX), ""); +} + +TEST_F(VectorTest, _grow_OverflowCapacityDoubling) { + Vector<int> vector; + + // This should fail because the calculated capacity will overflow even though + // the size of the vector doesn't. + // + // EXPECT_DEATH(vector.insertArrayAt(NULL, 0, (SIZE_MAX - 1)), "new_capacity_overflow"); + EXPECT_DEATH(vector.insertArrayAt(NULL, 0, (SIZE_MAX - 1)), ""); +} + +TEST_F(VectorTest, _grow_OverflowBufferAlloc) { + Vector<int> vector; + // This should fail because the capacity * sizeof(int) overflows, even + // though the capacity itself doesn't. + // + // EXPECT_DEATH(vector.insertArrayAt(NULL, 0, (SIZE_MAX / 2)), "new_alloc_size overflow"); + EXPECT_DEATH(vector.insertArrayAt(NULL, 0, (SIZE_MAX / 2)), ""); +} + +TEST_F(VectorTest, editArray_Shared) { + Vector<int> vector1; + vector1.add(1); + vector1.add(2); + vector1.add(3); + vector1.add(4); + + Vector<int> vector2 = vector1; + ASSERT_EQ(vector1.array(), vector2.array()); + // We must make a copy here, since we're not the exclusive owners + // of this array. + ASSERT_NE(vector1.editArray(), vector2.editArray()); + + // Vector doesn't implement operator ==. + ASSERT_EQ(vector1.size(), vector2.size()); + for (size_t i = 0; i < vector1.size(); ++i) { + EXPECT_EQ(vector1[i], vector2[i]); + } +} } // namespace android |