Index: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp =================================================================== --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp @@ -3065,12 +3065,27 @@ return Error("Invalid record"); SmallVector EXTRACTVALIdx; + Type *CurTy = Agg->getType(); for (unsigned RecSize = Record.size(); OpNum != RecSize; ++OpNum) { + bool IsArray = CurTy->isArrayTy(); + bool IsStruct = CurTy->isStructTy(); uint64_t Index = Record[OpNum]; + + if (!IsStruct && !IsArray) + return Error("EXTRACTVAL: Invalid type"); if ((unsigned)Index != Index) return Error("Invalid value"); + if (IsStruct && Index >= CurTy->subtypes().size()) + return Error("EXTRACTVAL: Invalid struct index"); + if (IsArray && Index >= CurTy->getArrayNumElements()) + return Error("EXTRACTVAL: Invalid array index"); EXTRACTVALIdx.push_back((unsigned)Index); + + if (IsStruct) + CurTy = CurTy->subtypes()[Index]; + else + CurTy = CurTy->subtypes()[0]; } I = ExtractValueInst::Create(Agg, EXTRACTVALIdx); @@ -3089,12 +3104,29 @@ return Error("Invalid record"); SmallVector INSERTVALIdx; + Type *CurTy = Agg->getType(); for (unsigned RecSize = Record.size(); OpNum != RecSize; ++OpNum) { + bool IsArray = CurTy->isArrayTy(); + bool IsStruct = CurTy->isStructTy(); uint64_t Index = Record[OpNum]; + + if (!IsStruct && !IsArray) + return Error("INSERTVAL: Invalid type"); + if (!CurTy->isStructTy() && !CurTy->isArrayTy()) + return Error("Invalid type"); if ((unsigned)Index != Index) return Error("Invalid value"); + if (IsStruct && Index >= CurTy->subtypes().size()) + return Error("INSERTVAL: Invalid struct index"); + if (IsArray && Index >= CurTy->getArrayNumElements()) + return Error("INSERTVAL: Invalid array index"); + INSERTVALIdx.push_back((unsigned)Index); + if (IsStruct) + CurTy = CurTy->subtypes()[Index]; + else + CurTy = CurTy->subtypes()[0]; } I = InsertValueInst::Create(Agg, Val, INSERTVALIdx); Index: llvm/trunk/test/Bitcode/invalid.test =================================================================== --- llvm/trunk/test/Bitcode/invalid.test +++ llvm/trunk/test/Bitcode/invalid.test @@ -17,3 +17,24 @@ BAD-ABBREV-NUMBER: Invalid abbrev number BAD-TYPE-TABLE-FORWARD-REF: Invalid TYPE table: Only named structs can be forward referenced BAD-BITWIDTH: Bitwidth for integer type out of range + +RUN: not llvm-dis -disable-output %p/Inputs/invalid-extractval-array-idx.bc 2>&1 | \ +RUN: FileCheck --check-prefix=EXTRACT-ARRAY %s +RUN: not llvm-dis -disable-output %p/Inputs/invalid-extractval-struct-idx.bc 2>&1 | \ +RUN: FileCheck --check-prefix=EXTRACT-STRUCT %s +RUN: not llvm-dis -disable-output %p/Inputs/invalid-extractval-too-many-idxs.bc 2>&1 | \ +RUN: FileCheck --check-prefix=EXTRACT-IDXS %s +RUN: not llvm-dis -disable-output %p/Inputs/invalid-insertval-array-idx.bc 2>&1 | \ +RUN: FileCheck --check-prefix=INSERT-ARRAY %s +RUN: not llvm-dis -disable-output %p/Inputs/invalid-insertval-struct-idx.bc 2>&1 | \ +RUN: FileCheck --check-prefix=INSERT-STRUCT %s +RUN: not llvm-dis -disable-output %p/Inputs/invalid-insertval-too-many-idxs.bc 2>&1 | \ +RUN: FileCheck --check-prefix=INSERT-IDXS %s + + +EXTRACT-ARRAY: EXTRACTVAL: Invalid array index +EXTRACT-STRUCT: EXTRACTVAL: Invalid struct index +EXTRACT-IDXS: EXTRACTVAL: Invalid type +INSERT-ARRAY: INSERTVAL: Invalid array index +INSERT-STRUCT: INSERTVAL: Invalid struct index +INSERT-IDXS: INSERTVAL: Invalid type