WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit 0b16482

Browse files
authored
Refactor: use marks API (#3510)
* Remove: unecessary changes * Add: `rz_mark` in `BundledRizin.cmake` * Fix: clang format * Remove: `::fromString()` * Fix: mark handling * Refactor: use tooltip instead of label * Minimize tooltip flicker with similar dummy text
1 parent 4e53fd6 commit 0b16482

File tree

11 files changed

+519
-4
lines changed

11 files changed

+519
-4
lines changed

cmake/BundledRizin.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ endif()
5555
# instead of being hardcoded.
5656
set (Rizin_VERSION 0.9)
5757

58-
set (RZ_LIBS rz_core rz_config rz_cons rz_io rz_util rz_flag rz_arch rz_debug
58+
set (RZ_LIBS rz_core rz_config rz_cons rz_io rz_util rz_flag rz_mark rz_arch rz_debug
5959
rz_hash rz_bin rz_lang rz_il rz_egg rz_reg rz_search rz_syscall
6060
rz_socket rz_magic rz_crypto rz_type rz_diff rz_sign rz_demangler)
6161
set (RZ_EXTRA_LIBS rz_main)

src/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ set(SOURCES
158158
dialogs/preferences/ShortcutOptionsWidget.cpp
159159
shortcuts/ShortcutManager.cpp
160160
shortcuts/DefaultShortcuts.cpp
161+
dialogs/MarkDialog.cpp
161162
)
162163
set(HEADER_FILES
163164
core/Cutter.h
@@ -325,6 +326,7 @@ set(HEADER_FILES
325326
dialogs/preferences/ShortcutOptionsWidget.h
326327
shortcuts/ShortcutManager.h
327328
shortcuts/DefaultShortcuts.h
329+
dialogs/MarkDialog.h
328330
)
329331
set(UI_FILES
330332
dialogs/AboutDialog.ui
@@ -400,6 +402,7 @@ set(UI_FILES
400402
tools/basefind/BaseFindSearchDialog.ui
401403
tools/basefind/BaseFindResultsDialog.ui
402404
dialogs/preferences/ShortcutOptionsWidget.ui
405+
dialogs/MarkDialog.ui
403406
)
404407
set(QRC_FILES
405408
resources.qrc

src/core/Cutter.cpp

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "common/Configuration.h"
1717
#include "common/AsyncTask.h"
1818
#include "common/RizinTask.h"
19+
#include "dialogs/MarkDialog.h"
1920
#include "dialogs/RizinTaskDialog.h"
2021
#include "common/Json.h"
2122
#include "core/Cutter.h"
@@ -4457,6 +4458,88 @@ QString CutterCore::nearestFlag(RVA offset, RVA *flagOffsetOut)
44574458
return r->name;
44584459
}
44594460

4461+
void CutterCore::addMark(RVA from, RVA to, QString name, QString comment, QColor color)
4462+
{
4463+
CORE_LOCK();
4464+
auto m = rz_mark_set(core->marks, name.toStdString().c_str(), from, to);
4465+
if (m) {
4466+
rz_mark_item_set_comment(m, comment.toStdString().c_str());
4467+
rz_mark_item_set_color(m, color.name().toStdString().c_str());
4468+
}
4469+
emit marksChanged();
4470+
}
4471+
4472+
void CutterCore::delMark(const QString &name)
4473+
{
4474+
CORE_LOCK();
4475+
auto m = rz_mark_get(core->marks, name.toStdString().c_str());
4476+
if (m) {
4477+
rz_mark_unset(core->marks, m);
4478+
}
4479+
emit marksChanged();
4480+
}
4481+
4482+
QList<MarkDescription> CutterCore::convertMarks(RzList *marks)
4483+
{
4484+
QList<MarkDescription> markList;
4485+
4486+
RzListIter *it;
4487+
RzMarkItem *mark;
4488+
CutterRzListForeach (marks, it, RzMarkItem, mark) {
4489+
MarkDescription desc;
4490+
desc.from = mark->from;
4491+
desc.to = mark->to;
4492+
desc.name = mark->name;
4493+
desc.realname = mark->realname;
4494+
desc.comment = mark->comment;
4495+
desc.color = mark->color ? QColor(mark->color) : QColor(Qt::black);
4496+
4497+
markList.append(desc);
4498+
}
4499+
rz_list_free(marks);
4500+
return markList;
4501+
}
4502+
4503+
QList<MarkDescription> CutterCore::getMarks()
4504+
{
4505+
CORE_LOCK();
4506+
return convertMarks(rz_mark_all_list(core->marks));
4507+
}
4508+
4509+
QList<MarkDescription> CutterCore::getMarksAt(RVA addr)
4510+
{
4511+
CORE_LOCK();
4512+
return convertMarks(rz_mark_get_all_off(core->marks, addr));
4513+
}
4514+
4515+
QColor CutterCore::getBlendedMarksColorAt(RVA addr)
4516+
{
4517+
const auto &marks = getMarksAt(addr);
4518+
double r = 0, g = 0, b = 0, a = 0;
4519+
bool first = true;
4520+
4521+
// Iterate in reverse because the oldest/first mark is at the end
4522+
for (auto it = marks.crbegin(); it != marks.crend(); ++it) {
4523+
QColor c = it->color;
4524+
if (!c.isValid()) {
4525+
continue;
4526+
}
4527+
4528+
double cr = c.redF(), cg = c.greenF(), cb = c.blueF();
4529+
if (first) {
4530+
r = cr, g = cg, b = cb, a = MARK_ALPHA_F;
4531+
first = false;
4532+
} else {
4533+
double a_out = MARK_ALPHA_F + a * (1.0 - MARK_ALPHA_F);
4534+
r = (cr * MARK_ALPHA_F + r * a * (1.0 - MARK_ALPHA_F)) / a_out;
4535+
g = (cg * MARK_ALPHA_F + g * a * (1.0 - MARK_ALPHA_F)) / a_out;
4536+
b = (cb * MARK_ALPHA_F + b * a * (1.0 - MARK_ALPHA_F)) / a_out;
4537+
a = a_out;
4538+
}
4539+
}
4540+
return first ? QColor() : QColor::fromRgbF(r, g, b, a);
4541+
}
4542+
44604543
void CutterCore::handleREvent(int type, void *data)
44614544
{
44624545
switch (type) {

src/core/Cutter.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,19 @@ class CUTTER_EXPORT CutterCore : public QObject
253253
QString nearestFlag(RVA offset, RVA *flagOffsetOut);
254254
void triggerFlagsChanged();
255255

256+
/* Marks */
257+
void addMark(RVA from, RVA to, QString name, QString comment = {}, QColor color = {});
258+
void delMark(const QString &name);
259+
QList<MarkDescription> getMarks();
260+
QList<MarkDescription> getMarksAt(RVA addr);
261+
/**
262+
* @brief Compute the blended color of all marks containing a specific address.
263+
* @param addr address to query
264+
* @return resulting blended color, or invalid QColor if no marks are present at
265+
* the specified address
266+
*/
267+
QColor getBlendedMarksColorAt(RVA addr);
268+
256269
/* Global Variables */
257270
void addGlobalVariable(RVA offset, QString name, QString typ);
258271
void delGlobalVariable(QString name);
@@ -788,6 +801,7 @@ class CUTTER_EXPORT CutterCore : public QObject
788801
void breakpointsChanged(RVA offset);
789802
void refreshCodeViews();
790803
void stackChanged();
804+
void marksChanged();
791805
/**
792806
* @brief update all the widgets that are affected by rebasing in debug mode
793807
*/
@@ -872,6 +886,7 @@ class CUTTER_EXPORT CutterCore : public QObject
872886
QVector<QString> getCutterRCFilePaths() const;
873887
QList<TypeDescription> getBaseType(RzBaseTypeKind kind, const char *category);
874888
QList<SearchDescription> getAllSearchCommand(QString searchFor, SearchKind kind, QString in);
889+
QList<MarkDescription> convertMarks(RzList *marks);
875890
};
876891

877892
class CUTTER_EXPORT RzCoreLocked

src/core/CutterDescriptions.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,16 @@ struct BasefindResultDescription
418418
ut32 score;
419419
};
420420

421+
struct MarkDescription
422+
{
423+
RVA from;
424+
RVA to;
425+
QString name;
426+
QString realname;
427+
QString comment;
428+
QColor color;
429+
};
430+
421431
Q_DECLARE_METATYPE(FunctionDescription)
422432
Q_DECLARE_METATYPE(ImportDescription)
423433
Q_DECLARE_METATYPE(ExportDescription)
@@ -459,5 +469,6 @@ Q_DECLARE_METATYPE(RefDescription)
459469
Q_DECLARE_METATYPE(VariableDescription)
460470
Q_DECLARE_METATYPE(BasefindCoreStatusDescription)
461471
Q_DECLARE_METATYPE(BasefindResultDescription)
472+
Q_DECLARE_METATYPE(MarkDescription)
462473

463474
#endif // DESCRIPTIONS_H

src/dialogs/MarkDialog.cpp

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
#include "MarkDialog.h"
2+
#include "Cutter.h"
3+
#include "CutterCommon.h"
4+
#include "ui_MarkDialog.h"
5+
#include <QColorDialog>
6+
#include <QRegularExpressionValidator>
7+
8+
MarkDialog::MarkDialog(RVA start, RVA end, QWidget *parent, QString name)
9+
: QDialog(parent),
10+
ui(new Ui::MarkDialog),
11+
markName(name),
12+
markFrom(start),
13+
markTo(end),
14+
markColor(Qt::black),
15+
markComment(""),
16+
edit(false)
17+
{
18+
ui->setupUi(this);
19+
20+
if (!markName.isEmpty()) {
21+
// Editing existing Mark
22+
setWindowTitle("Edit Mark");
23+
RzCoreLocked core(Core());
24+
RzMarkItem *mark = rz_mark_get(core->marks, markName.toStdString().c_str());
25+
if (mark) {
26+
markFrom = mark->from;
27+
markTo = mark->to;
28+
markColor = QColor(mark->color);
29+
markComment = mark->comment;
30+
}
31+
edit = true;
32+
} else {
33+
// Creating new Mark
34+
setWindowTitle("Add Mark");
35+
markName = QString("%1_%2").arg(RzAddressString(markFrom), RzAddressString(markTo));
36+
}
37+
38+
ui->startAddressEdit->setText(RzAddressString(markFrom));
39+
ui->endAddressEdit->setText(RzAddressString(markTo));
40+
ui->nameEdit->setText(markName);
41+
ui->commentEdit->setText(markComment);
42+
ui->colorDisplay->setStyleSheet(colorToStyle(markColor));
43+
44+
auto hexValidator =
45+
new QRegularExpressionValidator(QRegularExpression("(?:0[xX])?[0-9a-fA-F]+"), this);
46+
ui->startAddressEdit->setValidator(hexValidator);
47+
ui->endAddressEdit->setValidator(hexValidator);
48+
49+
connect(ui->colorButton, &QPushButton::clicked, this, &MarkDialog::onPickColor);
50+
connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &MarkDialog::accept);
51+
connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &MarkDialog::reject);
52+
}
53+
54+
void MarkDialog::accept()
55+
{
56+
bool ok = false;
57+
markFrom = ui->startAddressEdit->text().toULongLong(&ok, 16);
58+
if (!ok) {
59+
QMessageBox::warning(this, tr("Invalid Input"),
60+
tr("Starting address is not a valid hexadecimal number"));
61+
return;
62+
}
63+
markTo = ui->endAddressEdit->text().toULongLong(&ok, 16);
64+
if (!ok) {
65+
QMessageBox::warning(this, tr("Invalid Input"),
66+
tr("Ending address is not a valid hexadecimal number"));
67+
return;
68+
}
69+
if (markFrom > markTo) {
70+
QMessageBox::warning(this, tr("Invalid Input"),
71+
tr("Starting address cannot be greater than ending address"));
72+
return;
73+
}
74+
75+
QString name = ui->nameEdit->text();
76+
if (edit && !name.isEmpty() && name != markName) {
77+
Core()->delMark(markName); // Delete the old mark
78+
} else if (name.isEmpty()) {
79+
QMessageBox::warning(this, tr("Invalid Input"), tr("Name cannot be empty"));
80+
return;
81+
}
82+
83+
markName = name;
84+
markComment = ui->commentEdit->toPlainText();
85+
Core()->addMark(markFrom, markTo, markName, markComment, markColor);
86+
87+
QDialog::accept();
88+
}
89+
90+
MarkDialog::~MarkDialog() {}
91+
92+
void MarkDialog::onPickColor()
93+
{
94+
QColor c = QColorDialog::getColor(markColor, this, tr("Pick Background Color"));
95+
if (c.isValid()) {
96+
markColor = c;
97+
ui->colorDisplay->setStyleSheet(colorToStyle(markColor));
98+
}
99+
}
100+
101+
QString MarkDialog::colorToStyle(const QColor &color)
102+
{
103+
return QString("background-color: rgba(%1, %2, %3, %4);")
104+
.arg(color.red())
105+
.arg(color.green())
106+
.arg(color.blue())
107+
.arg(MARK_ALPHA_F);
108+
}

src/dialogs/MarkDialog.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#ifndef MARKDIALOG_H
2+
#define MARKDIALOG_H
3+
4+
#include "CutterCommon.h"
5+
#include <QDialog>
6+
#include <QColor>
7+
8+
constexpr qreal MARK_ALPHA_F = 0.5; // 50% alpha to show blending of multiple overalapping marks
9+
10+
namespace Ui {
11+
class MarkDialog;
12+
}
13+
14+
class MarkDialog : public QDialog
15+
{
16+
Q_OBJECT
17+
18+
public:
19+
explicit MarkDialog(RVA from, RVA to, QWidget *parent = nullptr, QString name = {});
20+
~MarkDialog();
21+
22+
void accept() override;
23+
24+
private slots:
25+
void onPickColor();
26+
27+
private:
28+
std::unique_ptr<Ui::MarkDialog> ui;
29+
QString markName;
30+
RVA markFrom;
31+
RVA markTo;
32+
QColor markColor;
33+
QString markComment;
34+
bool edit;
35+
36+
static QString colorToStyle(const QColor &color);
37+
};
38+
39+
#endif // MARKDIALOG_H

0 commit comments

Comments
 (0)