| Index: lib/Bitcode/NaCl/TestUtils/NaClBitcodeMungeWriter.cpp
|
| diff --git a/lib/Bitcode/NaCl/TestUtils/NaClBitcodeMungeWriter.cpp b/lib/Bitcode/NaCl/TestUtils/NaClBitcodeMungeWriter.cpp
|
| index da2907b1a9ee44af02ac208e9d5321f59451f7af..13b396955f8dc9e22c6e086815306aff736eb035 100644
|
| --- a/lib/Bitcode/NaCl/TestUtils/NaClBitcodeMungeWriter.cpp
|
| +++ b/lib/Bitcode/NaCl/TestUtils/NaClBitcodeMungeWriter.cpp
|
| @@ -118,10 +118,32 @@ struct WriteState {
|
| BlocksWithOmittedAbbrevs.insert(SetBID);
|
| }
|
|
|
| + // Returns true if abbreviation operand is legal. If not, logs
|
| + // a recoverable error message and returns false. Assumes that
|
| + // the caller does the actual error recovery if applicable.
|
| + bool verifyAbbrevOp(NaClBitCodeAbbrevOp::Encoding Encoding, uint64_t Value,
|
| + const NaClBitcodeAbbrevRecord &Record);
|
| +
|
| // Converts the abbreviation record to the corresponding abbreviation.
|
| // Returns nullptr if unable to build abbreviation.
|
| NaClBitCodeAbbrev *buildAbbrev(const NaClBitcodeAbbrevRecord &Record);
|
|
|
| + // Gets the next value (based on Index) from the record values,
|
| + // assigns it to ExtractedValue, and returns true. Otherwise, logs a
|
| + // recoverable error message and returns false. Assumes that the
|
| + // caller does the actual error recovery if applicable.
|
| + bool LLVM_ATTRIBUTE_UNUSED_RESULT
|
| + nextAbbrevValue(uint64_t &ExtractedValue,
|
| + const NaClBitcodeAbbrevRecord &Record, size_t &Index) {
|
| + if (Index >= Record.Values.size()) {
|
| + RecoverableError()
|
| + << "Malformed abbreviation found: " << Record << "\n";
|
| + return false;
|
| + }
|
| + ExtractedValue = Record.Values[Index++];
|
| + return true;
|
| + }
|
| +
|
| // Emits the given record to the bitcode file. Returns true if
|
| // successful.
|
| bool LLVM_ATTRIBUTE_UNUSED_RESULT
|
| @@ -465,68 +487,71 @@ static NaClBitCodeAbbrev *deleteAbbrev(NaClBitCodeAbbrev *Abbrev) {
|
| return nullptr;
|
| }
|
|
|
| +bool WriteState::verifyAbbrevOp(NaClBitCodeAbbrevOp::Encoding Encoding,
|
| + uint64_t Value,
|
| + const NaClBitcodeAbbrevRecord &Record) {
|
| + if (NaClBitCodeAbbrevOp::isValid(Encoding, Value))
|
| + return true;
|
| + RecoverableError() << "Invalid abbreviation "
|
| + << NaClBitCodeAbbrevOp::getEncodingName(Encoding)
|
| + << "(" << static_cast<int64_t>(Value)
|
| + << ") in: " << Record << "\n";
|
| + return false;
|
| +}
|
| +
|
| NaClBitCodeAbbrev *WriteState::buildAbbrev(
|
| const NaClBitcodeAbbrevRecord &Record) {
|
| // Note: Recover by removing abbreviation.
|
| NaClBitCodeAbbrev *Abbrev = new NaClBitCodeAbbrev();
|
| size_t Index = 0;
|
| - size_t NumValues = Record.Values.size();
|
| - if (NumValues == 0) {
|
| - RecoverableError() << "Empty abbreviation record not allowed: "
|
| - << Record << "\n";
|
| + size_t NumAbbrevOps;
|
| + if (!nextAbbrevValue(NumAbbrevOps, Record, Index))
|
| return deleteAbbrev(Abbrev);
|
| - }
|
| - size_t NumAbbreviations = Record.Values[Index++];
|
| - if (NumAbbreviations == 0) {
|
| + if (NumAbbrevOps == 0) {
|
| RecoverableError() << "Abbreviation must contain at least one operator: "
|
| << Record << "\n";
|
| return deleteAbbrev(Abbrev);
|
| }
|
| - for (size_t Count = 0; Count < NumAbbreviations; ++Count) {
|
| - if (Index >= NumValues) {
|
| - RecoverableError()
|
| - << "Malformed abbreviation found. Expects " << NumAbbreviations
|
| - << " operands but found " << Count << ": " << Record << "\n";
|
| + for (size_t Count = 0; Count < NumAbbrevOps; ++Count) {
|
| + uint64_t IsLiteral;
|
| + if (!nextAbbrevValue(IsLiteral, Record, Index))
|
| return deleteAbbrev(Abbrev);
|
| - }
|
| - switch (Record.Values[Index++]) {
|
| - case 1:
|
| - if (Index >= NumValues) {
|
| - RecoverableError() << "Malformed literal abbreviation: "
|
| - << Record << "\n";
|
| + switch (IsLiteral) {
|
| + case 1: {
|
| + uint64_t Value;
|
| + if (!nextAbbrevValue(Value, Record, Index))
|
| return deleteAbbrev(Abbrev);
|
| - }
|
| - Abbrev->Add(NaClBitCodeAbbrevOp(Record.Values[Index++]));
|
| + if (!verifyAbbrevOp(NaClBitCodeAbbrevOp::Literal, Value, Record))
|
| + return deleteAbbrev(Abbrev);
|
| + Abbrev->Add(NaClBitCodeAbbrevOp(Value));
|
| break;
|
| + }
|
| case 0: {
|
| - if (Index >= NumValues) {
|
| - RecoverableError() << "Malformed abbreviation found: "
|
| - << Record << "\n";
|
| + uint64_t Kind;
|
| + if (!nextAbbrevValue(Kind, Record, Index))
|
| return deleteAbbrev(Abbrev);
|
| - }
|
| - unsigned Kind = Record.Values[Index++];
|
| switch (Kind) {
|
| - case NaClBitCodeAbbrevOp::Fixed:
|
| - if (Index >= NumValues) {
|
| - RecoverableError() << "Malformed fixed abbreviation found: "
|
| - << Record << "\n";
|
| + case NaClBitCodeAbbrevOp::Fixed: {
|
| + uint64_t Value;
|
| + if (!nextAbbrevValue(Value, Record, Index))
|
| return deleteAbbrev(Abbrev);
|
| - }
|
| - Abbrev->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed,
|
| - Record.Values[Index++]));
|
| + if (!verifyAbbrevOp(NaClBitCodeAbbrevOp::Fixed, Value, Record))
|
| + return deleteAbbrev(Abbrev);
|
| + Abbrev->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, Value));
|
| break;
|
| - case NaClBitCodeAbbrevOp::VBR:
|
| - if (Index >= NumValues) {
|
| - RecoverableError() << "Malformed vbr abbreviation found: "
|
| - << Record << "\n";
|
| + }
|
| + case NaClBitCodeAbbrevOp::VBR: {
|
| + uint64_t Value;
|
| + if (!nextAbbrevValue(Value, Record, Index))
|
| return deleteAbbrev(Abbrev);
|
| - }
|
| - Abbrev->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::VBR,
|
| - Record.Values[Index++]));
|
| + if (!verifyAbbrevOp(NaClBitCodeAbbrevOp::VBR, Value, Record))
|
| + return deleteAbbrev(Abbrev);
|
| + Abbrev->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::VBR, Value));
|
| break;
|
| + }
|
| case NaClBitCodeAbbrevOp::Array:
|
| - if (Index >= NumValues) {
|
| - RecoverableError() << "Malformed array abbreviation found: "
|
| + if (Count + 2 != NumAbbrevOps) {
|
| + RecoverableError() << "Array abbreviation must be second to last: "
|
| << Record << "\n";
|
| return deleteAbbrev(Abbrev);
|
| }
|
| @@ -543,11 +568,23 @@ NaClBitCodeAbbrev *WriteState::buildAbbrev(
|
| break;
|
| }
|
| default:
|
| - RecoverableError() << "Error: Bad abbreviation operand encoding "
|
| + RecoverableError() << "Bad abbreviation operand encoding "
|
| << Record.Values[Index-1] << ": " << Record << "\n";
|
| return deleteAbbrev(Abbrev);
|
| }
|
| }
|
| + if (Index != Record.Values.size()) {
|
| + RecoverableError() << "Error: Too many values for number of operands ("
|
| + << NumAbbrevOps << "): "
|
| + << Record << "\n";
|
| + return deleteAbbrev(Abbrev);
|
| + }
|
| + if (!Abbrev->isValid()) {
|
| + raw_ostream &Out = RecoverableError();
|
| + Abbrev->Print(Out << "Abbreviation ");
|
| + Out << " not valid: " << Record << "\n";
|
| + return deleteAbbrev(Abbrev);
|
| + }
|
| return Abbrev;
|
| }
|
|
|
|
|