diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/architecture.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/architecture.cc index e71bf7ad44b..150b8acbcf0 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/architecture.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/architecture.cc @@ -23,6 +23,7 @@ #ifdef CPUI_STATISTICS #include #endif +#include namespace ghidra { @@ -741,23 +742,24 @@ void Architecture::decodeDynamicRule(Decoder &decoder) ProtoModel *Architecture::decodeProto(Decoder &decoder) { - ProtoModel *res; + std::unique_ptr model; uint4 elemId = decoder.peekElement(); if (elemId == ELEM_PROTOTYPE) - res = new ProtoModel(this); + model = std::unique_ptr(new ProtoModel(this)); else if (elemId == ELEM_RESOLVEPROTOTYPE) - res = new ProtoModelMerged(this); + model = std::unique_ptr(new ProtoModelMerged(this)); else throw LowlevelError("Expecting or tag"); - res->decode(decoder); + model->decode(decoder); - ProtoModel *other = getModel(res->getName()); + ProtoModel *other = getModel(model->getName()); if (other != (ProtoModel *)0) { - string errMsg = "Duplicate ProtoModel name: " + res->getName(); - delete res; + string errMsg = "Duplicate ProtoModel name: " + model->getName(); throw LowlevelError(errMsg); } + + ProtoModel* res = model.release(); protoModels[res->getName()] = res; return res; } diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.cc index 491bd3815e4..ca62628ae3d 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/funcdata.cc @@ -14,6 +14,7 @@ * limitations under the License. */ #include "funcdata.hh" +#include namespace ghidra { @@ -615,9 +616,9 @@ void Funcdata::decodeJumpTable(Decoder &decoder) { uint4 elemId = decoder.openElement(ELEM_JUMPTABLELIST); while(decoder.peekElement() != 0) { - JumpTable *jt = new JumpTable(glb); + std::unique_ptr jt = std::unique_ptr(new JumpTable(glb)); jt->decode(decoder); - jumpvec.push_back(jt); + jumpvec.push_back(jt.release()); } decoder.closeElement(elemId); } diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/marshal.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/marshal.cc index 1c138774acb..7d91bf300db 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/marshal.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/marshal.cc @@ -689,7 +689,10 @@ void PackedDecode::endIngest(int4 bufPos) } uint1 *buf = inStream.back().start; buf[bufPos] = ELEMENT_END; + } else { + throw DecoderError("Ended ingestion without any input"); } + } PackedDecode::~PackedDecode(void) @@ -1006,6 +1009,9 @@ AddrSpace *PackedDecode::readSpace(void) AddrSpace *spc; if (typeCode == TYPECODE_ADDRESSSPACE) { res = readInteger(readLengthCode(typeByte)); + if (res >= spcManager->numSpaces()) + throw DecoderError("Invalid address space index"); + spc = spcManager->getSpace(res); if (spc == (AddrSpace *)0) throw DecoderError("Unknown address space index"); diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/marshal.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/marshal.hh index 3b0ec0e4cc2..9817f7b0131 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/marshal.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/marshal.hh @@ -536,7 +536,7 @@ private: uint1 getByte(Position &pos) { return *pos.current; } ///< Get the byte at the current position, do not advance uint1 getBytePlus1(Position &pos); ///< Get the byte following the current byte, do not advance position uint1 getNextByte(Position &pos); ///< Get the byte at the current position and advance to the next byte - void advancePosition(Position &pos,int4 skip); ///< Advance the position by the given number of bytes + void advancePosition(Position &pos,uint4 skip); ///< Advance the position by the given number of bytes uint8 readInteger(int4 len); ///< Read an integer from the \e current position given its length in bytes uint4 readLengthCode(uint1 typeByte) { return ((uint4)typeByte & PackedFormat::LENGTHCODE_MASK); } ///< Extract length code from type byte void findMatchingAttribute(const AttributeId &attribId); ///< Find attribute matching the given id in open element @@ -631,7 +631,7 @@ inline uint1 PackedDecode::getNextByte(Position &pos) /// An exception is thrown of position is advanced past the end of the stream /// \param pos is the position being advanced /// \param skip is the number of bytes to advance -inline void PackedDecode::advancePosition(Position &pos,int4 skip) +inline void PackedDecode::advancePosition(Position &pos,uint4 skip) { while(pos.end - pos.current <= skip) { diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/modelrules.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/modelrules.cc index 2335bc012d1..6401f4e8c8d 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/modelrules.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/modelrules.cc @@ -15,6 +15,7 @@ */ #include "modelrules.hh" #include "funcdata.hh" +#include namespace ghidra { @@ -252,23 +253,23 @@ PrimitiveExtractor::PrimitiveExtractor(Datatype *dt,bool unionIllegal,int offset DatatypeFilter *DatatypeFilter::decodeFilter(Decoder &decoder) { - DatatypeFilter *filter; + std::unique_ptr filter; uint4 elemId = decoder.openElement(ELEM_DATATYPE); string nm = decoder.readString(ATTRIB_NAME); if (nm == "any") { - filter = new SizeRestrictedFilter(); + filter = std::unique_ptr(new SizeRestrictedFilter()); } else if (nm == "homogeneous-float-aggregate") { - filter = new HomogeneousAggregate(TYPE_FLOAT,4,0,0); + filter = std::unique_ptr(new HomogeneousAggregate(TYPE_FLOAT,4,0,0)); } else { // If no other name matches, assume this is a metatype type_metatype meta = string2metatype(nm); - filter = new MetaTypeFilter(meta); + filter = std::unique_ptr(new MetaTypeFilter(meta)); } filter->decode(decoder); decoder.closeElement(elemId); - return filter; + return filter.release(); } /// Parse the given string as a comma or space separated list of decimal integers, @@ -451,18 +452,18 @@ void HomogeneousAggregate::decode(Decoder &decoder) QualifierFilter *QualifierFilter::decodeFilter(Decoder &decoder) { - QualifierFilter *filter; + std::unique_ptr filter; uint4 elemId = decoder.peekElement(); if (elemId == ELEM_VARARGS) - filter = new VarargsFilter(); + filter = std::unique_ptr(new VarargsFilter()); else if (elemId == ELEM_POSITION) - filter = new PositionMatchFilter(-1); + filter = std::unique_ptr(new PositionMatchFilter(-1)); else if (elemId == ELEM_DATATYPE_AT) - filter = new DatatypeMatchFilter(); + filter = std::unique_ptr(new DatatypeMatchFilter()); else return (QualifierFilter *)0; filter->decode(decoder); - return filter; + return filter.release(); } /// The AndFilter assumes ownership of all the filters in the array and the original vector is cleared @@ -592,32 +593,32 @@ bool AssignAction::fillinOutputMap(ParamActive *active) const AssignAction *AssignAction::decodeAction(Decoder &decoder,const ParamListStandard *res) { - AssignAction *action; + std::unique_ptr action; uint4 elemId = decoder.peekElement(); if (elemId == ELEM_GOTO_STACK) - action = new GotoStack(res,0); + action = std::unique_ptr(new GotoStack(res,0)); else if (elemId == ELEM_JOIN) { - action = new MultiSlotAssign(res); + action = std::unique_ptr(new MultiSlotAssign(res)); } else if (elemId == ELEM_CONSUME) { - action = new ConsumeAs(TYPECLASS_GENERAL,res); + action = std::unique_ptr(new ConsumeAs(TYPECLASS_GENERAL,res)); } else if (elemId == ELEM_CONVERT_TO_PTR) { - action = new ConvertToPointer(res); + action = std::unique_ptr(new ConvertToPointer(res)); } else if (elemId == ELEM_HIDDEN_RETURN) { - action = new HiddenReturnAssign(res,hiddenret_specialreg); + action = std::unique_ptr(new HiddenReturnAssign(res,hiddenret_specialreg)); } else if (elemId == ELEM_JOIN_PER_PRIMITIVE) { - action = new MultiMemberAssign(TYPECLASS_GENERAL,false,res->isBigEndian(),res); + action = std::unique_ptr(new MultiMemberAssign(TYPECLASS_GENERAL,false,res->isBigEndian(),res)); } else if (elemId == ELEM_JOIN_DUAL_CLASS) { - action = new MultiSlotDualAssign(res); + action = std::unique_ptr(new MultiSlotDualAssign(res)); } else throw DecoderError("Expecting model rule action"); action->decode(decoder); - return action; + return action.release(); } /// \brief Read the next model rule precondition element from the stream @@ -653,22 +654,22 @@ AssignAction *AssignAction::decodePrecondition(Decoder &decoder,const ParamListS AssignAction *AssignAction::decodeSideeffect(Decoder &decoder,const ParamListStandard *res) { - AssignAction *action; + std::unique_ptr action; uint4 elemId = decoder.peekElement(); if (elemId == ELEM_CONSUME_EXTRA) { - action = new ConsumeExtra(res); + action = std::unique_ptr(new ConsumeExtra(res)); } else if (elemId == ELEM_EXTRA_STACK) { - action = new ExtraStack(res); + action = std::unique_ptr(new ExtraStack(res)); } else if (elemId == ELEM_CONSUME_REMAINING) { - action = new ConsumeRemaining(res); + action = std::unique_ptr(new ConsumeRemaining(res)); } else throw DecoderError("Expecting model rule sideeffect"); action->decode(decoder); - return action; + return action.release(); } /// \brief Truncate a tiling by a given number of bytes diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/override.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/override.cc index f6fd0f55241..cfea2c57cff 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/override.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/override.cc @@ -15,6 +15,7 @@ */ #include "override.hh" #include "funcdata.hh" +#include namespace ghidra { @@ -367,10 +368,10 @@ void Override::decode(Decoder &decoder,Architecture *glb) } else if (subId == ELEM_PROTOOVERRIDE) { Address callpoint = Address::decode(decoder); - FuncProto *fp = new FuncProto(); + std::unique_ptr fp(new FuncProto()); fp->setInternal(glb->defaultfp,glb->types->getTypeVoid()); fp->decode(decoder,glb); - insertProtoOverride(callpoint,fp); + insertProtoOverride(callpoint,fp.release()); } else if (subId == ELEM_FORCEGOTO) { Address targetpc = Address::decode(decoder); diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.cc index 18e2ff8ba18..069e12f77c6 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.cc @@ -15,6 +15,7 @@ */ #include "semantics.hh" #include "translate.hh" +#include namespace ghidra { @@ -720,9 +721,9 @@ void OpTpl::decode(Decoder &decoder) output->decode(decoder); } while(decoder.peekElement() != 0) { - VarnodeTpl *vn = new VarnodeTpl(); + std::unique_ptr vn(new VarnodeTpl()); vn->decode(decoder); - input.push_back(vn); + input.push_back(vn.release()); } decoder.closeElement(el); } @@ -914,9 +915,9 @@ int4 ConstructTpl::decode(Decoder &decoder) result->decode(decoder); } while(decoder.peekElement() != 0) { - OpTpl *op = new OpTpl(); + std::unique_ptr op(new OpTpl()); op->decode(decoder); - vec.push_back(op); + vec.push_back(op.release()); } decoder.closeElement(el); return sectionid; diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.hh index b53b18797d8..2a768a7befd 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.hh @@ -142,7 +142,7 @@ class OpTpl { OpCode opc; vector input; public: - OpTpl(void) {} + OpTpl(void) : output(nullptr) {} OpTpl(OpCode oc) { opc = oc; output = (VarnodeTpl *)0; } ~OpTpl(void); VarnodeTpl *getOut(void) const { return output; } diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/slghpatexpress.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/slghpatexpress.cc index 94109785953..8aeef0f74a3 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/slghpatexpress.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/slghpatexpress.cc @@ -15,6 +15,7 @@ */ #include "slghpatexpress.hh" #include "sleighbase.hh" +#include namespace ghidra { @@ -503,10 +504,12 @@ PatternExpression *PatternExpression::decodeExpression(Decoder &decoder,Translat else if (el == sla::ELEM_NOT_EXP) res = new NotExpression(); else - return (PatternExpression *)0; + throw DecoderError("Invalid pattern expression element"); - res->decode(decoder,trans); - return res; + // Call PatternExpression::release on decoding failure + std::unique_ptr patexp(res, PatternExpression::release); + patexp->decode(decoder, trans); + return patexp.release(); } static intb getInstructionBytes(ParserWalker &walker,int4 bytestart,int4 byteend,bool bigendian) @@ -826,6 +829,9 @@ void OperandValue::decode(Decoder &decoder,Translate *trans) uintm ctid = decoder.readUnsignedInteger(sla::ATTRIB_CT); SleighBase *sleigh = (SleighBase *)trans; SubtableSymbol *tab = dynamic_cast(sleigh->findSymbol(tabid)); + if (ctid >= tab->getNumConstructors()) { + throw DecoderError("Invalid constructor id"); + } ct = tab->getConstructor(ctid); decoder.closeElement(el); } diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/slghpattern.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/slghpattern.cc index fc993930b49..2d856915ca5 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/slghpattern.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/slghpattern.cc @@ -15,6 +15,7 @@ */ #include "slghpattern.hh" #include "slaformat.hh" +#include namespace ghidra { @@ -141,16 +142,16 @@ bool DisjointPattern::resolvesIntersect(const DisjointPattern *op1,const Disjoin DisjointPattern *DisjointPattern::decodeDisjoint(Decoder &decoder) { // DisjointPattern factory - DisjointPattern *res; + std::unique_ptr res; uint4 el = decoder.peekElement(); if (el == sla::ELEM_INSTRUCT_PAT) - res = new InstructionPattern(); + res = std::unique_ptr(new InstructionPattern()); else if (el == sla::ELEM_CONTEXT_PAT) - res = new ContextPattern(); + res = std::unique_ptr(new ContextPattern()); else - res = new CombinePattern(); + res = std::unique_ptr(new CombinePattern()); res->decode(decoder); - return res; + return res.release(); } void PatternBlock::normalize(void) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/slghsymbol.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/slghsymbol.cc index e62c4708b2f..ec6ad32a86a 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/slghsymbol.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/slghsymbol.cc @@ -16,6 +16,7 @@ #include "slghsymbol.hh" #include "sleighbase.hh" #include +#include namespace ghidra { @@ -49,10 +50,12 @@ SymbolTable::~SymbolTable(void) { vector::iterator iter; for(iter=table.begin();iter!=table.end();++iter) - delete *iter; + if (*iter) + delete *iter; vector::iterator siter; for(siter=symbollist.begin();siter!=symbollist.end();++siter) - delete *siter; + if (*siter) + delete *siter; } void SymbolTable::addScope(void) @@ -175,8 +178,20 @@ void SymbolTable::decode(Decoder &decoder,SleighBase *trans) for(int4 i=0;i= table.size()) { + throw SleighError("Bad symbol scope id: exceeds symbol scope table size"); + } + uintm parent = decoder.readUnsignedInteger(sla::ATTRIB_PARENT); + if (parent >= table.size()) { + throw SleighError("Bad symbol scope parent id: exceeds symbol scope table size"); + } + SymbolScope *parscope = (parent==id) ? (SymbolScope *)0 : table[parent]; + if (table[id]) { + throw SleighError("Bad symbol scope parent id: not unique"); + } + table[id] = new SymbolScope( parscope, id ); decoder.closeElement(subel); } @@ -202,39 +217,58 @@ void SymbolTable::decodeSymbolHeader(Decoder &decoder) { // Put the shell of a symbol in the symbol table // in order to allow recursion - SleighSymbol *sym; + std::unique_ptr sym; uint4 el = decoder.peekElement(); if (el == sla::ELEM_USEROP_HEAD) - sym = new UserOpSymbol(); + sym = std::unique_ptr(new UserOpSymbol()); else if (el == sla::ELEM_EPSILON_SYM_HEAD) - sym = new EpsilonSymbol(); + sym = std::unique_ptr(new EpsilonSymbol()); else if (el == sla::ELEM_VALUE_SYM_HEAD) - sym = new ValueSymbol(); + sym = std::unique_ptr(new ValueSymbol()); else if (el == sla::ELEM_VALUEMAP_SYM_HEAD) - sym = new ValueMapSymbol(); + sym = std::unique_ptr(new ValueMapSymbol()); else if (el == sla::ELEM_NAME_SYM_HEAD) - sym = new NameSymbol(); + sym = std::unique_ptr(new NameSymbol()); else if (el == sla::ELEM_VARNODE_SYM_HEAD) - sym = new VarnodeSymbol(); + sym = std::unique_ptr(new VarnodeSymbol()); else if (el == sla::ELEM_CONTEXT_SYM_HEAD) - sym = new ContextSymbol(); + sym = std::unique_ptr(new ContextSymbol()); else if (el == sla::ELEM_VARLIST_SYM_HEAD) - sym = new VarnodeListSymbol(); + sym = std::unique_ptr(new VarnodeListSymbol()); else if (el == sla::ELEM_OPERAND_SYM_HEAD) - sym = new OperandSymbol(); + sym = std::unique_ptr(new OperandSymbol()); else if (el == sla::ELEM_START_SYM_HEAD) - sym = new StartSymbol(); + sym = std::unique_ptr(new StartSymbol()); else if (el == sla::ELEM_END_SYM_HEAD) - sym = new EndSymbol(); + sym = std::unique_ptr(new EndSymbol()); else if (el == sla::ELEM_NEXT2_SYM_HEAD) - sym = new Next2Symbol(); + sym = std::unique_ptr(new Next2Symbol()); else if (el == sla::ELEM_SUBTABLE_SYM_HEAD) - sym = new SubtableSymbol(); + sym = std::unique_ptr(new SubtableSymbol()); else throw SleighError("Bad symbol xml"); + sym->decodeHeader(decoder); // Restore basic elements of symbol - symbollist[sym->id] = sym; // Put the basic symbol in the table - table[sym->scopeid]->addSymbol(sym); // to allow recursion + + if (sym->id >= symbollist.size()) { + throw SleighError("Bad symbol id: exceeds symbollist size"); + } + + if (symbollist[sym->id] != (SleighSymbol *)0) { + throw SleighError("Bad symbol id: not unique"); + } + + if (sym->scopeid >= table.size()) { + throw SleighError("Bad symbol scope id: too large"); + } + + if (table[sym->scopeid] == (SymbolScope *)0) { + throw SleighError("Bad symbol scope id: undefined"); + } + + SleighSymbol *res = sym.release(); + symbollist[res->id] = res; // Put the basic symbol in the table + table[res->scopeid]->addSymbol(res); // to allow recursion } void SymbolTable::purge(void) @@ -500,6 +534,9 @@ void ValueSymbol::encodeHeader(Encoder &encoder) const void ValueSymbol::decode(Decoder &decoder,SleighBase *trans) { + if (patval) + throw DecoderError("Already decoded symbol"); + patval = (PatternValue *) PatternExpression::decodeExpression(decoder,trans); patval->layClaim(); decoder.closeElement(sla::ELEM_VALUE_SYM.getId()); @@ -581,6 +618,9 @@ void ValueMapSymbol::encodeHeader(Encoder &encoder) const void ValueMapSymbol::decode(Decoder &decoder,SleighBase *trans) { + if (patval) + throw DecoderError("Already decoded symbol"); + patval = (PatternValue *) PatternExpression::decodeExpression(decoder,trans); patval->layClaim(); while(decoder.peekElement() != 0) { @@ -660,6 +700,9 @@ void NameSymbol::encodeHeader(Encoder &encoder) const void NameSymbol::decode(Decoder &decoder,SleighBase *trans) { + if (patval) + throw DecoderError("Already decoded symbol"); + patval = (PatternValue *) PatternExpression::decodeExpression(decoder,trans); patval->layClaim(); while(decoder.peekElement() != 0) { @@ -794,6 +837,10 @@ void ContextSymbol::decode(Decoder &decoder,SleighBase *trans) if (lowMissing || highMissing) { throw DecoderError("Missing high/low attributes"); } + + if (patval) + throw DecoderError("Already decoded symbol"); + patval = (PatternValue *) PatternExpression::decodeExpression(decoder,trans); patval->layClaim(); decoder.closeElement(sla::ELEM_CONTEXT_SYM.getId()); @@ -898,6 +945,9 @@ void VarnodeListSymbol::encodeHeader(Encoder &encoder) const void VarnodeListSymbol::decode(Decoder &decoder,SleighBase *trans) { + if (patval) + throw DecoderError("Already decoded symbol"); + patval = (PatternValue *) PatternExpression::decodeExpression(decoder,trans); patval->layClaim(); while(decoder.peekElement() != 0) { @@ -945,7 +995,9 @@ void OperandSymbol::defineOperand(TripleSymbol *tri) OperandSymbol::~OperandSymbol(void) { - PatternExpression::release(localexp); + if (localexp != (PatternExpression *)0) + PatternExpression::release(localexp); + if (defexp != (PatternExpression *)0) PatternExpression::release(defexp); } @@ -1040,6 +1092,9 @@ void OperandSymbol::encodeHeader(Encoder &encoder) const void OperandSymbol::decode(Decoder &decoder,SleighBase *trans) { + if (defexp || localexp) + throw DecoderError("Already decoded symbol"); + defexp = (PatternExpression *)0; triple = (TripleSymbol *)0; flags = 0; @@ -1066,6 +1121,7 @@ void OperandSymbol::decode(Decoder &decoder,SleighBase *trans) localexp = (OperandValue *)PatternExpression::decodeExpression(decoder,trans); localexp->layClaim(); if (decoder.peekElement() != 0) { + defexp = PatternExpression::decodeExpression(decoder,trans); defexp->layClaim(); } @@ -1630,29 +1686,29 @@ void Constructor::decode(Decoder &decoder,SleighBase *trans) decoder.closeElement(subel); } else if (subel == sla::ELEM_CONTEXT_OP) { - ContextOp *c_op = new ContextOp(); + std::unique_ptr c_op = std::unique_ptr(new ContextOp()); c_op->decode(decoder,trans); - context.push_back(c_op); + context.push_back(c_op.release()); } else if (subel == sla::ELEM_COMMIT) { - ContextCommit *c_op = new ContextCommit(); + std::unique_ptr c_op = std::unique_ptr(new ContextCommit()); c_op->decode(decoder,trans); - context.push_back(c_op); + context.push_back(c_op.release()); } else { - ConstructTpl *cur = new ConstructTpl(); + std::unique_ptr cur = std::unique_ptr(new ConstructTpl()); int4 sectionid = cur->decode(decoder); if (sectionid < 0) { - if (templ != (ConstructTpl *)0) - throw LowlevelError("Duplicate main section"); - templ = cur; + if (templ != (ConstructTpl *)0) + throw LowlevelError("Duplicate main section"); + templ = cur.release(); } else { - while(namedtempl.size() <= sectionid) - namedtempl.push_back((ConstructTpl *)0); - if (namedtempl[sectionid] != (ConstructTpl *)0) - throw LowlevelError("Duplicate named section"); - namedtempl[sectionid] = cur; + while(namedtempl.size() <= sectionid) + namedtempl.push_back((ConstructTpl *)0); + if (namedtempl[sectionid] != (ConstructTpl *)0) + throw LowlevelError("Duplicate named section"); + namedtempl[sectionid] = cur.release(); } } subel = decoder.peekElement(); @@ -2334,15 +2390,18 @@ void DecisionNode::decode(Decoder &decoder,DecisionNode *par,SubtableSymbol *sub if (subel == sla::ELEM_PAIR) { decoder.openElement(); uintm id = decoder.readSignedInteger(sla::ATTRIB_ID); + if (id >= sub->getNumConstructors()) { + throw DecoderError("Invalid constructor id"); + } Constructor *ct = sub->getConstructor(id); DisjointPattern *pat = DisjointPattern::decodeDisjoint(decoder); list.push_back(pair(pat,ct)); decoder.closeElement(subel); } else if (subel == sla::ELEM_DECISION) { - DecisionNode *subnode = new DecisionNode(); + std::unique_ptr subnode = std::unique_ptr(new DecisionNode()); subnode->decode(decoder,this,sub); - children.push_back(subnode); + children.push_back(subnode.release()); } subel = decoder.peekElement(); } diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/slghsymbol.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/slghsymbol.hh index 5e8b4d3dfdc..eda7965f5c3 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/slghsymbol.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/slghsymbol.hh @@ -326,7 +326,7 @@ private: void setVariableLength(void) { flags |= variable_len; } bool isVariableLength(void) const { return ((flags&variable_len)!=0); } public: - OperandSymbol(void) {} // For use with decode + OperandSymbol(void) : localexp(nullptr), defexp(nullptr) {} // For use with decode OperandSymbol(const string &nm,int4 index,Constructor *ct); uint4 getRelativeOffset(void) const { return reloffset; } int4 getOffsetBase(void) const { return offsetbase; } @@ -448,8 +448,8 @@ class ContextOp : public ContextChange { int4 shift; // Number of bits to shift value into place public: ContextOp(int4 startbit,int4 endbit,PatternExpression *pe); - ContextOp(void) {} // For use with decode - virtual ~ContextOp(void) { PatternExpression::release(patexp); } + ContextOp(void) : patexp(nullptr) {} // For use with decode + virtual ~ContextOp(void) { if (patexp) PatternExpression::release(patexp); } virtual void validate(void) const; virtual void encode(Encoder &encoder) const; virtual void decode(Decoder &decoder,SleighBase *trans); diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/translate.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/translate.cc index ec235a46d46..b381c274ca6 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/translate.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/translate.cc @@ -14,6 +14,7 @@ * limitations under the License. */ #include "translate.hh" +#include namespace ghidra { @@ -258,20 +259,20 @@ AddrSpace *AddrSpaceManager::decodeSpace(Decoder &decoder,const Translate *trans { uint4 elemId = decoder.peekElement(); - AddrSpace *res; + std::unique_ptr res; if (elemId == ELEM_SPACE_BASE) - res = new SpacebaseSpace(this,trans); + res = std::unique_ptr(new SpacebaseSpace(this,trans)); else if (elemId == ELEM_SPACE_UNIQUE) - res = new UniqueSpace(this,trans); + res = std::unique_ptr(new UniqueSpace(this,trans)); else if (elemId == ELEM_SPACE_OTHER) - res = new OtherSpace(this,trans); + res = std::unique_ptr(new OtherSpace(this,trans)); else if (elemId == ELEM_SPACE_OVERLAY) - res = new OverlaySpace(this,trans); + res = std::unique_ptr(new OverlaySpace(this,trans)); else - res = new AddrSpace(this,trans,IPTR_PROCESSOR); + res = std::unique_ptr(new AddrSpace(this,trans,IPTR_PROCESSOR)); res->decode(decoder); - return res; + return res.release(); } /// This routine initializes (almost) all the address spaces used