Skip to content

Commit

Permalink
Merge pull request #121 from Mahlet-Inc/develop
Browse files Browse the repository at this point in the history
Merge in some kaitai fixes and improvements
  • Loading branch information
goldest-star committed Aug 22, 2021
2 parents 2297a40 + d499141 commit 8165fa7
Show file tree
Hide file tree
Showing 14 changed files with 298 additions and 133 deletions.
Binary file modified docs/hobbits_screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 10 additions & 4 deletions src/hobbits-core/bitarray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -702,7 +702,7 @@ QByteArray BitArray::readBytesNoSync(qint64 byteOffset, qint64 maxBytes) const
return m_dataFile.read(maxBytes);
}

QSharedPointer<BitArray> BitArray::fromString(QString bitArraySpec, QStringList parseErrors)
QSharedPointer<BitArray> BitArray::fromString(QString bitArraySpec, QStringList *parseErrors)
{
int size = 0;
if (bitArraySpec.startsWith("0x")) {
Expand All @@ -718,7 +718,9 @@ QSharedPointer<BitArray> BitArray::fromString(QString bitArraySpec, QStringList
return QSharedPointer<BitArray>(new BitArray(bytes, size));
}
else {
parseErrors.append(QString("Expected only hex digits in '0x'-prefixed data - got '%1'").arg(bitArraySpec));
if (parseErrors != nullptr) {
parseErrors->append(QString("Expected only hex digits in '0x'-prefixed data - got '%1'").arg(bitArraySpec));
}
return QSharedPointer<BitArray>(new BitArray());
}
}
Expand All @@ -731,10 +733,12 @@ QSharedPointer<BitArray> BitArray::fromString(QString bitArraySpec, QStringList
int val = bitArraySpec.mid(i, 1).toInt(&parseOk, 8);

if (!parseOk) {
parseErrors.append(
if (parseErrors != nullptr) {
parseErrors->append(
QString("Expected octal digit in '0o'-prefixed data - got %1").arg(
bitArraySpec.at(
i)));
}
continue;
}

Expand All @@ -752,8 +756,10 @@ QSharedPointer<BitArray> BitArray::fromString(QString bitArraySpec, QStringList
bits->set(i - 2, true);
}
else if (bitArraySpec.at(i) != '0') {
parseErrors.append(
if (parseErrors != nullptr) {
parseErrors->append(
QString("Expected '1' or '0' in '0b'-prefixed data - got '%1'").arg(bitArraySpec.at(i)));
}
}
}
return bits;
Expand Down
2 changes: 1 addition & 1 deletion src/hobbits-core/bitarray.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class HOBBITSCORESHARED_EXPORT BitArray
static BitArray* deserialize(QDataStream &stream);
void serialize(QDataStream &stream) const;

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

private:
void writeToStream(QDataStream &dataStream) const; // private for use by serializer and writeTo
Expand Down
28 changes: 20 additions & 8 deletions src/hobbits-core/rangehighlight.cpp
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
#include "rangehighlight.h"

RangeHighlight::RangeHighlight(QString category, QString label, Range range, quint32 color, QList<RangeHighlight> children) :
RangeHighlight::RangeHighlight(QString category, QString label, Range range, quint32 color, QList<RangeHighlight> children, QStringList tags) :
m_category(category),
m_label(label),
m_range(range),
m_color(color),
m_children(children)
m_children(children),
m_tags(tags)
{

}

RangeHighlight::RangeHighlight(QString category, QString label, QList<RangeHighlight> children, quint32 color) :
RangeHighlight::RangeHighlight(QString category, QString label, QList<RangeHighlight> children, quint32 color, QStringList tags) :
m_category(category),
m_label(label),
m_color(color),
m_children(children)
m_children(children),
m_tags(tags)
{
std::sort(m_children.begin(), m_children.end());
if (m_children.isEmpty()) {
Expand All @@ -23,9 +25,9 @@ RangeHighlight::RangeHighlight(QString category, QString label, QList<RangeHighl
m_range = Range(m_children.first().range().start(), m_children.last().range().end());
}

RangeHighlight RangeHighlight::simple(QString category, QString label, Range range, quint32 color)
RangeHighlight RangeHighlight::simple(QString category, QString label, Range range, quint32 color, QStringList tags)
{
return RangeHighlight(category, label, range, color);
return RangeHighlight(category, label, range, color, {}, tags);
}

bool operator<(const RangeHighlight &a, const RangeHighlight &b)
Expand Down Expand Up @@ -68,30 +70,40 @@ QList<RangeHighlight> RangeHighlight::allDescendants() const
return all;
}

QStringList RangeHighlight::tags() const
{
return m_tags;
}

const QString VERSION_1 = "RangeHighlight v1";
const QString VERSION_2 = "RangeHighlight v2";
const QString VERSION_3 = "RangeHighlight v3";
const QString VERSION_4 = "RHv4";
QDataStream& operator<<(QDataStream& stream, const RangeHighlight& highlight)
{
stream << VERSION_3;
stream << VERSION_4;
stream << highlight.category();
stream << highlight.label();
stream << highlight.range();
stream << highlight.color();
stream << highlight.children();
stream << highlight.tags();
return stream;
}

QDataStream& operator>>(QDataStream& stream, RangeHighlight& highlight)
{
QString version;
stream >> version;
if (version == VERSION_3) {
if (version == VERSION_3 || version == VERSION_4) {
stream >> highlight.m_category;
stream >> highlight.m_label;
stream >> highlight.m_range;
stream >> highlight.m_color;
stream >> highlight.m_children;
if (version == VERSION_4) {
stream >> highlight.m_tags;
}
return stream;
}
else {
Expand Down
8 changes: 5 additions & 3 deletions src/hobbits-core/rangehighlight.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,18 @@ class HOBBITSCORESHARED_EXPORT RangeHighlight
RangeHighlight(const RangeHighlight &) = default;
RangeHighlight &operator=(const RangeHighlight &) = default;

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

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

QString label() const;
QString category() const;
Range range() const;
quint32 color() const;
QList<RangeHighlight> children() const;
QList<RangeHighlight> allDescendants() const;
QStringList tags() const;

friend QDataStream& operator<<(QDataStream&, const RangeHighlight&);
friend QDataStream& operator>>(QDataStream&, RangeHighlight&);
Expand All @@ -39,6 +40,7 @@ class HOBBITSCORESHARED_EXPORT RangeHighlight
Range m_range;
quint32 m_color;
QList<RangeHighlight> m_children;
QStringList m_tags;
};

bool HOBBITSCORESHARED_EXPORT operator<(const RangeHighlight &a, const RangeHighlight &b);
Expand Down
8 changes: 7 additions & 1 deletion src/hobbits-plugins/analyzers/Find/find.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,13 @@ QSharedPointer<const AnalyzerResult> Find::analyzeBits(
return AnalyzerResult::error(QString("Invalid parameters passed to %1:\n%2").arg(name()).arg(invalidations.join("\n")));
}

auto findBits = BitArray::fromString(parameters.value("search_string").toString());
QStringList parseErrors;
QString searchString = parameters.value("search_string").toString();
auto findBits = BitArray::fromString(searchString, &parseErrors);
if (!parseErrors.isEmpty()) {
return AnalyzerResult::error(QString("Failed to parse search term:\n%1").arg(parseErrors.mid(0, 10).join("\n")));
}

auto bits = container->bits();

if (findBits->sizeInBits() < 1) {
Expand Down
53 changes: 32 additions & 21 deletions src/hobbits-plugins/analyzers/KaitaiStruct/kaitaistruct.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ QSharedPointer<const AnalyzerResult> KaitaiStruct::analyzeBits(
return AnalyzerResult::error("Output analysis file doesn't contain a 'sections' specification");
}
QList<RangeHighlight> highlights;
QMap<QString, QPair<Range, QList<QString>>> labelMap;
QMap<QString, QSharedPointer<KsField>> fieldMap;
QList<QString> topLevel;
QJsonArray sections = outputObj.value("sections").toArray();
int sectionNum = 0;
Expand All @@ -269,32 +269,43 @@ QSharedPointer<const AnalyzerResult> KaitaiStruct::analyzeBits(
}
sectionNum++;
QJsonObject s = section.toObject();

QString label = QString("<%1>").arg(sectionNum);
if (s.contains("label") && s.value("label").isString()) {
label = s.value("label").toString();
}
if (!s.contains("start") || !s.contains("end") || !s.value("start").isDouble() || !s.value("end").isDouble()) {
labelMap.insert(label, {Range(), {}});
}
else {
auto field = QSharedPointer<KsField>(new KsField);
fieldMap.insert(label, field);
field->label = label;

if (s.contains("start") && s.contains("end") && s.value("start").isDouble() && s.value("end").isDouble()) {
Range range(qint64(s.value("start").toDouble())*8, qint64(s.value("end").toDouble())*8 - 1);
labelMap.insert(label, {range, {}});
field->range = range;
}

if (s.contains("value")) {
field->value = s.value("value").toVariant().toString();
}

if (s.contains("type")) {
field->type = s.value("type").toVariant().toString();
}

if (!s.contains("parent") || s.value("parent").toString().isEmpty()) {
topLevel.append(label);
}
else if (labelMap.contains(s.value("parent").toString())) {
labelMap[s.value("parent").toString()].second.append(label);
else if (fieldMap.contains(s.value("parent").toString())) {
fieldMap[s.value("parent").toString()]->children.append(label);
}
}

int colorIdx = 0;
for (auto label : topLevel) {
highlights.append(makeHighlight(label, labelMap, colorIdx));
highlights.append(makeHighlight(label, fieldMap, colorIdx));
}

QSharedPointer<BitInfo> bitInfo = BitInfo::copyFromContainer(container);
bitInfo->clearHighlightCategory(KAITAI_STRUCT_CATEGORY);
bitInfo->addHighlights(highlights);

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

RangeHighlight KaitaiStruct::makeHighlight(QString label, const QMap<QString, QPair<Range, QList<QString>>> &rangeData, int &colorIdx)
RangeHighlight KaitaiStruct::makeHighlight(QString label, const QMap<QString, QSharedPointer<KsField>> &fieldData, int &colorIdx)
{
QList<QColor> colors = {
QColor(100, 220, 100, 85),
QColor(100, 0, 255, 50),
QColor(0, 150, 230, 100),
QColor(200, 140, 0, 100),
QColor(250, 50, 0, 100)
QColor(100, 220, 100, 200),
QColor(100, 0, 255, 200),
QColor(0, 150, 230, 200),
QColor(200, 140, 0, 200),
QColor(250, 50, 0, 200)
};
auto pair = rangeData.value(label);
if (pair.second.isEmpty()) {
auto highlight = RangeHighlight(KAITAI_STRUCT_CATEGORY, label, pair.first, colors.at(colorIdx).rgba());
auto field = fieldData.value(label);
if (field->children.isEmpty()) {
auto highlight = RangeHighlight(KAITAI_STRUCT_CATEGORY, label, field->range, colors.at(colorIdx).rgba(), {}, {field->type, field->value});
colorIdx = (colorIdx + 1) % colors.size();
return highlight;
}
else {
int parentColorIndex = colorIdx;
colorIdx = 0;
QList<RangeHighlight> children;
for (auto child : pair.second) {
children.append(makeHighlight(child, rangeData, colorIdx));
for (auto child : field->children) {
children.append(makeHighlight(child, fieldData, colorIdx));
}
colorIdx = parentColorIndex;
auto highlight = RangeHighlight(KAITAI_STRUCT_CATEGORY, label, children, colors.at(colorIdx).rgba());
auto highlight = RangeHighlight(KAITAI_STRUCT_CATEGORY, label, children, colors.at(colorIdx).rgba(), {field->type});
colorIdx = (colorIdx + 1) % colors.size();
return highlight;
}
Expand Down
9 changes: 8 additions & 1 deletion src/hobbits-plugins/analyzers/KaitaiStruct/kaitaistruct.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,14 @@ class KaitaiStruct : public QObject, AnalyzerInterface


private:
RangeHighlight makeHighlight(QString label, const QMap<QString, QPair<Range, QList<QString>>> &rangeData, int &colorIdx);
typedef struct KsField {
QString label;
Range range;
QString value;
QString type;
QVector<QString> children;
} KsField;
RangeHighlight makeHighlight(QString label, const QMap<QString, QSharedPointer<KsField>> &fieldData, int &colorIdx);

QSharedPointer<ParameterDelegate> m_delegate;

Expand Down
Loading

0 comments on commit 8165fa7

Please sign in to comment.