aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStig Bjørlykke <stig@bjorlykke.org>2016-02-14 23:01:09 +0100
committerAlexis La Goutte <alexis.lagoutte@gmail.com>2016-02-16 21:43:14 +0000
commit989739c4fcb229f51389997e0a5e2947b97c68d2 (patch)
tree701930a3739f9cc5c368d57aa73b048f31ef4d8b
parenta6118997ff3a1ebbeb816d50daf6d15247b8bd52 (diff)
Qt: Add Decode as in Show Packet Bytes
Add an option to decode the packet bytes from base64 or zlib compressed. Also add configurable start byte and end byte to make it possible to decode a subset of bytes. It's also possible to select a range in ASCII view and select "Show selected" from the context menu to make a subset. In ASCII view a null terminator is replaced by UTF8 symbol for NULL, and a CR is replaced by UTF8 symbol for carriage return. This is done to make it possible to "Show selected" from the context menu. Change-Id: Ie03c9912c304c121af6ca9e998a6e8445b5382c5 Reviewed-on: https://code.wireshark.org/review/13958 Petri-Dish: Stig Bjørlykke <stig@bjorlykke.org> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com>
-rw-r--r--docbook/wsug_src/WSUG_chapter_advanced.asciidoc32
-rw-r--r--ui/qt/show_packet_bytes_dialog.cpp262
-rw-r--r--ui/qt/show_packet_bytes_dialog.h51
-rw-r--r--ui/qt/show_packet_bytes_dialog.ui41
-rw-r--r--ui/qt/wireshark_en.qmbin1992 -> 2152 bytes
-rw-r--r--ui/qt/wireshark_en.ts159
-rw-r--r--wsutil/utf8_entities.h3
7 files changed, 468 insertions, 80 deletions
diff --git a/docbook/wsug_src/WSUG_chapter_advanced.asciidoc b/docbook/wsug_src/WSUG_chapter_advanced.asciidoc
index bd649c817e..29a0e641f1 100644
--- a/docbook/wsug_src/WSUG_chapter_advanced.asciidoc
+++ b/docbook/wsug_src/WSUG_chapter_advanced.asciidoc
@@ -90,14 +90,19 @@ You can choose to view the data in one of the following formats:
=== Show Packet Bytes
-If a selected packet field does not show all the bytes (i.e. they are truncated)
-or if they are shown as bytes rather than string or if they require more formatting
-because they contain an image or HTML then this dialog can be used.
+If a selected packet field does not show all the bytes (i.e. they are truncated
+when displayed) or if they are shown as bytes rather than string or if they require
+more formatting because they contain an image or HTML then this dialog can be used.
+
+This dialog can also be used to decode field bytes from base64 or zlib compressed
+and show the decoded bytes as configurable output. It's also possible to select
+a subset of bytes setting the start byte and end byte.
You can choose from the following actions:
. __Find__: Search for the given text. Matching text will be highlighted,
- and the ``Find Next'' will search for more.
+ and the ``Find Next'' will search for more. In the context menu for the
+ find text it's possible to configure to use regular expression find.
. __Print__: Print the bytes in the currently selected format.
@@ -107,13 +112,28 @@ You can choose from the following actions:
. __Close__: Close this dialog box.
+You can choose to decode the data from one of the following formats:
+
+. __None__: This is the default which does not decode anything.
+
+. __Base64__: This will decode from Base64.
+
+. __Compressed__: This will decompress the buffer using zlib.
+
You can choose to view the data in one of the following formats:
. __ASCII__: In this view you see the bytes as ASCII.
- All non-ASCII bytes are replaced by dot for readability.
+ A null terminator is shown using the UTF-8 symbol for NULL, a CR is shown using
+ the UTF-8 symbol for carriage return, and all other non-ASCII bytes are replaced
+ by dot for readability.
+
+. __C Array__: This allows you to import the field data into your own C program.
. __EBCDIC__: For the big-iron freaks out there.
+. __HEX Dump__: This allows you to see all the data. This will require a lot of
+ screen space and is best used with binary protocols.
+
. __HTML__: This allows you to see all the data formatted as a HTML document.
The HTML supported is what's supported by the Qt QTextEdit class.
@@ -128,6 +148,8 @@ You can choose to view the data in one of the following formats:
. __UTF8__: In this view you see the bytes as UTF-8.
+. __YAML__: This will show the bytes as a YAML binary dump.
+
[[ChAdvExpert]]
=== Expert Information
diff --git a/ui/qt/show_packet_bytes_dialog.cpp b/ui/qt/show_packet_bytes_dialog.cpp
index 93539399cc..a52b6717d5 100644
--- a/ui/qt/show_packet_bytes_dialog.cpp
+++ b/ui/qt/show_packet_bytes_dialog.cpp
@@ -26,55 +26,54 @@
#include "wireshark_application.h"
#include "epan/charsets.h"
-#include <wsutil/utf8_entities.h>
+#include "wsutil/base64.h"
+#include "wsutil/utf8_entities.h"
+#include <QAction>
#include <QImage>
#include <QKeyEvent>
+#include <QMenu>
#include <QPrintDialog>
#include <QPrinter>
#include <QTextStream>
// To do:
// - Add show as custom protocol in a Packet Details view
-// - Add show as PDF or handle PDF as Image
-// - Add decode from BASE64
// - Use ByteViewText to ShowAsHexDump and supplementary view for custom protocol
// - Handle large data blocks
ShowPacketBytesDialog::ShowPacketBytesDialog(QWidget &parent, CaptureFile &cf) :
WiresharkDialog(parent, cf),
ui(new Ui::ShowPacketBytesDialog),
+ finfo_(cf.capFile()->finfo_selected),
+ decode_as_(DecodeAsNone),
show_as_(ShowAsASCII),
use_regex_find_(false)
{
ui->setupUi(this);
- field_info *finfo = cf.capFile()->finfo_selected;
- QString field_name = QString("%1 (%2)").arg(finfo->hfinfo->name, finfo->hfinfo->abbrev);
+ QString field_name = QString("%1 (%2)").arg(finfo_->hfinfo->name, finfo_->hfinfo->abbrev);
setWindowSubtitle (field_name);
- const guint8 *bytes = tvb_get_ptr(finfo->ds_tvb, 0, -1) + finfo->start;
- field_bytes_ = QByteArray((const char *)bytes, finfo->length);
-
- QString hint = tr("Frame %1, %2, %Ln byte(s).", "", finfo->length)
- .arg(cf.capFile()->current_frame->num)
- .arg(field_name);
- hint.prepend("<small><i>");
- hint.append("</i></small>");
- ui->hintLabel->setText(hint);
-
- // Try loading as image
- if (image_.loadFromData(field_bytes_)) {
- show_as_ = ShowAsImage;
- }
+ hint_label_ = tr("Frame %1, %2, %Ln byte(s).", "", finfo_->length)
+ .arg(cf.capFile()->current_frame->num)
+ .arg(field_name);
ui->tePacketBytes->installEventFilter(this);
+ connect(ui->tePacketBytes, SIGNAL(showSelected(int,int)), this, SLOT(showSelected(int,int)));
connect(ui->leFind, SIGNAL(useRegexFind(bool)), this, SLOT(useRegexFind(bool)));
// XXX Use recent settings instead
resize(parent.width() * 2 / 3, parent.height());
+ ui->cbDecodeAs->blockSignals(true);
+ ui->cbDecodeAs->addItem(tr("None"), DecodeAsNone);
+ ui->cbDecodeAs->addItem(tr("Base64"), DecodeAsBASE64);
+ ui->cbDecodeAs->addItem(tr("Compressed"), DecodeAsCompressed);
+ ui->cbDecodeAs->addItem(tr("ROT13"), DecodeAsROT13);
+ ui->cbDecodeAs->blockSignals(false);
+
ui->cbShowAs->blockSignals(true);
ui->cbShowAs->addItem(tr("ASCII"), ShowAsASCII);
ui->cbShowAs->addItem(tr("C Array"), ShowAsCArray);
@@ -89,6 +88,9 @@ ShowPacketBytesDialog::ShowPacketBytesDialog(QWidget &parent, CaptureFile &cf) :
ui->cbShowAs->setCurrentIndex(show_as_);
ui->cbShowAs->blockSignals(false);
+ ui->sbStart->setMinimum(0);
+ ui->sbEnd->setMaximum(finfo_->length);
+
print_button_ = ui->buttonBox->addButton(tr("Print"), QDialogButtonBox::ActionRole);
connect(print_button_, SIGNAL(clicked()), this, SLOT(printBytes()));
@@ -101,7 +103,8 @@ ShowPacketBytesDialog::ShowPacketBytesDialog(QWidget &parent, CaptureFile &cf) :
connect(ui->buttonBox, SIGNAL(helpRequested()), this, SLOT(helpButton()));
connect(&cap_file_, SIGNAL(captureFileClosing()), this, SLOT(captureFileClosing()));
- updatePacketBytes();
+ setStartAndEnd(0, finfo_->length);
+ updateFieldBytes(true);
}
ShowPacketBytesDialog::~ShowPacketBytesDialog()
@@ -109,16 +112,99 @@ ShowPacketBytesDialog::~ShowPacketBytesDialog()
delete ui;
}
+void ShowPacketBytesDialog::showSelected(int start, int end)
+{
+ if (end == -1) {
+ // end set to -1 means show all packet bytes
+ setStartAndEnd(0, finfo_->length);
+ } else {
+ setStartAndEnd(start_ + start, start_ + end);
+ }
+ updateFieldBytes();
+}
+
+void ShowPacketBytesDialog::setStartAndEnd(int start, int end)
+{
+ start_ = start;
+ end_ = end;
+
+ ui->sbStart->blockSignals(true);
+ ui->sbStart->setMaximum(end_);
+ ui->sbStart->setValue(start_);
+ ui->sbStart->blockSignals(false);
+
+ ui->sbEnd->blockSignals(true);
+ ui->sbEnd->setMinimum(start_);
+ ui->sbEnd->setValue(end_);
+ ui->sbEnd->blockSignals(false);
+
+ updateHintLabel();
+}
+
+bool ShowPacketBytesDialog::enableShowSelected()
+{
+ // "Show Selected" only works when showing all bytes:
+ // - DecodeAs must not alter the number of bytes in the buffer
+ // - ShowAs must show all bytes in the buffer
+
+ return (((decode_as_ == DecodeAsNone) ||
+ (decode_as_ == DecodeAsROT13)) &&
+ ((show_as_ == ShowAsASCII) ||
+ (show_as_ == ShowAsEBCDIC)));
+}
+
void ShowPacketBytesDialog::updateWidgets()
{
WiresharkDialog::updateWidgets();
}
+void ShowPacketBytesDialog::updateHintLabel()
+{
+ QString hint = hint_label_;
+
+ if (start_ > 0 || end_ < finfo_->length) {
+ hint.append(" <span style=\"color: red\">" +
+ tr("Displaying %Ln byte(s).", "", end_ - start_) +
+ "</span>");
+ }
+
+ ui->hintLabel->setText("<small><i>" + hint + "</i></small>");
+}
+
+void ShowPacketBytesDialog::on_sbStart_valueChanged(int value)
+{
+ start_ = value;
+ ui->sbEnd->setMinimum(value);
+
+ updateHintLabel();
+ updateFieldBytes();
+}
+
+void ShowPacketBytesDialog::on_sbEnd_valueChanged(int value)
+{
+ end_ = value;
+ ui->sbStart->setMaximum(value);
+
+ updateHintLabel();
+ updateFieldBytes();
+}
+
+void ShowPacketBytesDialog::on_cbDecodeAs_currentIndexChanged(int idx)
+{
+ if (idx < 0) return;
+ decode_as_ = static_cast<DecodeAsType>(ui->cbDecodeAs->itemData(idx).toInt());
+
+ ui->tePacketBytes->setShowSelectedEnabled(enableShowSelected());
+
+ updateFieldBytes();
+}
+
void ShowPacketBytesDialog::on_cbShowAs_currentIndexChanged(int idx)
{
if (idx < 0) return;
show_as_ = static_cast<ShowAsType>(ui->cbShowAs->itemData(idx).toInt());
+ ui->tePacketBytes->setShowSelectedEnabled(enableShowSelected());
ui->lFind->setEnabled(true);
ui->leFind->setEnabled(true);
ui->bFind->setEnabled(true);
@@ -316,13 +402,86 @@ void ShowPacketBytesDialog::keyPressEvent(QKeyEvent *event)
QDialog::keyPressEvent(event);
}
-static inline void sanitize_buffer(QByteArray &ba)
+void ShowPacketBytesDialog::sanitizeBuffer(QByteArray &ba)
{
for (int i = 0; i < ba.length(); i++) {
- if (!g_ascii_isspace(ba[i]) && !g_ascii_isprint(ba[i])) {
- ba[i] = '.';
+ if (ba[i] != '\0' && ba[i] != '\r' && ba[i] != '\n') {
+ if (g_ascii_isspace(ba[i])) {
+ ba[i] = ' ';
+ } else if (!g_ascii_isprint(ba[i])) {
+ ba[i] = '.';
+ }
}
}
+
+ // Null and CR are replaced with UTF8 symbols to be able to show all
+ // bytes in ASCII view. This will ensure that "Show Selected" works.
+ ba.replace('\0', UTF8_SYMBOL_FOR_NULL);
+ ba.replace('\r', UTF8_SYMBOL_FOR_CARRIAGE_RETURN);
+}
+
+void ShowPacketBytesDialog::rot13(QByteArray &ba)
+{
+ for (int i = 0; i < ba.length(); i++) {
+ gchar upper = g_ascii_toupper(ba[i]);
+ if (upper >= 'A' && upper <= 'M') ba[i] = ba[i] + 13;
+ else if (upper >= 'N' && upper <= 'Z') ba[i] = ba[i] - 13;
+ }
+}
+
+void ShowPacketBytesDialog::updateFieldBytes(bool initialization)
+{
+ int start = finfo_->start + start_;
+ int length = end_ - start_;
+ const guint8 *bytes;
+
+ switch (decode_as_) {
+
+ case DecodeAsNone:
+ bytes = tvb_get_ptr(finfo_->ds_tvb, start, -1);
+ field_bytes_ = QByteArray((const char *)bytes, length);
+ break;
+
+ case DecodeAsBASE64:
+ {
+ bytes = tvb_get_ptr(finfo_->ds_tvb, start, -1);
+ field_bytes_ = QByteArray((const char *)bytes, length);
+ size_t len = ws_base64_decode_inplace(field_bytes_.data());
+ field_bytes_.resize(len);
+ break;
+ }
+
+ case DecodeAsCompressed:
+ {
+ tvbuff *uncompr_tvb = tvb_uncompress(finfo_->ds_tvb, start, length);
+ if (uncompr_tvb) {
+ bytes = tvb_get_ptr(uncompr_tvb, 0, -1);
+ field_bytes_ = QByteArray((const char *)bytes, tvb_reported_length(uncompr_tvb));
+ tvb_free(uncompr_tvb);
+ } else {
+ field_bytes_.clear();
+ }
+ break;
+ }
+
+ case DecodeAsROT13:
+ bytes = tvb_get_ptr(finfo_->ds_tvb, start, -1);
+ field_bytes_ = QByteArray((const char *)bytes, length);
+ rot13(field_bytes_);
+ break;
+ }
+
+ if (initialization || show_as_ == ShowAsImage) {
+ // Try loading as image
+ if (image_.loadFromData(field_bytes_) && initialization) {
+ show_as_ = ShowAsImage;
+ ui->cbShowAs->blockSignals(true);
+ ui->cbShowAs->setCurrentIndex(ShowAsImage);
+ ui->cbShowAs->blockSignals(false);
+ }
+ }
+
+ updatePacketBytes();
}
void ShowPacketBytesDialog::updatePacketBytes(void)
@@ -337,7 +496,7 @@ void ShowPacketBytesDialog::updatePacketBytes(void)
case ShowAsASCII:
{
QByteArray ba(field_bytes_);
- sanitize_buffer(ba);
+ sanitizeBuffer(ba);
ui->tePacketBytes->setPlainText(ba);
break;
}
@@ -383,7 +542,7 @@ void ShowPacketBytesDialog::updatePacketBytes(void)
{
QByteArray ba(field_bytes_);
EBCDIC_to_ASCII((guint8*)ba.data(), ba.length());
- sanitize_buffer(ba);
+ sanitizeBuffer(ba);
ui->tePacketBytes->setPlainText(ba);
break;
}
@@ -392,6 +551,7 @@ void ShowPacketBytesDialog::updatePacketBytes(void)
{
int pos = 0, len = field_bytes_.length();
QString text;
+ text.reserve((len / 16) * 80);
while (pos < len) {
char hexbuf[256];
@@ -458,6 +618,8 @@ void ShowPacketBytesDialog::updatePacketBytes(void)
case ShowAsISO8859_1:
{
+ // The ISO 8859-1 string should probably also use UTF8_SYMBOL_FOR_NULL
+ // to be able to show all bytes.
guint8 *bytes = get_8859_1_string(NULL, (const guint8 *)field_bytes_.constData(), field_bytes_.length());
ui->tePacketBytes->setPlainText((const char *)bytes);
wmem_free (NULL, bytes);
@@ -469,7 +631,9 @@ void ShowPacketBytesDialog::updatePacketBytes(void)
// The QString docs say that invalid characters will be replaced with
// replacement characters or removed. It would be nice if we could
// explicitly choose one or the other.
- QString utf8 = QString::fromUtf8(field_bytes_);
+ QByteArray ba(field_bytes_);
+ ba.replace('\0', UTF8_SYMBOL_FOR_NULL);
+ QString utf8 = QString::fromUtf8(ba);
ui->tePacketBytes->setPlainText(utf8);
break;
}
@@ -499,9 +663,55 @@ void ShowPacketBytesDialog::updatePacketBytes(void)
void ShowPacketBytesDialog::captureFileClosing()
{
+ // We have lost the source backend and must disable all functions
+ // for manipulating decoding and displayed range.
+
+ ui->tePacketBytes->setMenusEnabled(false);
+ ui->lDecodeAs->setEnabled(false);
+ ui->cbDecodeAs->setEnabled(false);
+ ui->lStart->setEnabled(false);
+ ui->sbStart->setEnabled(false);
+ ui->lEnd->setEnabled(false);
+ ui->sbEnd->setEnabled(false);
+
+ finfo_ = NULL; // This will invalidate the source backend
+
WiresharkDialog::captureFileClosing();
}
+void ShowPacketBytesTextEdit::contextMenuEvent(QContextMenuEvent *event)
+{
+ QMenu *menu = createStandardContextMenu();
+ QAction *action;
+
+ menu->addSeparator();
+
+ action = menu->addAction(tr("Show Selected"));
+ action->setEnabled(menus_enabled_ && show_selected_enabled_ && textCursor().hasSelection());
+ connect(action, SIGNAL(triggered()), this, SLOT(showSelected()));
+
+ action = menu->addAction(tr("Show All"));
+ action->setEnabled(menus_enabled_);
+ connect(action, SIGNAL(triggered()), this, SLOT(showAll()));
+
+ menu->exec(event->globalPos());
+ delete menu;
+}
+
+void ShowPacketBytesTextEdit::showSelected()
+{
+ QTextCursor cursor = textCursor();
+ int start = cursor.selectionStart();
+ int end = cursor.selectionEnd();
+
+ emit showSelected(start, end);
+}
+
+void ShowPacketBytesTextEdit::showAll()
+{
+ emit showSelected(0, -1);
+}
+
/*
* Editor modelines
*
diff --git a/ui/qt/show_packet_bytes_dialog.h b/ui/qt/show_packet_bytes_dialog.h
index 9161b97ee5..19558d03e8 100644
--- a/ui/qt/show_packet_bytes_dialog.h
+++ b/ui/qt/show_packet_bytes_dialog.h
@@ -33,10 +33,13 @@
#include "file.h"
#include "wireshark_dialog.h"
+#include <QLineEdit>
#include <QPushButton>
+#include <QTextEdit>
namespace Ui {
class ShowPacketBytesDialog;
+class ShowPacketBytesTextEdit;
}
class ShowPacketBytesDialog : public WiresharkDialog
@@ -55,11 +58,15 @@ protected:
void keyPressEvent(QKeyEvent *event);
private slots:
+ void on_sbStart_valueChanged(int value);
+ void on_sbEnd_valueChanged(int value);
+ void on_cbDecodeAs_currentIndexChanged(int idx);
void on_cbShowAs_currentIndexChanged(int idx);
void on_leFind_returnPressed();
void on_bFind_clicked();
void on_buttonBox_rejected();
+ void showSelected(int start, int end);
void useRegexFind(bool use_regex);
void findText(bool go_back = true);
void helpButton();
@@ -68,6 +75,12 @@ private slots:
void saveAs();
private:
+ enum DecodeAsType {
+ DecodeAsNone,
+ DecodeAsBASE64,
+ DecodeAsCompressed,
+ DecodeAsROT13
+ };
enum ShowAsType {
ShowAsASCII,
ShowAsCArray,
@@ -81,20 +94,56 @@ private:
ShowAsYAML
};
+ void setStartAndEnd(int start, int end);
+ bool enableShowSelected();
void updateWidgets(); // Needed for WiresharkDialog?
- void updatePacketBytes(void);
+ void updateHintLabel();
+ void sanitizeBuffer(QByteArray &ba);
+ void rot13(QByteArray &ba);
+ void updateFieldBytes(bool initialization = false);
+ void updatePacketBytes();
Ui::ShowPacketBytesDialog *ui;
+ const field_info *finfo_;
QByteArray field_bytes_;
+ QString hint_label_;
QPushButton *print_button_;
QPushButton *copy_button_;
QPushButton *save_as_button_;
+ DecodeAsType decode_as_;
ShowAsType show_as_;
bool use_regex_find_;
+ int start_;
+ int end_;
QImage image_;
};
+class ShowPacketBytesTextEdit : public QTextEdit
+{
+ Q_OBJECT
+
+public:
+ explicit ShowPacketBytesTextEdit(QWidget *parent = 0) :
+ QTextEdit(parent), show_selected_enabled_(true), menus_enabled_(true) { }
+ ~ShowPacketBytesTextEdit() { }
+
+ void setShowSelectedEnabled(bool enabled) { show_selected_enabled_ = enabled; }
+ void setMenusEnabled(bool enabled) { menus_enabled_ = enabled; }
+
+signals:
+ void showSelected(int, int);
+
+private slots:
+ void contextMenuEvent(QContextMenuEvent *event);
+ void showSelected();
+ void showAll();
+
+private:
+ bool show_selected_enabled_;
+ bool menus_enabled_;
+};
+
#endif // SHOW_PACKET_BYTES_DIALOG_H
/*
diff --git a/ui/qt/show_packet_bytes_dialog.ui b/ui/qt/show_packet_bytes_dialog.ui
index 441a19fcf9..08cfd4574d 100644
--- a/ui/qt/show_packet_bytes_dialog.ui
+++ b/ui/qt/show_packet_bytes_dialog.ui
@@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
- <width>594</width>
+ <width>710</width>
<height>620</height>
</rect>
</property>
@@ -24,7 +24,7 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
- <widget class="QTextEdit" name="tePacketBytes">
+ <widget class="ShowPacketBytesTextEdit" name="tePacketBytes">
<property name="readOnly">
<bool>true</bool>
</property>
@@ -41,7 +41,17 @@
</widget>
</item>
<item>
- <layout class="QHBoxLayout" name="horizontalLayout_1" stretch="0,0,0">
+ <layout class="QHBoxLayout" name="horizontalLayout_1" stretch="0,0,0,0,1,0,0,0,0">
+ <item>
+ <widget class="QLabel" name="lDecodeAs">
+ <property name="text">
+ <string>Decode as</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="cbDecodeAs"/>
+ </item>
<item>
<widget class="QLabel" name="lShowAs">
<property name="text">
@@ -69,6 +79,26 @@
</property>
</spacer>
</item>
+ <item>
+ <widget class="QLabel" name="lStart">
+ <property name="text">
+ <string>Start</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="sbStart"/>
+ </item>
+ <item>
+ <widget class="QLabel" name="lEnd">
+ <property name="text">
+ <string>End</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="sbEnd"/>
+ </item>
</layout>
</item>
<item>
@@ -107,6 +137,11 @@
<extends>QLineEdit</extends>
<header>find_line_edit.h</header>
</customwidget>
+ <customwidget>
+ <class>ShowPacketBytesTextEdit</class>
+ <extends>QTextEdit</extends>
+ <header>show_packet_bytes_dialog.h</header>
+ </customwidget>
</customwidgets>
<resources/>
<connections/>
diff --git a/ui/qt/wireshark_en.qm b/ui/qt/wireshark_en.qm
index fe756a2c58..acbb40498b 100644
--- a/ui/qt/wireshark_en.qm
+++ b/ui/qt/wireshark_en.qm
Binary files differ
diff --git a/ui/qt/wireshark_en.ts b/ui/qt/wireshark_en.ts
index 166a6c88d1..41722f59ad 100644
--- a/ui/qt/wireshark_en.ts
+++ b/ui/qt/wireshark_en.ts
@@ -2666,20 +2666,33 @@ for filter files: %2.</source>
</message>
</context>
<context>
+ <name>FindLineEdit</name>
+ <message>
+ <location filename="find_line_edit.cpp" line="37"/>
+ <source>Textual Find</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="find_line_edit.cpp" line="42"/>
+ <source>Regular Expression Find</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>FollowStreamDialog</name>
<message>
- <location filename="follow_stream_dialog.cpp" line="116"/>
+ <location filename="follow_stream_dialog.cpp" line="119"/>
<source>Filter Out This Stream</source>
<oldsource>Hide this stream</oldsource>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="follow_stream_dialog.cpp" line="119"/>
+ <location filename="follow_stream_dialog.cpp" line="122"/>
<source>Print</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="follow_stream_dialog.cpp" line="122"/>
+ <location filename="follow_stream_dialog.cpp" line="125"/>
<source>Save as</source>
<oldsource>Save as...</oldsource>
<translation type="unfinished"></translation>
@@ -2699,47 +2712,47 @@ for filter files: %2.</source>
</translation>
</message>
<message>
- <location filename="follow_stream_dialog.cpp" line="107"/>
+ <location filename="follow_stream_dialog.cpp" line="110"/>
<source>ASCII</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="follow_stream_dialog.cpp" line="108"/>
+ <location filename="follow_stream_dialog.cpp" line="111"/>
<source>C Arrays</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="follow_stream_dialog.cpp" line="109"/>
+ <location filename="follow_stream_dialog.cpp" line="112"/>
<source>EBCDIC</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="follow_stream_dialog.cpp" line="110"/>
+ <location filename="follow_stream_dialog.cpp" line="113"/>
<source>Hex Dump</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="follow_stream_dialog.cpp" line="111"/>
+ <location filename="follow_stream_dialog.cpp" line="114"/>
<source>UTF-8</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="follow_stream_dialog.cpp" line="112"/>
+ <location filename="follow_stream_dialog.cpp" line="115"/>
<source>YAML</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="follow_stream_dialog.cpp" line="113"/>
+ <location filename="follow_stream_dialog.cpp" line="116"/>
<source>Raw</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="follow_stream_dialog.cpp" line="166"/>
+ <location filename="follow_stream_dialog.cpp" line="169"/>
<source>Packet %1. </source>
<translation type="unfinished"></translation>
</message>
<message numerus="yes">
- <location filename="follow_stream_dialog.cpp" line="169"/>
+ <location filename="follow_stream_dialog.cpp" line="172"/>
<source>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;client&lt;/span&gt; pkt(s), </source>
<translation>
<numerusform>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;client&lt;/span&gt; pkt, </numerusform>
@@ -2747,7 +2760,7 @@ for filter files: %2.</source>
</translation>
</message>
<message numerus="yes">
- <location filename="follow_stream_dialog.cpp" line="172"/>
+ <location filename="follow_stream_dialog.cpp" line="175"/>
<source>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;server&lt;/span&gt; pkt(s), </source>
<translation>
<numerusform>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;server&lt;/span&gt; pkt, </numerusform>
@@ -2755,7 +2768,7 @@ for filter files: %2.</source>
</translation>
</message>
<message numerus="yes">
- <location filename="follow_stream_dialog.cpp" line="175"/>
+ <location filename="follow_stream_dialog.cpp" line="178"/>
<source>%Ln turn(s).</source>
<translation>
<numerusform>%Ln turn.</numerusform>
@@ -2763,65 +2776,65 @@ for filter files: %2.</source>
</translation>
</message>
<message>
- <location filename="follow_stream_dialog.cpp" line="178"/>
+ <location filename="follow_stream_dialog.cpp" line="181"/>
<source> Click to select.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="follow_stream_dialog.cpp" line="239"/>
+ <location filename="follow_stream_dialog.cpp" line="261"/>
<source>Save Stream Content As</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="follow_stream_dialog.cpp" line="504"/>
+ <location filename="follow_stream_dialog.cpp" line="526"/>
<source>
[Stream output truncated]</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="follow_stream_dialog.cpp" line="769"/>
+ <location filename="follow_stream_dialog.cpp" line="791"/>
<source>No capture file.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="follow_stream_dialog.cpp" line="769"/>
+ <location filename="follow_stream_dialog.cpp" line="791"/>
<source>Please make sure you have a capture file opened.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="follow_stream_dialog.cpp" line="775"/>
- <location filename="follow_stream_dialog.cpp" line="781"/>
+ <location filename="follow_stream_dialog.cpp" line="797"/>
+ <location filename="follow_stream_dialog.cpp" line="803"/>
<source>Error following stream.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="follow_stream_dialog.cpp" line="775"/>
+ <location filename="follow_stream_dialog.cpp" line="797"/>
<source>Capture file invalid.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="follow_stream_dialog.cpp" line="781"/>
+ <location filename="follow_stream_dialog.cpp" line="803"/>
<source>Please make sure you have a %1 packet selected.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="follow_stream_dialog.cpp" line="897"/>
+ <location filename="follow_stream_dialog.cpp" line="919"/>
<source>Follow %1 Stream (%2)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="follow_stream_dialog.cpp" line="803"/>
+ <location filename="follow_stream_dialog.cpp" line="825"/>
<source>Error creating filter for this stream.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="follow_stream_dialog.cpp" line="804"/>
+ <location filename="follow_stream_dialog.cpp" line="826"/>
<source>A transport or network layer header is needed.</source>
<translation type="unfinished"></translation>
</message>
<message numerus="yes">
- <location filename="follow_stream_dialog.cpp" line="834"/>
- <location filename="follow_stream_dialog.cpp" line="846"/>
+ <location filename="follow_stream_dialog.cpp" line="856"/>
+ <location filename="follow_stream_dialog.cpp" line="868"/>
<source>%Ln total stream(s).</source>
<translation type="unfinished">
<numerusform>%Ln stream.</numerusform>
@@ -2829,7 +2842,7 @@ for filter files: %2.</source>
</translation>
</message>
<message>
- <location filename="follow_stream_dialog.cpp" line="915"/>
+ <location filename="follow_stream_dialog.cpp" line="937"/>
<source>File closed.</source>
<translation type="unfinished"></translation>
</message>
@@ -13720,16 +13733,31 @@ a:hover {
</message>
<message>
<location filename="show_packet_bytes_dialog.ui" line="48"/>
+ <source>Decode as</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="show_packet_bytes_dialog.ui" line="58"/>
<source>Show as</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="show_packet_bytes_dialog.ui" line="79"/>
+ <location filename="show_packet_bytes_dialog.ui" line="85"/>
+ <source>Start</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="show_packet_bytes_dialog.ui" line="95"/>
+ <source>End</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="show_packet_bytes_dialog.ui" line="109"/>
<source>Find:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="show_packet_bytes_dialog.ui" line="89"/>
+ <location filename="show_packet_bytes_dialog.ui" line="119"/>
<source>Find &amp;Next</source>
<translation type="unfinished"></translation>
</message>
@@ -13742,77 +13770,118 @@ a:hover {
</translation>
</message>
<message>
- <location filename="show_packet_bytes_dialog.cpp" line="76"/>
+ <location filename="show_packet_bytes_dialog.cpp" line="71"/>
+ <source>None</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="show_packet_bytes_dialog.cpp" line="72"/>
+ <source>Base64</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="show_packet_bytes_dialog.cpp" line="73"/>
+ <source>Compressed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="show_packet_bytes_dialog.cpp" line="74"/>
+ <source>ROT13</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="show_packet_bytes_dialog.cpp" line="78"/>
<source>ASCII</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="show_packet_bytes_dialog.cpp" line="77"/>
+ <location filename="show_packet_bytes_dialog.cpp" line="79"/>
<source>C Array</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="show_packet_bytes_dialog.cpp" line="78"/>
+ <location filename="show_packet_bytes_dialog.cpp" line="80"/>
<source>EBCDIC</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="show_packet_bytes_dialog.cpp" line="79"/>
+ <location filename="show_packet_bytes_dialog.cpp" line="81"/>
<source>Hex Dump</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="show_packet_bytes_dialog.cpp" line="80"/>
+ <location filename="show_packet_bytes_dialog.cpp" line="82"/>
<source>HTML</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="show_packet_bytes_dialog.cpp" line="81"/>
+ <location filename="show_packet_bytes_dialog.cpp" line="83"/>
<source>Image</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="show_packet_bytes_dialog.cpp" line="82"/>
+ <location filename="show_packet_bytes_dialog.cpp" line="84"/>
<source>ISO 8859-1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="show_packet_bytes_dialog.cpp" line="83"/>
+ <location filename="show_packet_bytes_dialog.cpp" line="85"/>
<source>Raw</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="show_packet_bytes_dialog.cpp" line="84"/>
+ <location filename="show_packet_bytes_dialog.cpp" line="86"/>
<source>UTF-8</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="show_packet_bytes_dialog.cpp" line="85"/>
+ <location filename="show_packet_bytes_dialog.cpp" line="87"/>
<source>YAML</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="show_packet_bytes_dialog.cpp" line="89"/>
+ <location filename="show_packet_bytes_dialog.cpp" line="94"/>
<source>Print</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="show_packet_bytes_dialog.cpp" line="92"/>
+ <location filename="show_packet_bytes_dialog.cpp" line="97"/>
<source>Copy</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="show_packet_bytes_dialog.cpp" line="95"/>
+ <location filename="show_packet_bytes_dialog.cpp" line="100"/>
<source>Save as</source>
<translation type="unfinished"></translation>
</message>
+ <message numerus="yes">
+ <location filename="show_packet_bytes_dialog.cpp" line="167"/>
+ <source>Displaying %Ln byte(s).</source>
+ <translation type="unfinished">
+ <numerusform>Displaying %Ln byte.</numerusform>
+ <numerusform>Displaying %Ln bytes.</numerusform>
+ </translation>
+ </message>
<message>
- <location filename="show_packet_bytes_dialog.cpp" line="183"/>
+ <location filename="show_packet_bytes_dialog.cpp" line="291"/>
<source>Save Selected Packet Bytes As</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
+ <name>ShowPacketBytesTextEdit</name>
+ <message>
+ <location filename="show_packet_bytes_dialog.cpp" line="689"/>
+ <source>Show Selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="show_packet_bytes_dialog.cpp" line="693"/>
+ <source>Show All</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>SimpleDialog</name>
<message>
<location filename="simple_dialog.cpp" line="200"/>
diff --git a/wsutil/utf8_entities.h b/wsutil/utf8_entities.h
index 5d58cf232c..658a0141c6 100644
--- a/wsutil/utf8_entities.h
+++ b/wsutil/utf8_entities.h
@@ -45,6 +45,9 @@
#define UTF8_PLACE_OF_INTEREST_SIGN "\xe2\x8c\x98" /* 8984 / 0x2318 */
+#define UTF8_SYMBOL_FOR_NULL "\xe2\x90\x80" /* 9216 / 0x2400 */
+#define UTF8_SYMBOL_FOR_CARRIAGE_RETURN "\xe2\x90\x8d" /* 9229 / 0x240d */
+
#define UTF8_CHECK_MARK "\xe2\x9c\x93" /* 10003 / 0x2713 */
#define UTF8_BALLOT_X "\xe2\x9c\x97" /* 10007 / 0x2717 */
#define UTF8_LONG_RIGHTWARDS_ARROW "\xe2\x9f\xb6" /* 10230 / 0x27f6 */