mirror of
https://github.com/rizinorg/cutter
synced 2026-08-11 16:23:06 -04:00
Compare commits
146 commits
dev
...
v2.5.0-rc2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e9dc99554b | ||
|
|
2f053ddd6c | ||
|
|
31413d2d7e | ||
|
|
c71bb46310 | ||
|
|
d02c98355e | ||
|
|
cf8a5eeebd | ||
|
|
1e8f59f269 | ||
|
|
5324efc12a | ||
|
|
a419700f3a | ||
|
|
a5f88d10d1 | ||
|
|
e8874be001 | ||
|
|
48b3875b2e | ||
|
|
2a2fc759a5 | ||
|
|
6de8b8f491 | ||
|
|
192c2ac00d | ||
|
|
8692e63107 | ||
|
|
d6c3f3fe4c | ||
|
|
5c9203b7ec | ||
|
|
ec6a6fb142 | ||
|
|
9184085e4d | ||
|
|
7efb9b2ee3 | ||
|
|
7d88b0137e | ||
|
|
8fface0a4c | ||
|
|
de35babfd1 | ||
|
|
47813b55f6 | ||
|
|
209c26b862 | ||
|
|
90c1bf0826 | ||
|
|
efa29b63fa | ||
|
|
762830d4ac | ||
|
|
929466c668 | ||
|
|
807bbf4032 | ||
|
|
e612dcdf33 | ||
|
|
cbb0b805dc | ||
|
|
1d07ebc513 | ||
|
|
f39540fae4 | ||
|
|
9138967ed7 | ||
|
|
359bd91a21 | ||
|
|
2066a4b3e1 | ||
|
|
58f6c4d6e1 | ||
|
|
89f53bc073 | ||
|
|
fb4c2a1a17 | ||
|
|
ba2c9415a1 | ||
|
|
eeb2691e42 | ||
|
|
37fb67a86e | ||
|
|
48b35953bb | ||
|
|
351f27d955 | ||
|
|
f4be9a8266 | ||
|
|
dd216beb9c | ||
|
|
e523ac8365 | ||
|
|
9cbacff329 | ||
|
|
a96206e7ab | ||
|
|
4191a00965 | ||
|
|
b6e1778344 | ||
|
|
546999978e | ||
|
|
4f0d8f7e2b | ||
|
|
937c01a806 | ||
|
|
c0f260ca69 | ||
|
|
ef0d69b53a | ||
|
|
bc979211fe | ||
|
|
341d42c3a2 | ||
|
|
6995152366 | ||
|
|
8e232bed91 | ||
|
|
2475ffe1a1 | ||
|
|
dd4af7e8a0 | ||
|
|
be565f3a88 | ||
|
|
77b93fbab0 | ||
|
|
fd42ddb0bb | ||
|
|
181506cb1f | ||
|
|
39dc10a430 | ||
|
|
ba4f8a3024 | ||
|
|
a6dca2956d | ||
|
|
2529196df0 | ||
|
|
bd49557cab | ||
|
|
7eb4311c2b | ||
|
|
70bd668af1 | ||
|
|
c60a8ee134 | ||
|
|
e73a4c60e3 | ||
|
|
cf15a5761b | ||
|
|
ed47645405 | ||
|
|
f20b59d8ac | ||
|
|
a7d3eaffb0 | ||
|
|
84b33d50bd | ||
|
|
9e0e094bbb | ||
|
|
d2e2bcd6b6 | ||
|
|
05b771b8bb | ||
|
|
5fd55df710 | ||
|
|
544b904c2c | ||
|
|
266db132aa | ||
|
|
712709200a | ||
|
|
49cf6555a8 | ||
|
|
832dae38b4 | ||
|
|
575952d22e | ||
|
|
82f14b5667 | ||
|
|
b3e74b2dad | ||
|
|
ebe4ca5072 | ||
|
|
cf30b400f3 | ||
|
|
df8c2749a6 | ||
|
|
fb82370dfc | ||
|
|
6e07f4d97a | ||
|
|
493ff68365 | ||
|
|
6345604172 | ||
|
|
e022e44474 | ||
|
|
34b1f01a86 | ||
|
|
6fca09d313 | ||
|
|
7d42a5c7e6 | ||
|
|
a48399f73b | ||
|
|
cbda0ad27e | ||
|
|
5440a0ef50 | ||
|
|
12721aaa9e | ||
|
|
46ea1569d2 | ||
|
|
f8744d12c2 | ||
|
|
ae2ad5d50c | ||
|
|
6629d579c6 | ||
|
|
3e168fb76a | ||
|
|
085f5024b9 | ||
|
|
d65ad504ca | ||
|
|
0dc4e94647 | ||
|
|
b6288ecbf6 | ||
|
|
76c1ab894e | ||
|
|
8ace08b6e0 | ||
|
|
21ab0e2a9e | ||
|
|
7119017eae | ||
|
|
b884fe5f74 | ||
|
|
9d2404b486 | ||
|
|
f26f04b5fe | ||
|
|
b0c2dea772 | ||
|
|
518014ee19 | ||
|
|
ddaa02c0f8 | ||
|
|
c95a5d59a5 | ||
|
|
a4bc803eea | ||
|
|
cff49fa2a2 | ||
|
|
22cb8e7594 | ||
|
|
f7e6f9466d | ||
|
|
35408be46f | ||
|
|
cabe3ffb3e | ||
|
|
4f627e9bff | ||
|
|
453974da35 | ||
|
|
297b9bb192 | ||
|
|
893baea832 | ||
|
|
5c4ba4891d | ||
|
|
138078a6f4 | ||
|
|
98411b4dbf | ||
|
|
f5a7a79ee8 | ||
|
|
829f4091c5 | ||
|
|
7d50b80d44 | ||
|
|
7dfc289660 |
27 changed files with 262 additions and 932 deletions
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
|
|
@ -397,7 +397,7 @@ jobs:
|
|||
python-version: 3.12.x
|
||||
output-id: artifact_windows
|
||||
- name: macos-x86_64
|
||||
os: macos-15-intel # Must be an x86_64 image: https://github.com/actions/runner-images#available-images
|
||||
os: macos-14
|
||||
arch: x86_64
|
||||
package: true
|
||||
- name: macos-arm64
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ set(CUTTER_EXTRA_PLUGIN_DIRS "" CACHE STRING "List of addition plugin locations"
|
|||
option(CUTTER_ENABLE_DEPENDENCY_DOWNLOADS "Enable downloading of dependencies. Setting to OFF doesn't affect any downloads done by rizin build." OFF)
|
||||
option(CUTTER_ENABLE_PACKAGING "Enable building platform-specific packages for distributing" OFF)
|
||||
option(CUTTER_ENABLE_SIGDB "Downloads and installs sigdb (only available when CUTTER_USE_BUNDLED_RIZIN=ON)." OFF)
|
||||
option(CUTTER_ENABLE_TRANSLATIONS "Build and install translation files" ON)
|
||||
option(CUTTER_PACKAGE_DEPENDENCIES "During install step include the third party dependencies." OFF)
|
||||
option(CUTTER_PACKAGE_RZ_GHIDRA "Compile and install rz-ghidra during install step." OFF)
|
||||
option(CUTTER_PACKAGE_RZ_LIBSWIFT "Compile and install rz-libswift demangler during the install step." OFF)
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ endif()
|
|||
|
||||
# TODO: This version number should be fetched automatically
|
||||
# instead of being hardcoded.
|
||||
set (Rizin_VERSION 0.10)
|
||||
set (Rizin_VERSION 0.9)
|
||||
|
||||
set (RZ_LIBS rz_core rz_config rz_cons rz_io rz_util rz_flag rz_mark rz_arch rz_debug
|
||||
rz_hash rz_bin rz_lang rz_il rz_egg rz_reg rz_search rz_syscall
|
||||
|
|
|
|||
4
dist/CMakeLists.txt
vendored
4
dist/CMakeLists.txt
vendored
|
|
@ -201,9 +201,9 @@ if(CUTTER_PACKAGE_RZ_GHIDRA)
|
|||
# installed Cutter.
|
||||
ExternalProject_Add(rz-ghidra
|
||||
GIT_REPOSITORY https://github.com/rizinorg/rz-ghidra
|
||||
#GIT_TAG v0.3.0
|
||||
GIT_TAG v0.9.0
|
||||
#GIT_TAG c7a50a2e7c0a95cd52b167c9ee0fa1805223f08e
|
||||
GIT_TAG dev
|
||||
#GIT_TAG dev
|
||||
#GIT_SHALLOW ON # disable this line when using commit hash
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
|
|
|
|||
2
dist/bundle_jsdec.ps1
vendored
2
dist/bundle_jsdec.ps1
vendored
|
|
@ -4,7 +4,7 @@ $plugin_path = "$dist\plugins\native\"
|
|||
$pathdll = "$plugin_path\jsdec_cutter.dll"
|
||||
|
||||
if (-not (Test-Path -Path 'jsdec' -PathType Container)) {
|
||||
git clone https://github.com/rizinorg/jsdec.git --depth 1 --branch "dev"
|
||||
git clone https://github.com/rizinorg/jsdec.git --depth 1 --branch "v0.9.0"
|
||||
}
|
||||
cd jsdec
|
||||
$jsdecdir = (Get-Item .).FullName
|
||||
|
|
|
|||
2
dist/bundle_rz_libswift.ps1
vendored
2
dist/bundle_rz_libswift.ps1
vendored
|
|
@ -2,7 +2,7 @@ $dist = $args[0]
|
|||
$python = Split-Path((Get-Command python.exe).Path)
|
||||
|
||||
if (-not (Test-Path -Path 'libswift' -PathType Container)) {
|
||||
git clone https://github.com/rizinorg/rz-libswift.git --depth 1 libswift
|
||||
git clone https://github.com/rizinorg/rz-libswift.git --depth 1 --branch "v0.9.0" libswift
|
||||
}
|
||||
cd libswift
|
||||
& meson.exe --buildtype=release --prefix=$dist build
|
||||
|
|
|
|||
2
dist/bundle_rz_libyara.ps1
vendored
2
dist/bundle_rz_libyara.ps1
vendored
|
|
@ -3,7 +3,7 @@ $cmake_opts = $args[1]
|
|||
$python = Split-Path((Get-Command python.exe).Path)
|
||||
|
||||
if (-not (Test-Path -Path 'rz_libyara' -PathType Container)) {
|
||||
git clone https://github.com/rizinorg/rz-libyara.git --depth 1 --branch main rz_libyara
|
||||
git clone https://github.com/rizinorg/rz-libyara.git --depth 1 --branch "v0.9.0" rz_libyara
|
||||
git -C rz_libyara submodule init
|
||||
git -C rz_libyara submodule update
|
||||
}
|
||||
|
|
|
|||
2
dist/bundle_rz_silhouette.ps1
vendored
2
dist/bundle_rz_silhouette.ps1
vendored
|
|
@ -3,7 +3,7 @@ $cmake_opts = $args[1]
|
|||
$python = Split-Path((Get-Command python.exe).Path)
|
||||
|
||||
if (-not (Test-Path -Path 'rz-silhouette' -PathType Container)) {
|
||||
git clone https://github.com/rizinorg/rz-silhouette.git --depth 1 rz-silhouette
|
||||
git clone https://github.com/rizinorg/rz-silhouette.git --depth 1 --branch "v0.9.0-beta4" rz-silhouette
|
||||
}
|
||||
cd rz-silhouette
|
||||
& meson.exe --buildtype=release --prefix=$dist build
|
||||
|
|
|
|||
2
rizin
2
rizin
|
|
@ -1 +1 @@
|
|||
Subproject commit 136a337e1c40236723a58ccca6549aa577e8aaa5
|
||||
Subproject commit da228d11cfc865b06442bd66b192caeb6e5ff556
|
||||
|
|
@ -5,7 +5,7 @@ set -e
|
|||
cd $(dirname "${BASH_SOURCE[0]}")/..
|
||||
mkdir -p cutter-deps && cd cutter-deps
|
||||
|
||||
DEPS_BASE_URL=https://github.com/rizinorg/cutter-deps/releases/download/v19
|
||||
DEPS_BASE_URL=https://github.com/rizinorg/cutter-deps/releases/download/v18
|
||||
|
||||
if [ "$CUTTER_QT" == "5" ]; then
|
||||
DEPS_FILE_linux_x86_64=cutter-deps-q5-linux-x86_64.tar.gz
|
||||
|
|
@ -13,18 +13,18 @@ if [ "$CUTTER_QT" == "5" ]; then
|
|||
DEPS_BASE_URL=https://github.com/rizinorg/cutter-deps/releases/download/qt5-v17
|
||||
else
|
||||
DEPS_FILE_linux_x86_64=cutter-deps-linux-x86_64.tar.gz
|
||||
DEPS_SHA256_linux_x86_64=b4bebf95c69f6216456d31b345d660ae3347517a6c14a4a4e9d568b03289c3de
|
||||
DEPS_SHA256_linux_x86_64=204683c44e4824df7cb9925f1939544f081e64b7a701fe95fd03f67125a165b4
|
||||
fi
|
||||
echo $DEPS_SHA256_linux_x86_64
|
||||
|
||||
DEPS_FILE_macos_x86_64=cutter-deps-macos-x86_64.tar.gz
|
||||
DEPS_SHA256_macos_x86_64=6f202bd2b18cae780d4fe4ddce662909eebb4f0cd3f1c685e5b2bb6cd46a3e7d
|
||||
DEPS_SHA256_macos_x86_64=a46c2dee12d4160410237da848075fc87c41c3850021f583d3b469a59c386650
|
||||
|
||||
DEPS_FILE_macos_arm64=cutter-deps-macos-arm64.tar.gz
|
||||
DEPS_SHA256_macos_arm64=fa4b3c58f02e7b57a18c2fe7b8c196dd008187deda72fa1ae685c8ed661e10c6
|
||||
DEPS_SHA256_macos_arm64=1ca381b562d632a370e05a85b0fe60a591a261bba0f48d97a0e40b4307c2577a
|
||||
|
||||
DEPS_FILE_win_x86_64=cutter-deps-win-x86_64.tar.gz
|
||||
DEPS_SHA256_win_x86_64=3d69280bfedfdd3363fac450f814fc2f09cdd6149f60541dcdaa81f782c3ac76
|
||||
DEPS_SHA256_win_x86_64=95a3cf676178b8c58442d22ee8b21ce2530bfdae86f514901310490a8f28867a
|
||||
|
||||
|
||||
ARCH=x86_64
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ SCRIPTPATH=$(realpath "$(dirname "${BASH_SOURCE[0]}")")
|
|||
cd "$SCRIPTPATH/.."
|
||||
|
||||
if [ ! -d jsdec ]; then
|
||||
git clone https://github.com/rizinorg/jsdec.git --depth 1 --branch "dev"
|
||||
git clone https://github.com/rizinorg/jsdec.git --depth 1 --branch "v0.9.0"
|
||||
fi
|
||||
|
||||
cd jsdec
|
||||
|
|
|
|||
|
|
@ -108,17 +108,9 @@ resign_dmg() {
|
|||
notarize_bundle Cutter-rw/Cutter.app
|
||||
unmount
|
||||
trap - EXIT
|
||||
# Remove temporary signing space and restore HFS+ volume consistency.
|
||||
ee hdiutil resize -size min Cutter-rw.dmg
|
||||
OUTPUT="${1%.*}-signed.dmg"
|
||||
echo_step "Creating final read-only ${OUTPUT}"
|
||||
ee hdiutil convert -format UDZO -o "${OUTPUT}" Cutter-rw.dmg
|
||||
echo_step "Verifying filesystem in ${OUTPUT}"
|
||||
ee hdiutil attach "${OUTPUT}" -readonly -nobrowse -noautofsck -mountpoint Cutter-rw
|
||||
trap unmount EXIT
|
||||
ee diskutil verifyVolume Cutter-rw
|
||||
unmount
|
||||
trap - EXIT
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ SCRIPTPATH=$(realpath "$(dirname "${BASH_SOURCE[0]}")")
|
|||
cd "$SCRIPTPATH/.."
|
||||
|
||||
if [[ ! -d libswift ]]; then
|
||||
git clone https://github.com/rizinorg/rz-libswift.git --depth 1 libswift
|
||||
git clone https://github.com/rizinorg/rz-libswift.git --depth 1 --branch "v0.9.0" libswift
|
||||
fi
|
||||
|
||||
cd libswift
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ EXTRA_CMAKE_OPTS="$2"
|
|||
cd "$SCRIPTPATH/.."
|
||||
|
||||
if [[ ! -d rz_libyara ]]; then
|
||||
git clone https://github.com/rizinorg/rz-libyara.git --depth 1 --branch main rz_libyara
|
||||
git clone https://github.com/rizinorg/rz-libyara.git --depth 1 --branch "v0.9.0" rz_libyara
|
||||
git -C rz_libyara submodule init
|
||||
git -C rz_libyara submodule update
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ EXTRA_CMAKE_OPTS="$2"
|
|||
cd "$SCRIPTPATH/.."
|
||||
|
||||
if [[ ! -d rz-silhouette ]]; then
|
||||
git clone https://github.com/rizinorg/rz-silhouette.git --depth 1 rz-silhouette
|
||||
git clone https://github.com/rizinorg/rz-silhouette.git --depth 1 --branch "v0.9.0-beta4" rz-silhouette
|
||||
fi
|
||||
|
||||
cd rz-silhouette
|
||||
|
|
|
|||
|
|
@ -613,9 +613,7 @@ if(CUTTER_ENABLE_PACKAGING)
|
|||
target_compile_definitions(Cutter PRIVATE CUTTER_ENABLE_PACKAGING)
|
||||
endif()
|
||||
|
||||
if(CUTTER_ENABLE_TRANSLATIONS)
|
||||
include(Translations)
|
||||
endif()
|
||||
include(Translations)
|
||||
|
||||
# Install files
|
||||
install(TARGETS Cutter
|
||||
|
|
|
|||
|
|
@ -4,55 +4,19 @@
|
|||
|
||||
#include <QAbstractButton>
|
||||
#include <QAbstractItemView>
|
||||
#include <QAbstractTextDocumentLayout>
|
||||
#include <QComboBox>
|
||||
#include <QCryptographicHash>
|
||||
#include <QDockWidget>
|
||||
#include <QFileInfo>
|
||||
#include <QFontMetricsF>
|
||||
#include <QMenu>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QString>
|
||||
#include <QTextBlock>
|
||||
#include <QTextEdit>
|
||||
#include <QTreeWidget>
|
||||
#include <QtCore>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace {
|
||||
template<typename TextEditType>
|
||||
int calculateMaxDisplayedLines(TextEditType *textEdit)
|
||||
{
|
||||
qreal lineHeight = 0;
|
||||
const QTextBlock firstBlock = textEdit->document()->begin();
|
||||
if (firstBlock.isValid()) {
|
||||
lineHeight = textEdit->document()->documentLayout()->blockBoundingRect(firstBlock).height();
|
||||
}
|
||||
|
||||
if (lineHeight <= 0) {
|
||||
const QFontMetricsF fm(textEdit->font());
|
||||
lineHeight = fm.lineSpacing();
|
||||
}
|
||||
|
||||
qreal availableHeight = textEdit->viewport()->height();
|
||||
const qreal margin = textEdit->document()->documentMargin();
|
||||
availableHeight -= margin;
|
||||
|
||||
const qreal exactLines = availableHeight / lineHeight;
|
||||
const qreal floorValue = std::floor(exactLines);
|
||||
const qreal fractionalPart = exactLines - floorValue;
|
||||
|
||||
// If the last line is more than 15% visible then count it, otherwise leave it
|
||||
// avoids the issue where there is empty space at the bottom of a textedit widget
|
||||
if (fractionalPart >= 0.15) {
|
||||
return std::ceil(availableHeight / lineHeight);
|
||||
}
|
||||
|
||||
return floorValue;
|
||||
}
|
||||
}
|
||||
|
||||
namespace qhelpers {
|
||||
|
||||
QString formatByteCount(ut64 bytecount)
|
||||
|
|
@ -210,12 +174,20 @@ void SizePolicyMinMax::restoreHeight(QWidget *widget) const
|
|||
|
||||
int getMaxFullyDisplayedLines(QTextEdit *textEdit)
|
||||
{
|
||||
return calculateMaxDisplayedLines(textEdit);
|
||||
const QFontMetrics fontMetrics(textEdit->document()->defaultFont());
|
||||
return (textEdit->height()
|
||||
- (textEdit->contentsMargins().top() + textEdit->contentsMargins().bottom()
|
||||
+ (int)(textEdit->document()->documentMargin() * 2)))
|
||||
/ fontMetrics.lineSpacing();
|
||||
}
|
||||
|
||||
int getMaxFullyDisplayedLines(QPlainTextEdit *plainTextEdit)
|
||||
{
|
||||
return calculateMaxDisplayedLines(plainTextEdit);
|
||||
const QFontMetrics fontMetrics(plainTextEdit->document()->defaultFont());
|
||||
return (plainTextEdit->height()
|
||||
- (plainTextEdit->contentsMargins().top() + plainTextEdit->contentsMargins().bottom()
|
||||
+ (int)(plainTextEdit->document()->documentMargin() * 2)))
|
||||
/ fontMetrics.lineSpacing();
|
||||
}
|
||||
|
||||
QByteArray applyColorToSvg(const QByteArray &data, QColor color)
|
||||
|
|
|
|||
|
|
@ -1187,15 +1187,19 @@ void CutterCore::setConfig(const char *k, const RzInterval &itv)
|
|||
void CutterCore::setConfig(const char *k, const QStringList &list)
|
||||
{
|
||||
CORE_LOCK();
|
||||
RzSetS *set = rz_set_s_new(HT_STR_DUP);
|
||||
if (!set) {
|
||||
RzList *rzList = rz_list_newf(free);
|
||||
if (!rzList) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const QString &str : list) {
|
||||
rz_set_s_add(set, str.toUtf8().constData());
|
||||
char *dupStr = strdup(str.toUtf8().constData());
|
||||
if (dupStr) {
|
||||
rz_list_append(rzList, dupStr);
|
||||
}
|
||||
}
|
||||
rz_config_set_set(core->config, k, set);
|
||||
rz_set_s_free(set);
|
||||
|
||||
rz_config_set_list(core->config, k, rzList);
|
||||
}
|
||||
|
||||
int CutterCore::getConfigi(const char *k)
|
||||
|
|
@ -1222,12 +1226,16 @@ RzInterval CutterCore::getConfigItv(const char *k)
|
|||
return rz_config_get_interval(core->config, k);
|
||||
}
|
||||
|
||||
QSet<QString> CutterCore::getConfigSet(const char *k)
|
||||
QStringList CutterCore::getConfigList(const char *k)
|
||||
{
|
||||
CORE_LOCK();
|
||||
RzSetS *set = rz_config_get_set(core->config, k);
|
||||
QSet<QString> res = convertRzSetS(set);
|
||||
rz_set_s_free(set);
|
||||
|
||||
QStringList res;
|
||||
RzList *list = rz_config_get_list(core->config, k);
|
||||
for (const auto *s : CutterRzList<const char>(list)) {
|
||||
res << QString::fromUtf8(s);
|
||||
}
|
||||
rz_list_free(list);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -1287,18 +1295,18 @@ QString CutterCore::getConfig(const char *k)
|
|||
return { rz_config_get(core->config, k) };
|
||||
}
|
||||
|
||||
QSet<QString> CutterCore::getConfigOptions(const char *k)
|
||||
QStringList CutterCore::getConfigOptions(const char *k)
|
||||
{
|
||||
CORE_LOCK();
|
||||
const RzConfigNode *node = rz_config_node_get(core->config, k);
|
||||
if (!(node && node->options)) {
|
||||
return {};
|
||||
}
|
||||
QSet<QString> res;
|
||||
for (auto it = CutterRzIter<const char *>(rz_set_s_as_iter(node->options)); it; ++it) {
|
||||
res << QString::fromUtf8(*it);
|
||||
QStringList list;
|
||||
for (const auto &s : CutterRzList<char>(node->options)) {
|
||||
list << s;
|
||||
}
|
||||
return res;
|
||||
return list;
|
||||
}
|
||||
|
||||
void CutterCore::setConfig(const char *k, const QVariant &v)
|
||||
|
|
@ -4146,11 +4154,13 @@ QList<EvaluableVarDescription> CutterCore::getAllEvaluableVars()
|
|||
var.type = EvaluableVarDescription::Interval;
|
||||
const RzInterval itv = rz_config_var_get_interval(v);
|
||||
value = QVariant::fromValue(itv);
|
||||
} else if (RZ_CONFIG_VAR_IS_TYPE(flags, RZ_CONFIG_VAR_TYPE_SET)) {
|
||||
var.type = EvaluableVarDescription::Set;
|
||||
RzSetS *set = rz_config_var_get_set(v);
|
||||
value = QVariant::fromValue(convertRzSetS(set));
|
||||
rz_set_s_free(set);
|
||||
} else if (RZ_CONFIG_VAR_IS_TYPE(flags, RZ_CONFIG_VAR_TYPE_LIST)) {
|
||||
var.type = EvaluableVarDescription::List;
|
||||
const RzList *list = rz_config_var_get_list(v);
|
||||
QStringList stringList;
|
||||
for (const auto *c : CutterRzList<const char>(list)) {
|
||||
stringList << QString(c);
|
||||
}
|
||||
}
|
||||
|
||||
if (value.isNull()) {
|
||||
|
|
@ -4158,9 +4168,13 @@ QList<EvaluableVarDescription> CutterCore::getAllEvaluableVars()
|
|||
}
|
||||
var.value = value;
|
||||
|
||||
const RzSetS *optionsSet = rz_config_var_get_options(v);
|
||||
if (optionsSet) {
|
||||
var.options = convertRzSetS(optionsSet);
|
||||
const RzList *optionsList = rz_config_var_get_options(v);
|
||||
if (optionsList) {
|
||||
RzListIter *iter;
|
||||
char *option;
|
||||
CutterRzListForeach (optionsList, iter, char, option) {
|
||||
var.options << QString::fromUtf8(option);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const RzConfigNode *node = &entry->node;
|
||||
|
|
@ -4175,8 +4189,10 @@ QList<EvaluableVarDescription> CutterCore::getAllEvaluableVars()
|
|||
|
||||
var.value = QString::fromUtf8(rz_config_entry_get_as_string(entry));
|
||||
|
||||
if (node->options) {
|
||||
var.options = convertRzSetS(node->options);
|
||||
RzListIter *iter;
|
||||
char *option;
|
||||
CutterRzListForeach (node->options, iter, char, option) {
|
||||
var.options << QString::fromUtf8(option);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -495,12 +495,12 @@ public:
|
|||
bool getConfigb(const QString &k) { return getConfigb(k.toUtf8().constData()); }
|
||||
RzInterval getConfigItv(const char *k);
|
||||
RzInterval getConfigItv(const QString &k) { return getConfigItv(k.toUtf8().constData()); }
|
||||
QSet<QString> getConfigSet(const char *k);
|
||||
QSet<QString> getConfigSet(const QString &k) { return getConfigSet(k.toUtf8().constData()); }
|
||||
QStringList getConfigList(const char *k);
|
||||
QStringList getConfigList(const QString &k) { return getConfigList(k.toUtf8().constData()); }
|
||||
QString getConfig(const char *k);
|
||||
QString getConfig(const QString &k) { return getConfig(k.toUtf8().constData()); }
|
||||
QString getConfigDescription(const char *k);
|
||||
QSet<QString> getConfigOptions(const char *k);
|
||||
QStringList getConfigOptions(const char *k);
|
||||
QStringList getColorThemes();
|
||||
QHash<QString, QColor> getTheme();
|
||||
QStringList getThemeKeys();
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@
|
|||
#include <QColor>
|
||||
#include <QList>
|
||||
#include <QMetaType>
|
||||
#include <QSet>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QVariant>
|
||||
|
||||
struct FunctionDescription
|
||||
|
|
@ -448,11 +448,11 @@ struct EvaluableVarDescription
|
|||
QString description;
|
||||
bool readOnly;
|
||||
|
||||
enum Type : ut8 { Bool = 0, Int, String, Interval, Set };
|
||||
enum Type : ut8 { Bool = 0, Int, String, Interval, List };
|
||||
Type type;
|
||||
|
||||
QVariant value; ///< Can be either QString, QSet<QString> or RzInterval depending on type
|
||||
QSet<QString> options;
|
||||
QVariant value; ///< Can be either QString, QStringList or RzInterval depending on type
|
||||
QList<QString> options;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(FunctionDescription)
|
||||
|
|
|
|||
|
|
@ -1,12 +1 @@
|
|||
#include "RizinCpp.h"
|
||||
|
||||
#include <QSet>
|
||||
|
||||
QSet<QString> convertRzSetS(const RzSetS *set)
|
||||
{
|
||||
QSet<QString> res;
|
||||
for (auto it = CutterRzIter<const char *>(rz_set_s_as_iter(set)); it; ++it) {
|
||||
res << QString::fromUtf8(*it);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -187,9 +187,9 @@ public:
|
|||
return *this;
|
||||
}
|
||||
operator bool() { return rzIter && rzIter->cur; }
|
||||
T &operator*() { return *reinterpret_cast<T *>(rzIter->cur); }
|
||||
T *get() { return reinterpret_cast<T *>(rzIter->cur); }
|
||||
T *operator->() { return reinterpret_cast<T *>(rzIter->cur); }
|
||||
T &operator*() { return *reinterpret_cast<RzCoreDecodedBytes *>(rzIter->cur); }
|
||||
T *get() { return reinterpret_cast<RzCoreDecodedBytes *>(rzIter->cur); }
|
||||
T *operator->() { return reinterpret_cast<RzCoreDecodedBytes *>(rzIter->cur); }
|
||||
};
|
||||
|
||||
#define CutterHtDef(xx, XX, K, VB) \
|
||||
|
|
@ -219,6 +219,4 @@ public:
|
|||
|
||||
CutterHtDef(sp, SP, const char *, void *);
|
||||
|
||||
QSet<QString> convertRzSetS(const RzSetS *set);
|
||||
|
||||
#endif // RIZINCPP_H
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ QVariant RizinConfigOptionsModel::data(const QModelIndex &index, int role) const
|
|||
const auto itv = evalVar.value.value<RzInterval>();
|
||||
return QString("%1+%2").arg(rzAddressString(itv.addr), rzSizeString(itv.size));
|
||||
}
|
||||
if (evalVar.type == EvaluableVarDescription::Set) {
|
||||
if (evalVar.type == EvaluableVarDescription::List) {
|
||||
const QStringList list = evalVar.value.toStringList();
|
||||
if (list.isEmpty()) {
|
||||
return QString();
|
||||
|
|
@ -344,16 +344,14 @@ QWidget *RizinConfigOptionsDelegate::createEditor(QWidget *parent,
|
|||
|
||||
if (evalVar.type == EvaluableVarDescription::Bool
|
||||
|| evalVar.type == EvaluableVarDescription::Interval
|
||||
|| evalVar.type == EvaluableVarDescription::Set) {
|
||||
|| evalVar.type == EvaluableVarDescription::List) {
|
||||
// handled in lambda connected to ui->treeView::doubleClicked
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!evalVar.options.isEmpty()) {
|
||||
auto *comboBox = new QComboBox(parent);
|
||||
QStringList opts = evalVar.options.values();
|
||||
opts.sort();
|
||||
for (const auto &opt : opts) {
|
||||
for (const auto &opt : evalVar.options) {
|
||||
comboBox->addItem(opt);
|
||||
}
|
||||
return comboBox;
|
||||
|
|
@ -488,7 +486,7 @@ RizinConfigOptionsWidget::RizinConfigOptionsWidget(PreferencesDialog *parent)
|
|||
return;
|
||||
}
|
||||
|
||||
if (evalVar.type == EvaluableVarDescription::Set) {
|
||||
if (evalVar.type == EvaluableVarDescription::List) {
|
||||
StringListDialog dialog(evalVar.value.toStringList(), this);
|
||||
dialog.setWindowTitle(tr("Edit List for %1").arg(evalVar.name));
|
||||
|
||||
|
|
@ -598,8 +596,8 @@ void RizinConfigOptionsWidget::handleConfigOptionChanged(const QModelIndex &topL
|
|||
if (!originalValues.contains(evalVar.name)) {
|
||||
if (evalVar.type == EvaluableVarDescription::Interval) {
|
||||
originalValues[evalVar.name] = QVariant::fromValue(Core()->getConfigItv(evalVar.name));
|
||||
} else if (evalVar.type == EvaluableVarDescription::Set) {
|
||||
originalValues[evalVar.name] = QVariant::fromValue(Core()->getConfigSet(evalVar.name));
|
||||
} else if (evalVar.type == EvaluableVarDescription::List) {
|
||||
originalValues[evalVar.name] = QVariant::fromValue(Core()->getConfigList(evalVar.name));
|
||||
} else {
|
||||
originalValues[evalVar.name] = Core()->getConfig(evalVar.name);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -215,10 +215,6 @@ const QHash<QString, Shortcut> &getDefaultShortcuts()
|
|||
{ { Qt::Key_Space },
|
||||
QT_TRANSLATE_NOOP("DisassemblyWidget", "Switch to Graph"),
|
||||
"DisassemblyWidget" } },
|
||||
{ "Disassembly.moveLeft",
|
||||
{ QList<QKeySequence> { Qt::Key_H }
|
||||
+ QKeySequence::keyBindings(QKeySequence::MoveToPreviousChar),
|
||||
QT_TRANSLATE_NOOP("DisassemblyWidget", "Move Cursor Down"), "DisassemblyWidget" } },
|
||||
{ "Disassembly.moveDown",
|
||||
{ QList<QKeySequence> { Qt::Key_J }
|
||||
+ QKeySequence::keyBindings(QKeySequence::MoveToNextLine),
|
||||
|
|
@ -227,10 +223,6 @@ const QHash<QString, Shortcut> &getDefaultShortcuts()
|
|||
{ QList<QKeySequence> { Qt::Key_K }
|
||||
+ QKeySequence::keyBindings(QKeySequence::MoveToPreviousLine),
|
||||
QT_TRANSLATE_NOOP("DisassemblyWidget", "Move Cursor Up"), "DisassemblyWidget" } },
|
||||
{ "Disassembly.moveRight",
|
||||
{ QList<QKeySequence> { Qt::Key_L }
|
||||
+ QKeySequence::keyBindings(QKeySequence::MoveToNextChar),
|
||||
QT_TRANSLATE_NOOP("DisassemblyWidget", "Move Cursor Up"), "DisassemblyWidget" } },
|
||||
{ "Disassembly.pageDown",
|
||||
{ QKeySequence::keyBindings(QKeySequence::MoveToNextPage),
|
||||
QT_TRANSLATE_NOOP("DisassemblyWidget", "Move Cursor Down By Page"),
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -19,8 +19,6 @@ class DisassemblyContextMenu;
|
|||
class DisassemblyLeftPanel;
|
||||
class AddressRangeScrollBar;
|
||||
|
||||
enum class RefreshMode : ut8 { Append, Prepend, Reset, Keep, None };
|
||||
|
||||
/**
|
||||
* @brief Main widget for showing disassembly of a binary
|
||||
*
|
||||
|
|
@ -35,67 +33,48 @@ public:
|
|||
|
||||
static QString getWidgetType();
|
||||
|
||||
QFontMetricsF getFontMetrics();
|
||||
QList<DisassemblyLine> getLines();
|
||||
|
||||
int getStartIndex() const;
|
||||
int getEndIndex() const;
|
||||
|
||||
/**
|
||||
* @brief Updates the offset and character position where the cursor selection ends
|
||||
*/
|
||||
void updateSelectionPos(const QTextCursor &cursor);
|
||||
|
||||
/**
|
||||
* @brief Updates the offset and character position where the cursor selection starts
|
||||
*/
|
||||
void updateSelectionAnchor(const QTextCursor &cursor);
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* @brief Highlights the currently selected line and updates the
|
||||
* highlighting of the same words under the cursor in the visible screen.
|
||||
* @return List of selections to be highlighted
|
||||
* This overrides all previous highlighting.
|
||||
*/
|
||||
QList<QTextEdit::ExtraSelection> highlightCurrentLine();
|
||||
void highlightCurrentLine();
|
||||
/**
|
||||
* @brief Adds the PC line highlighting to the other current highlighting.
|
||||
* This is generally called after highlightCurrentLine
|
||||
* @return List of selections to be highlighted
|
||||
* This should be called after highlightCurrentLine since that function
|
||||
* overrides all previous highlighting.
|
||||
*/
|
||||
QList<QTextEdit::ExtraSelection> highlightPCLine();
|
||||
void highlightPCLine();
|
||||
void showDisasContextMenu(const QPoint &pt);
|
||||
void fontsUpdatedSlot();
|
||||
void colorsUpdatedSlot();
|
||||
void scrollInstructions(int count, bool clampToScrollBarRange = false);
|
||||
void seekPrev();
|
||||
void setPreviewMode(bool previewMode);
|
||||
QFontMetricsF getFontMetrics();
|
||||
QList<DisassemblyLine> getLines();
|
||||
|
||||
/**
|
||||
* @brief Forces the transient vertical scrollbar to appear on scroll
|
||||
*/
|
||||
void showTransientScrollBar();
|
||||
|
||||
void refreshDisasm(RVA offset = RVA_INVALID, RefreshMode mode = RefreshMode::Reset);
|
||||
|
||||
protected slots:
|
||||
void onSeekChanged(RVA offset, CutterCore::SeekHistoryType type);
|
||||
void refreshIfInRange(RVA offset);
|
||||
void instructionChanged(RVA offset);
|
||||
void refreshDisasm(RVA offset = RVA_INVALID);
|
||||
|
||||
bool updateMaxLines();
|
||||
|
||||
void cursorPositionChanged();
|
||||
/**
|
||||
* @brief Copies the currently highlighted disassembly text to the system clipboard
|
||||
*/
|
||||
void copySelection();
|
||||
|
||||
protected:
|
||||
DisassemblyContextMenu *mCtxMenu;
|
||||
DisassemblyScrollArea *mDisasScrollArea;
|
||||
DisassemblyTextEdit *mDisasTextEdit;
|
||||
DisassemblyLeftPanel *leftPanel;
|
||||
QList<DisassemblyLine> lines;
|
||||
|
||||
private:
|
||||
RVA topOffset;
|
||||
|
|
@ -122,31 +101,7 @@ private:
|
|||
int topOffsetHistoryPos = 0;
|
||||
QList<RVA> topOffsetHistory;
|
||||
|
||||
int startIndex = 0;
|
||||
int endIndex = 0;
|
||||
QList<DisassemblyLine> lines;
|
||||
|
||||
// Cursor selection related
|
||||
RVA selectionAnchorRVA = RVA_INVALID;
|
||||
/**
|
||||
* @brief metadata lines attached to instruction have the same offset as the instruction itself,
|
||||
* this keeps track of which metdata line the cursor was at inside the offset block
|
||||
*/
|
||||
int selectionAnchorSubIndex = 0;
|
||||
int selectionAnchorChar = 0;
|
||||
RVA selectionPosRVA = RVA_INVALID;
|
||||
/**
|
||||
* @brief same use-case as @ref selectionAnchorSubIndex but for cursor position instead if
|
||||
* anchor
|
||||
*/
|
||||
int selectionPosSubIndex = 0;
|
||||
int selectionPosChar = 0;
|
||||
|
||||
QList<RVA> breakpoints;
|
||||
/**
|
||||
* @brief Set whenever breakpoints have been updated or the screen has been manually refreshed
|
||||
*/
|
||||
bool breakpointsDirty = true;
|
||||
|
||||
void setupFonts();
|
||||
void setupColors();
|
||||
|
|
@ -155,53 +110,9 @@ private:
|
|||
|
||||
void connectCursorPositionChanged(bool disconnect);
|
||||
|
||||
void moveCursorRelative(QTextCursor::MoveOperation op, bool page);
|
||||
void moveCursorRelative(bool up, bool page);
|
||||
|
||||
void jumpToOffsetUnderCursor(const QTextCursor &);
|
||||
|
||||
/**
|
||||
* @brief Visually highlights the text on screen between the selection start (anchor) and the
|
||||
* current cursor position
|
||||
*/
|
||||
void updateSelection();
|
||||
void updateContextMenuSelection(bool hasSelection);
|
||||
|
||||
/**
|
||||
* @brief Finds the visual line number in the current view for a specific offset
|
||||
* @param offset The memory address (RVA) to look for
|
||||
* @param offsetSubIndex The specific sub-line to target if the instructions has metadata
|
||||
* attached to it
|
||||
* @return The index of the line, or -1 if not found
|
||||
*
|
||||
* @see DisassemblyHelper::getIndexInOffsetGroup()
|
||||
*/
|
||||
int getLineIndex(RVA offset, int offsetSubIndex) const;
|
||||
/**
|
||||
* @brief Refreshes the background colors in the disassembly view.
|
||||
* It applies highlights to both the line currently under the user's cursor and the Program
|
||||
* Counter (PC) line.
|
||||
*/
|
||||
void updateLineHighlights();
|
||||
/**
|
||||
* @brief Clears the current text selection so nothing is highlighted as selected
|
||||
*/
|
||||
void invalidateCursorSelection();
|
||||
|
||||
/**
|
||||
* @brief Metadata lines attached to an instruction have the same offset saved with it as the
|
||||
* instruction, This function returns the index of the current line within that offset
|
||||
* group/block
|
||||
* * e.g:
|
||||
* * @code
|
||||
* ; a comment
|
||||
* ; another comment <------ assume cursor is here
|
||||
* ; void func1()
|
||||
* 0x1000 mov rax, rax
|
||||
* @endcode
|
||||
*
|
||||
* Then the returned index is "1"
|
||||
*/
|
||||
int getIndexInOffsetGroup(const QTextCursor &cursor) const;
|
||||
};
|
||||
|
||||
class DisassemblyScrollArea : public QAbstractScrollArea
|
||||
|
|
@ -231,30 +142,23 @@ class DisassemblyTextEdit : public QPlainTextEdit
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DisassemblyTextEdit(DisassemblyWidget *disasmWidget = nullptr);
|
||||
explicit DisassemblyTextEdit(QWidget *parent = nullptr)
|
||||
: QPlainTextEdit(parent), lockScroll(false)
|
||||
{
|
||||
}
|
||||
|
||||
void setLockScroll(bool lock) { this->lockScroll = lock; }
|
||||
|
||||
qreal textOffset() const;
|
||||
|
||||
void setCursorVisible(bool visible);
|
||||
|
||||
protected:
|
||||
bool viewportEvent(QEvent *event) override;
|
||||
void scrollContentsBy(int dx, int dy) override;
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
void mouseMoveEvent(QMouseEvent *event) override;
|
||||
|
||||
private:
|
||||
bool lockScroll;
|
||||
QTimer *blinkTimer;
|
||||
bool cursorVisible = true;
|
||||
QColor cursorColor;
|
||||
|
||||
DisassemblyWidget *disasmWidget = nullptr;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -349,16 +349,13 @@ void GraphView::paint(QPainter &p, QPoint offset, QRect viewport, qreal scale, b
|
|||
|
||||
p.setBrush(Qt::gray);
|
||||
|
||||
// Always draw edges
|
||||
// TODO: Only draw edges if they are actually visible ...
|
||||
// Draw edges
|
||||
for (GraphEdge &edge : block.edges) {
|
||||
if (edge.polyline.empty()) {
|
||||
continue;
|
||||
}
|
||||
// Skips expensive polyline and arrow rendering if the edge's bounding box
|
||||
// is completely outside the current viewport.
|
||||
if (!edge.polyline.boundingRect().adjusted(-1, -1, 1, 1).intersects(windowF)) {
|
||||
continue;
|
||||
}
|
||||
const QPolygonF polyline = edge.polyline;
|
||||
const EdgeConfiguration ec =
|
||||
edgeConfiguration(block, &blocks[edge.target], interactive);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue