Skip to content

Commit b3a1828

Browse files
authored
Merge pull request #121 from Mahlet-Inc/develop
Merge in some kaitai fixes and improvements
2 parents 8bfb997 + e81e2ce commit b3a1828

File tree

14 files changed

+298
-133
lines changed

14 files changed

+298
-133
lines changed

docs/hobbits_screenshot.png

-152 KB
Loading

src/hobbits-core/bitarray.cpp

+10-4
Original file line numberDiff line numberDiff line change
@@ -702,7 +702,7 @@ QByteArray BitArray::readBytesNoSync(qint64 byteOffset, qint64 maxBytes) const
702702
return m_dataFile.read(maxBytes);
703703
}
704704

705-
QSharedPointer<BitArray> BitArray::fromString(QString bitArraySpec, QStringList parseErrors)
705+
QSharedPointer<BitArray> BitArray::fromString(QString bitArraySpec, QStringList *parseErrors)
706706
{
707707
int size = 0;
708708
if (bitArraySpec.startsWith("0x")) {
@@ -718,7 +718,9 @@ QSharedPointer<BitArray> BitArray::fromString(QString bitArraySpec, QStringList
718718
return QSharedPointer<BitArray>(new BitArray(bytes, size));
719719
}
720720
else {
721-
parseErrors.append(QString("Expected only hex digits in '0x'-prefixed data - got '%1'").arg(bitArraySpec));
721+
if (parseErrors != nullptr) {
722+
parseErrors->append(QString("Expected only hex digits in '0x'-prefixed data - got '%1'").arg(bitArraySpec));
723+
}
722724
return QSharedPointer<BitArray>(new BitArray());
723725
}
724726
}
@@ -731,10 +733,12 @@ QSharedPointer<BitArray> BitArray::fromString(QString bitArraySpec, QStringList
731733
int val = bitArraySpec.mid(i, 1).toInt(&parseOk, 8);
732734

733735
if (!parseOk) {
734-
parseErrors.append(
736+
if (parseErrors != nullptr) {
737+
parseErrors->append(
735738
QString("Expected octal digit in '0o'-prefixed data - got %1").arg(
736739
bitArraySpec.at(
737740
i)));
741+
}
738742
continue;
739743
}
740744

@@ -752,8 +756,10 @@ QSharedPointer<BitArray> BitArray::fromString(QString bitArraySpec, QStringList
752756
bits->set(i - 2, true);
753757
}
754758
else if (bitArraySpec.at(i) != '0') {
755-
parseErrors.append(
759+
if (parseErrors != nullptr) {
760+
parseErrors->append(
756761
QString("Expected '1' or '0' in '0b'-prefixed data - got '%1'").arg(bitArraySpec.at(i)));
762+
}
757763
}
758764
}
759765
return bits;

src/hobbits-core/bitarray.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class HOBBITSCORESHARED_EXPORT BitArray
6969
static BitArray* deserialize(QDataStream &stream);
7070
void serialize(QDataStream &stream) const;
7171

72-
static QSharedPointer<BitArray> fromString(QString bitArraySpec, QStringList parseErrors = QStringList());
72+
static QSharedPointer<BitArray> fromString(QString bitArraySpec, QStringList *parseErrors = nullptr);
7373

7474
private:
7575
void writeToStream(QDataStream &dataStream) const; // private for use by serializer and writeTo

src/hobbits-core/rangehighlight.cpp

+20-8
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
#include "rangehighlight.h"
22

3-
RangeHighlight::RangeHighlight(QString category, QString label, Range range, quint32 color, QList<RangeHighlight> children) :
3+
RangeHighlight::RangeHighlight(QString category, QString label, Range range, quint32 color, QList<RangeHighlight> children, QStringList tags) :
44
m_category(category),
55
m_label(label),
66
m_range(range),
77
m_color(color),
8-
m_children(children)
8+
m_children(children),
9+
m_tags(tags)
910
{
1011

1112
}
1213

13-
RangeHighlight::RangeHighlight(QString category, QString label, QList<RangeHighlight> children, quint32 color) :
14+
RangeHighlight::RangeHighlight(QString category, QString label, QList<RangeHighlight> children, quint32 color, QStringList tags) :
1415
m_category(category),
1516
m_label(label),
1617
m_color(color),
17-
m_children(children)
18+
m_children(children),
19+
m_tags(tags)
1820
{
1921
std::sort(m_children.begin(), m_children.end());
2022
if (m_children.isEmpty()) {
@@ -23,9 +25,9 @@ RangeHighlight::RangeHighlight(QString category, QString label, QList<RangeHighl
2325
m_range = Range(m_children.first().range().start(), m_children.last().range().end());
2426
}
2527

26-
RangeHighlight RangeHighlight::simple(QString category, QString label, Range range, quint32 color)
28+
RangeHighlight RangeHighlight::simple(QString category, QString label, Range range, quint32 color, QStringList tags)
2729
{
28-
return RangeHighlight(category, label, range, color);
30+
return RangeHighlight(category, label, range, color, {}, tags);
2931
}
3032

3133
bool operator<(const RangeHighlight &a, const RangeHighlight &b)
@@ -68,30 +70,40 @@ QList<RangeHighlight> RangeHighlight::allDescendants() const
6870
return all;
6971
}
7072

73+
QStringList RangeHighlight::tags() const
74+
{
75+
return m_tags;
76+
}
77+
7178
const QString VERSION_1 = "RangeHighlight v1";
7279
const QString VERSION_2 = "RangeHighlight v2";
7380
const QString VERSION_3 = "RangeHighlight v3";
81+
const QString VERSION_4 = "RHv4";
7482
QDataStream& operator<<(QDataStream& stream, const RangeHighlight& highlight)
7583
{
76-
stream << VERSION_3;
84+
stream << VERSION_4;
7785
stream << highlight.category();
7886
stream << highlight.label();
7987
stream << highlight.range();
8088
stream << highlight.color();
8189
stream << highlight.children();
90+
stream << highlight.tags();
8291
return stream;
8392
}
8493

8594
QDataStream& operator>>(QDataStream& stream, RangeHighlight& highlight)
8695
{
8796
QString version;
8897
stream >> version;
89-
if (version == VERSION_3) {
98+
if (version == VERSION_3 || version == VERSION_4) {
9099
stream >> highlight.m_category;
91100
stream >> highlight.m_label;
92101
stream >> highlight.m_range;
93102
stream >> highlight.m_color;
94103
stream >> highlight.m_children;
104+
if (version == VERSION_4) {
105+
stream >> highlight.m_tags;
106+
}
95107
return stream;
96108
}
97109
else {

src/hobbits-core/rangehighlight.h

+5-3
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,18 @@ class HOBBITSCORESHARED_EXPORT RangeHighlight
1818
RangeHighlight(const RangeHighlight &) = default;
1919
RangeHighlight &operator=(const RangeHighlight &) = default;
2020

21-
RangeHighlight(QString category, QString label, Range range, quint32 color, QList<RangeHighlight> children = {});
22-
RangeHighlight(QString category, QString label, QList<RangeHighlight> children, quint32 color);
21+
RangeHighlight(QString category, QString label, Range range, quint32 color, QList<RangeHighlight> children = {}, QStringList tags = {});
22+
RangeHighlight(QString category, QString label, QList<RangeHighlight> children, quint32 color, QStringList tags = {});
2323

24-
static RangeHighlight simple(QString category, QString label, Range range, quint32 color);
24+
static RangeHighlight simple(QString category, QString label, Range range, quint32 color, QStringList tags = {});
2525

2626
QString label() const;
2727
QString category() const;
2828
Range range() const;
2929
quint32 color() const;
3030
QList<RangeHighlight> children() const;
3131
QList<RangeHighlight> allDescendants() const;
32+
QStringList tags() const;
3233

3334
friend QDataStream& operator<<(QDataStream&, const RangeHighlight&);
3435
friend QDataStream& operator>>(QDataStream&, RangeHighlight&);
@@ -39,6 +40,7 @@ class HOBBITSCORESHARED_EXPORT RangeHighlight
3940
Range m_range;
4041
quint32 m_color;
4142
QList<RangeHighlight> m_children;
43+
QStringList m_tags;
4244
};
4345

4446
bool HOBBITSCORESHARED_EXPORT operator<(const RangeHighlight &a, const RangeHighlight &b);

src/hobbits-plugins/analyzers/Find/find.cpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,13 @@ QSharedPointer<const AnalyzerResult> Find::analyzeBits(
5454
return AnalyzerResult::error(QString("Invalid parameters passed to %1:\n%2").arg(name()).arg(invalidations.join("\n")));
5555
}
5656

57-
auto findBits = BitArray::fromString(parameters.value("search_string").toString());
57+
QStringList parseErrors;
58+
QString searchString = parameters.value("search_string").toString();
59+
auto findBits = BitArray::fromString(searchString, &parseErrors);
60+
if (!parseErrors.isEmpty()) {
61+
return AnalyzerResult::error(QString("Failed to parse search term:\n%1").arg(parseErrors.mid(0, 10).join("\n")));
62+
}
63+
5864
auto bits = container->bits();
5965

6066
if (findBits->sizeInBits() < 1) {

src/hobbits-plugins/analyzers/KaitaiStruct/kaitaistruct.cpp

+32-21
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ QSharedPointer<const AnalyzerResult> KaitaiStruct::analyzeBits(
259259
return AnalyzerResult::error("Output analysis file doesn't contain a 'sections' specification");
260260
}
261261
QList<RangeHighlight> highlights;
262-
QMap<QString, QPair<Range, QList<QString>>> labelMap;
262+
QMap<QString, QSharedPointer<KsField>> fieldMap;
263263
QList<QString> topLevel;
264264
QJsonArray sections = outputObj.value("sections").toArray();
265265
int sectionNum = 0;
@@ -269,32 +269,43 @@ QSharedPointer<const AnalyzerResult> KaitaiStruct::analyzeBits(
269269
}
270270
sectionNum++;
271271
QJsonObject s = section.toObject();
272+
272273
QString label = QString("<%1>").arg(sectionNum);
273274
if (s.contains("label") && s.value("label").isString()) {
274275
label = s.value("label").toString();
275276
}
276-
if (!s.contains("start") || !s.contains("end") || !s.value("start").isDouble() || !s.value("end").isDouble()) {
277-
labelMap.insert(label, {Range(), {}});
278-
}
279-
else {
277+
auto field = QSharedPointer<KsField>(new KsField);
278+
fieldMap.insert(label, field);
279+
field->label = label;
280+
281+
if (s.contains("start") && s.contains("end") && s.value("start").isDouble() && s.value("end").isDouble()) {
280282
Range range(qint64(s.value("start").toDouble())*8, qint64(s.value("end").toDouble())*8 - 1);
281-
labelMap.insert(label, {range, {}});
283+
field->range = range;
284+
}
285+
286+
if (s.contains("value")) {
287+
field->value = s.value("value").toVariant().toString();
288+
}
289+
290+
if (s.contains("type")) {
291+
field->type = s.value("type").toVariant().toString();
282292
}
283293

284294
if (!s.contains("parent") || s.value("parent").toString().isEmpty()) {
285295
topLevel.append(label);
286296
}
287-
else if (labelMap.contains(s.value("parent").toString())) {
288-
labelMap[s.value("parent").toString()].second.append(label);
297+
else if (fieldMap.contains(s.value("parent").toString())) {
298+
fieldMap[s.value("parent").toString()]->children.append(label);
289299
}
290300
}
291301

292302
int colorIdx = 0;
293303
for (auto label : topLevel) {
294-
highlights.append(makeHighlight(label, labelMap, colorIdx));
304+
highlights.append(makeHighlight(label, fieldMap, colorIdx));
295305
}
296306

297307
QSharedPointer<BitInfo> bitInfo = BitInfo::copyFromContainer(container);
308+
bitInfo->clearHighlightCategory(KAITAI_STRUCT_CATEGORY);
298309
bitInfo->addHighlights(highlights);
299310

300311
if (!kscOutput.isEmpty()) {
@@ -307,30 +318,30 @@ QSharedPointer<const AnalyzerResult> KaitaiStruct::analyzeBits(
307318
return AnalyzerResult::result(bitInfo, parameters);
308319
}
309320

310-
RangeHighlight KaitaiStruct::makeHighlight(QString label, const QMap<QString, QPair<Range, QList<QString>>> &rangeData, int &colorIdx)
321+
RangeHighlight KaitaiStruct::makeHighlight(QString label, const QMap<QString, QSharedPointer<KsField>> &fieldData, int &colorIdx)
311322
{
312323
QList<QColor> colors = {
313-
QColor(100, 220, 100, 85),
314-
QColor(100, 0, 255, 50),
315-
QColor(0, 150, 230, 100),
316-
QColor(200, 140, 0, 100),
317-
QColor(250, 50, 0, 100)
324+
QColor(100, 220, 100, 200),
325+
QColor(100, 0, 255, 200),
326+
QColor(0, 150, 230, 200),
327+
QColor(200, 140, 0, 200),
328+
QColor(250, 50, 0, 200)
318329
};
319-
auto pair = rangeData.value(label);
320-
if (pair.second.isEmpty()) {
321-
auto highlight = RangeHighlight(KAITAI_STRUCT_CATEGORY, label, pair.first, colors.at(colorIdx).rgba());
330+
auto field = fieldData.value(label);
331+
if (field->children.isEmpty()) {
332+
auto highlight = RangeHighlight(KAITAI_STRUCT_CATEGORY, label, field->range, colors.at(colorIdx).rgba(), {}, {field->type, field->value});
322333
colorIdx = (colorIdx + 1) % colors.size();
323334
return highlight;
324335
}
325336
else {
326337
int parentColorIndex = colorIdx;
327338
colorIdx = 0;
328339
QList<RangeHighlight> children;
329-
for (auto child : pair.second) {
330-
children.append(makeHighlight(child, rangeData, colorIdx));
340+
for (auto child : field->children) {
341+
children.append(makeHighlight(child, fieldData, colorIdx));
331342
}
332343
colorIdx = parentColorIndex;
333-
auto highlight = RangeHighlight(KAITAI_STRUCT_CATEGORY, label, children, colors.at(colorIdx).rgba());
344+
auto highlight = RangeHighlight(KAITAI_STRUCT_CATEGORY, label, children, colors.at(colorIdx).rgba(), {field->type});
334345
colorIdx = (colorIdx + 1) % colors.size();
335346
return highlight;
336347
}

src/hobbits-plugins/analyzers/KaitaiStruct/kaitaistruct.h

+8-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,14 @@ class KaitaiStruct : public QObject, AnalyzerInterface
2828

2929

3030
private:
31-
RangeHighlight makeHighlight(QString label, const QMap<QString, QPair<Range, QList<QString>>> &rangeData, int &colorIdx);
31+
typedef struct KsField {
32+
QString label;
33+
Range range;
34+
QString value;
35+
QString type;
36+
QVector<QString> children;
37+
} KsField;
38+
RangeHighlight makeHighlight(QString label, const QMap<QString, QSharedPointer<KsField>> &fieldData, int &colorIdx);
3239

3340
QSharedPointer<ParameterDelegate> m_delegate;
3441

0 commit comments

Comments
 (0)