mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-18 10:56:11 +00:00
Fix multiple crashes related to incorrect rz_iterator usage.
RzAnalysisBytes are owned by the iterator, so returning analysis bytes while destroying iterator owning it is incorrect.
This commit is contained in:
parent
70024929af
commit
6b660e7a48
@ -698,18 +698,16 @@ void CutterCore::delFlag(const QString &name)
|
||||
emit flagsChanged();
|
||||
}
|
||||
|
||||
PRzAnalysisBytes CutterCore::getRzAnalysisBytesSingle(RVA addr)
|
||||
CutterRzIter<RzAnalysisBytes> CutterCore::getRzAnalysisBytesSingle(RVA addr)
|
||||
{
|
||||
CORE_LOCK();
|
||||
ut8 buf[128];
|
||||
rz_io_read_at(core->io, addr, buf, sizeof(buf));
|
||||
|
||||
auto seek = seekTemp(addr);
|
||||
auto abiter = fromOwned(rz_core_analysis_bytes(core, addr, buf, sizeof(buf), 1));
|
||||
auto ab =
|
||||
abiter ? reinterpret_cast<RzAnalysisBytes *>(rz_iterator_next(abiter.get())) : nullptr;
|
||||
|
||||
return { ab, rz_analysis_bytes_free };
|
||||
// Warning! only safe to use with stack buffer, due to instruction count being 1
|
||||
auto result =
|
||||
CutterRzIter<RzAnalysisBytes>(rz_core_analysis_bytes(core, addr, buf, sizeof(buf), 1));
|
||||
return result;
|
||||
}
|
||||
|
||||
QString CutterCore::getInstructionBytes(RVA addr)
|
||||
|
@ -62,8 +62,6 @@ struct CUTTER_EXPORT RegisterRef
|
||||
QString name;
|
||||
};
|
||||
|
||||
using PRzAnalysisBytes = std::unique_ptr<RzAnalysisBytes, decltype(rz_analysis_bytes_free) *>;
|
||||
|
||||
class CUTTER_EXPORT CutterCore : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -248,7 +246,7 @@ public:
|
||||
QString getGlobalVariableType(RVA offset);
|
||||
|
||||
/* Edition functions */
|
||||
PRzAnalysisBytes getRzAnalysisBytesSingle(RVA addr);
|
||||
CutterRzIter<RzAnalysisBytes> getRzAnalysisBytesSingle(RVA addr);
|
||||
QString getInstructionBytes(RVA addr);
|
||||
QString getInstructionOpcode(RVA addr);
|
||||
void editInstruction(RVA addr, const QString &inst, bool fillWithNops = false);
|
||||
|
@ -51,12 +51,6 @@ static inline auto fromOwned(RZ_OWN RzList *data) -> UniquePtrCP<decltype(data),
|
||||
return { data, {} };
|
||||
}
|
||||
|
||||
static inline auto fromOwned(RZ_OWN RzIterator *data)
|
||||
-> UniquePtrCP<decltype(data), &rz_iterator_free>
|
||||
{
|
||||
return { data, {} };
|
||||
}
|
||||
|
||||
// Rizin list iteration macros
|
||||
// deprecated, prefer using CutterPVector and CutterRzList instead
|
||||
#define CutterRzListForeach(list, it, type, x) \
|
||||
@ -170,4 +164,30 @@ public:
|
||||
iterator end() const { return iterator(nullptr); }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class CutterRzIter
|
||||
{
|
||||
UniquePtrC<RzIterator, &rz_iterator_free> rzIter;
|
||||
|
||||
public:
|
||||
CutterRzIter(RzIterator *rzIter) : rzIter(rzIter)
|
||||
{
|
||||
// immediately attempt advancing by 1, otherwise it's hard to distinguish whether current
|
||||
// element is null due to not having called next, or due to having run out of elements
|
||||
if (rzIter) {
|
||||
++*this;
|
||||
}
|
||||
}
|
||||
|
||||
CutterRzIter<T> &operator++()
|
||||
{
|
||||
rz_iterator_next(rzIter.get());
|
||||
return *this;
|
||||
}
|
||||
operator bool() { return rzIter && rzIter->cur; }
|
||||
T &operator*() { return *reinterpret_cast<RzAnalysisBytes *>(rzIter->cur); }
|
||||
T *get() { return reinterpret_cast<RzAnalysisBytes *>(rzIter->cur); }
|
||||
T *operator->() { return reinterpret_cast<RzAnalysisBytes *>(rzIter->cur); }
|
||||
};
|
||||
|
||||
#endif // RIZINCPP_H
|
||||
|
Loading…
Reference in New Issue
Block a user