From 9ab99eecc3c614a6fc74f8ee8fab05ef43a0d3e5 Mon Sep 17 00:00:00 2001 From: "Duncan P. N. Exon Smith" Date: Sat, 20 Feb 2016 20:39:51 +0000 Subject: Lex: Add some unit tests for corrupt header maps Split the implementation of `HeaderMap` into `HeaderMapImpl` so that we can write unit tests that don't depend on the `FileManager`, and then write a few tests that cover the types of corrupt header maps already detected. This also moves type and constant definitions from HeaderMap.cpp to HeaderMapTypes.h so that the test can access them. llvm-svn: 261446 --- clang/unittests/Lex/HeaderMapTest.cpp | 94 +++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 clang/unittests/Lex/HeaderMapTest.cpp (limited to 'clang/unittests/Lex/HeaderMapTest.cpp') diff --git a/clang/unittests/Lex/HeaderMapTest.cpp b/clang/unittests/Lex/HeaderMapTest.cpp new file mode 100644 index 00000000000..726e89c2751 --- /dev/null +++ b/clang/unittests/Lex/HeaderMapTest.cpp @@ -0,0 +1,94 @@ +//===- unittests/Lex/HeaderMapTest.cpp - HeaderMap tests ----------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--------------------------------------------------------------===// + +#include "clang/Lex/HeaderMap.h" +#include "clang/Lex/HeaderMapTypes.h" +#include "llvm/Support/SwapByteOrder.h" +#include "gtest/gtest.h" + +using namespace clang; +using namespace llvm; + +namespace { + +// Lay out a header file for testing. +template struct MapFile { + HMapHeader Header; + HMapBucket Buckets[NumBuckets]; + unsigned char Bytes[NumBytes]; + + void init() { + memset(this, 0, sizeof(MapFile)); + Header.Magic = HMAP_HeaderMagicNumber; + Header.Version = HMAP_HeaderVersion; + Header.NumBuckets = NumBuckets; + Header.StringsOffset = sizeof(Header) + sizeof(Buckets); + } + + void swapBytes() { + using llvm::sys::getSwappedBytes; + Header.Magic = getSwappedBytes(Header.Magic); + Header.Version = getSwappedBytes(Header.Version); + Header.NumBuckets = getSwappedBytes(Header.NumBuckets); + Header.StringsOffset = getSwappedBytes(Header.StringsOffset); + } + + std::unique_ptr getBuffer() const { + return MemoryBuffer::getMemBuffer( + StringRef(reinterpret_cast(this), sizeof(MapFile)), + "header", + /* RequresNullTerminator */ false); + } +}; + +TEST(HeaderMapTest, checkHeaderEmpty) { + bool NeedsSwap; + ASSERT_FALSE(HeaderMapImpl::checkHeader( + *MemoryBuffer::getMemBufferCopy("", "empty"), NeedsSwap)); + ASSERT_FALSE(HeaderMapImpl::checkHeader( + *MemoryBuffer::getMemBufferCopy("", "empty"), NeedsSwap)); +} + +TEST(HeaderMapTest, checkHeaderMagic) { + MapFile<1, 1> File; + File.init(); + File.Header.Magic = 0; + bool NeedsSwap; + ASSERT_FALSE(HeaderMapImpl::checkHeader(*File.getBuffer(), NeedsSwap)); +} + +TEST(HeaderMapTest, checkHeaderReserved) { + MapFile<1, 1> File; + File.init(); + File.Header.Reserved = 1; + bool NeedsSwap; + ASSERT_FALSE(HeaderMapImpl::checkHeader(*File.getBuffer(), NeedsSwap)); +} + +TEST(HeaderMapTest, checkHeaderVersion) { + MapFile<1, 1> File; + File.init(); + ++File.Header.Version; + bool NeedsSwap; + ASSERT_FALSE(HeaderMapImpl::checkHeader(*File.getBuffer(), NeedsSwap)); +} + +TEST(HeaderMapTest, checkHeaderValidButEmpty) { + MapFile<1, 1> File; + File.init(); + bool NeedsSwap; + ASSERT_TRUE(HeaderMapImpl::checkHeader(*File.getBuffer(), NeedsSwap)); + ASSERT_FALSE(NeedsSwap); + + File.swapBytes(); + ASSERT_TRUE(HeaderMapImpl::checkHeader(*File.getBuffer(), NeedsSwap)); + ASSERT_TRUE(NeedsSwap); +} + +} // end namespace -- cgit v1.2.3