From b218cfab9d7f7714db5ff404673b561d6bc4c74b Mon Sep 17 00:00:00 2001 From: Gregory Morse Date: Fri, 26 Jul 2019 00:43:52 +0200 Subject: [PATCH] VarMap stable_sort throws Invalid Comparator Can thank Visual Studio 2019 debug build for finding this one. Only debug build runtime error but this is a legitimate violation of C++ standards. stable_sort requires a weak strict ordering yet inspection showed duplicates were ending up in the maplist. The solution is complexity-wise not ideal. But it certainly works to prevent this bug. --- .../Decompiler/src/decompile/cpp/varmap.cc | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/varmap.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/varmap.cc index b5a01672d8..4c0c1e34e0 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/varmap.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/varmap.cc @@ -292,6 +292,16 @@ bool RangeHint::compareRanges(const RangeHint *a,const RangeHint *b) return true; } +bool RangeHint::rangesEqual(const RangeHint* a, const RangeHint* b) +{ + if (a->sstart == b->sstart && a->size == b->size) { + type_metatype ameta = a->type->getMetatype(); + type_metatype bmeta = b->type->getMetatype(); + return (ameta == bmeta); + } + return false; +} + /// \param spc is the (stack) address space associated with this function's local variables /// \param fd is the function associated with these local variables /// \param g is the Architecture @@ -783,7 +793,10 @@ void MapState::addRange(uintb st,Datatype *ct,uint4 fl,RangeHint::RangeType rt,i sign_extend(sst,spaceid->getAddrSize()*8-1); sst = (intb)AddrSpace::addressToByte(sst,spaceid->getWordSize()); RangeHint *range = new RangeHint(st,sz,sst,ct,fl,rt,hi); - maplist.push_back(range); + if (std::find_if(maplist.begin(), maplist.end(), [range](RangeHint* rh) { + return RangeHint::rangesEqual(rh, range); + }) == maplist.end()) + maplist.push_back(range); #ifdef OPACTION_DEBUG if (debugon) { ostringstream s;