Skip to content

Commit

Permalink
Bitstream reader: Fix undefined behavior seen after rL364464
Browse files Browse the repository at this point in the history
Summary:
After rL364464 the following tests started to fail when
running the clang-doc tests with an ubsan instrumented
build of clang-doc:
    Clang Tools :: clang-doc/single-file-public.cpp
    Extra Tools Unit Tests :: clang-doc/./ClangDocTests/BitcodeTest.emitEnumInfoBitcode
    Extra Tools Unit Tests :: clang-doc/./ClangDocTests/BitcodeTest.emitMethodInfoBitcode
    Extra Tools Unit Tests :: clang-doc/./ClangDocTests/BitcodeTest.emitRecordInfoBitcode
    Extra Tools Unit Tests :: clang-doc/./ClangDocTests/SerializeTest.emitInfoWithCommentBitcode

We need to check that the read value is in range for being
casted to the llvm::bitc::FixedAbbrevIDs enum, before the
cast in ClangDocBitcodeReader::skipUntilRecordOrBlock.

SerializedDiagnosticReader::skipUntilRecordOrBlock was updated
in the same way.

Reviewers: jfb

Reviewed By: jfb

Subscribers: Bigcheese, vsapsai, bruno, ilya-biryukov, dexonsmith, kadircet, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D64262

llvm-svn: 365239
  • Loading branch information
bjope committed Jul 5, 2019
1 parent 28e0187 commit 0092253
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 12 deletions.
15 changes: 8 additions & 7 deletions clang-tools-extra/clang-doc/BitcodeReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -615,10 +615,12 @@ ClangDocBitcodeReader::skipUntilRecordOrBlock(unsigned &BlockOrRecordID) {
return Cursor::BadBlock;
}

// FIXME check that the enum is in range.
auto Code = static_cast<llvm::bitc::FixedAbbrevIDs>(MaybeCode.get());

switch (Code) {
unsigned Code = MaybeCode.get();
if (Code >= static_cast<unsigned>(llvm::bitc::FIRST_APPLICATION_ABBREV)) {
BlockOrRecordID = Code;
return Cursor::Record;
}
switch (static_cast<llvm::bitc::FixedAbbrevIDs>(Code)) {
case llvm::bitc::ENTER_SUBBLOCK:
if (Expected<unsigned> MaybeID = Stream.ReadSubBlockID())
BlockOrRecordID = MaybeID.get();
Expand All @@ -639,9 +641,8 @@ ClangDocBitcodeReader::skipUntilRecordOrBlock(unsigned &BlockOrRecordID) {
continue;
case llvm::bitc::UNABBREV_RECORD:
return Cursor::BadBlock;
default:
BlockOrRecordID = Code;
return Cursor::Record;
case llvm::bitc::FIRST_APPLICATION_ABBREV:
llvm_unreachable("Unexpected abbrev id.");
}
}
llvm_unreachable("Premature stream end.");
Expand Down
13 changes: 8 additions & 5 deletions clang/lib/Frontend/SerializedDiagnosticReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,12 @@ SerializedDiagnosticReader::skipUntilRecordOrBlock(
else
return llvm::errorToErrorCode(Res.takeError());

switch ((llvm::bitc::FixedAbbrevIDs)Code) {
if (Code >= static_cast<unsigned>(llvm::bitc::FIRST_APPLICATION_ABBREV)) {
// We found a record.
BlockOrRecordID = Code;
return Cursor::Record;
}
switch (static_cast<llvm::bitc::FixedAbbrevIDs>(Code)) {
case llvm::bitc::ENTER_SUBBLOCK:
if (Expected<unsigned> Res = Stream.ReadSubBlockID())
BlockOrRecordID = Res.get();
Expand All @@ -145,10 +150,8 @@ SerializedDiagnosticReader::skipUntilRecordOrBlock(
case llvm::bitc::UNABBREV_RECORD:
return SDError::UnsupportedConstruct;

default:
// We found a record.
BlockOrRecordID = Code;
return Cursor::Record;
case llvm::bitc::FIRST_APPLICATION_ABBREV:
llvm_unreachable("Unexpected abbrev id.");
}
}

Expand Down

0 comments on commit 0092253

Please sign in to comment.