From 3c6dab95b4a6c14fec3e65fe4f5130a6e57ecf85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stig=20Bj=C3=B8rlykke?= Date: Sun, 28 Feb 2016 13:38:08 +0100 Subject: [PATCH] Qt: Improve Show Packet Bytes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add ShowAsASCIIandControl to keep ShowAsASCII only ASCII printable. - Enable show selected when ShowAsRAW. - Use QString::fromLatin1() when ShowAs8859_1. - Don't replace null with symbol for null when ShowAsUTF8. Change-Id: I25750247160e33d342fde12e6a998e3198270acf Reviewed-on: https://code.wireshark.org/review/14220 Reviewed-by: Stig Bjørlykke --- .../wsug_src/WSUG_chapter_advanced.asciidoc | 11 ++- ui/qt/show_packet_bytes_dialog.cpp | 85 ++++++++++++++----- ui/qt/show_packet_bytes_dialog.h | 4 +- wsutil/utf8_entities.h | 1 - 4 files changed, 74 insertions(+), 27 deletions(-) diff --git a/docbook/wsug_src/WSUG_chapter_advanced.asciidoc b/docbook/wsug_src/WSUG_chapter_advanced.asciidoc index 29a0e641f1..58f970f807 100644 --- a/docbook/wsug_src/WSUG_chapter_advanced.asciidoc +++ b/docbook/wsug_src/WSUG_chapter_advanced.asciidoc @@ -112,6 +112,8 @@ You can choose from the following actions: . __Close__: Close this dialog box. +==== Decode as + You can choose to decode the data from one of the following formats: . __None__: This is the default which does not decode anything. @@ -120,12 +122,15 @@ You can choose to decode the data from one of the following formats: . __Compressed__: This will decompress the buffer using zlib. +==== Show as + You can choose to view the data in one of the following formats: . __ASCII__: In this view you see the bytes as ASCII. - 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. + All control characters and non-ASCII bytes are replaced by dot. + +. __ASCII & Control__: In this view all control characters are shown using a + UTF-8 symbol and all non-ASCII bytes are replaced by dot. . __C Array__: This allows you to import the field data into your own C program. diff --git a/ui/qt/show_packet_bytes_dialog.cpp b/ui/qt/show_packet_bytes_dialog.cpp index 57c463ee2b..f1b5a09443 100644 --- a/ui/qt/show_packet_bytes_dialog.cpp +++ b/ui/qt/show_packet_bytes_dialog.cpp @@ -74,6 +74,7 @@ ShowPacketBytesDialog::ShowPacketBytesDialog(QWidget &parent, CaptureFile &cf) : ui->cbShowAs->blockSignals(true); ui->cbShowAs->addItem(tr("ASCII"), ShowAsASCII); + ui->cbShowAs->addItem(tr("ASCII & Control"), ShowAsASCIIandControl); ui->cbShowAs->addItem(tr("C Array"), ShowAsCArray); ui->cbShowAs->addItem(tr("EBCDIC"), ShowAsEBCDIC); ui->cbShowAs->addItem(tr("Hex Dump"), ShowAsHexDump); @@ -116,6 +117,10 @@ void ShowPacketBytesDialog::showSelected(int start, int end) // end set to -1 means show all packet bytes setStartAndEnd(0, finfo_->length); } else { + if (show_as_ == ShowAsRAW) { + start /= 2; + end = (end + 1) / 2; + } setStartAndEnd(start_ + start, start_ + end); } updateFieldBytes(); @@ -148,7 +153,9 @@ bool ShowPacketBytesDialog::enableShowSelected() return (((decode_as_ == DecodeAsNone) || (decode_as_ == DecodeAsROT13)) && ((show_as_ == ShowAsASCII) || - (show_as_ == ShowAsEBCDIC))); + (show_as_ == ShowAsASCIIandControl) || + (show_as_ == ShowAsEBCDIC) || + (show_as_ == ShowAsRAW))); } void ShowPacketBytesDialog::updateWidgets() @@ -261,6 +268,14 @@ void ShowPacketBytesDialog::copyBytes() switch (show_as_) { case ShowAsASCII: + { + QByteArray ba(field_bytes_); + sanitizeBuffer(ba, true); + wsApp->clipboard()->setText(ba); + break; + } + + case ShowAsASCIIandControl: case ShowAsCArray: case ShowAsEBCDIC: case ShowAsHexDump: @@ -297,6 +312,14 @@ void ShowPacketBytesDialog::saveAs() switch (show_as_) { case ShowAsASCII: + { + QByteArray ba(field_bytes_); + sanitizeBuffer(ba, true); + file.write(ba); + break; + } + + case ShowAsASCIIandControl: case ShowAsCArray: case ShowAsEBCDIC: case ShowAsHexDump: @@ -400,22 +423,36 @@ void ShowPacketBytesDialog::keyPressEvent(QKeyEvent *event) QDialog::keyPressEvent(event); } -void ShowPacketBytesDialog::sanitizeBuffer(QByteArray &ba) +void ShowPacketBytesDialog::sanitizeBuffer(QByteArray &ba, bool keep_CR) { for (int i = 0; i < ba.length(); 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] = '.'; - } + if (ba[i] == '\n' || (keep_CR && ba[i] == '\r')) + // Keep LF and optionally CR + continue; + + if (ba[i] == '\0' || g_ascii_isspace(ba[i])) { + ba[i] = ' '; + } else if (!g_ascii_isprint(ba[i])) { + ba[i] = '.'; + } + } +} + +void ShowPacketBytesDialog::symbolizeBuffer(QByteArray &ba) +{ + for (int i = 0; i < ba.length(); i++) { + if ((ba[i] < '\0' || ba[i] >= ' ') && ba[i] != (char)0x7f && !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); + QByteArray symbol(UTF8_SYMBOL_FOR_NULL); + for (char i = 0; i < ' '; i++) { + ba.replace(i, symbol); + symbol[2] = symbol[2] + 1; + } + symbol[2] = symbol[2] + 1; // Skip SP + ba.replace((char)0x7f, symbol); // DEL } void ShowPacketBytesDialog::rot13(QByteArray &ba) @@ -494,7 +531,16 @@ void ShowPacketBytesDialog::updatePacketBytes(void) case ShowAsASCII: { QByteArray ba(field_bytes_); - sanitizeBuffer(ba); + sanitizeBuffer(ba, false); + ui->tePacketBytes->setLineWrapMode(QTextEdit::WidgetWidth); + ui->tePacketBytes->setPlainText(ba); + break; + } + + case ShowAsASCIIandControl: + { + QByteArray ba(field_bytes_); + symbolizeBuffer(ba); ui->tePacketBytes->setLineWrapMode(QTextEdit::WidgetWidth); ui->tePacketBytes->setPlainText(ba); break; @@ -541,7 +587,7 @@ void ShowPacketBytesDialog::updatePacketBytes(void) { QByteArray ba(field_bytes_); EBCDIC_to_ASCII((guint8*)ba.data(), ba.length()); - sanitizeBuffer(ba); + sanitizeBuffer(ba, false); ui->tePacketBytes->setLineWrapMode(QTextEdit::WidgetWidth); ui->tePacketBytes->setPlainText(ba); break; @@ -621,12 +667,9 @@ 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()); + QString latin1 = QString::fromLatin1(field_bytes_.constData(), (int)field_bytes_.length()); ui->tePacketBytes->setLineWrapMode(QTextEdit::WidgetWidth); - ui->tePacketBytes->setPlainText((const char *)bytes); - wmem_free (NULL, bytes); + ui->tePacketBytes->setPlainText(latin1); break; } @@ -635,9 +678,7 @@ 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. - QByteArray ba(field_bytes_); - ba.replace('\0', UTF8_SYMBOL_FOR_NULL); - QString utf8 = QString::fromUtf8(ba); + QString utf8 = QString::fromUtf8(field_bytes_.constData(), (int)field_bytes_.length()); ui->tePacketBytes->setLineWrapMode(QTextEdit::WidgetWidth); ui->tePacketBytes->setPlainText(utf8); break; diff --git a/ui/qt/show_packet_bytes_dialog.h b/ui/qt/show_packet_bytes_dialog.h index 19558d03e8..906a2d8bb8 100644 --- a/ui/qt/show_packet_bytes_dialog.h +++ b/ui/qt/show_packet_bytes_dialog.h @@ -83,6 +83,7 @@ private: }; enum ShowAsType { ShowAsASCII, + ShowAsASCIIandControl, ShowAsCArray, ShowAsEBCDIC, ShowAsHexDump, @@ -98,7 +99,8 @@ private: bool enableShowSelected(); void updateWidgets(); // Needed for WiresharkDialog? void updateHintLabel(); - void sanitizeBuffer(QByteArray &ba); + void sanitizeBuffer(QByteArray &ba, bool handle_CR); + void symbolizeBuffer(QByteArray &ba); void rot13(QByteArray &ba); void updateFieldBytes(bool initialization = false); void updatePacketBytes(); diff --git a/wsutil/utf8_entities.h b/wsutil/utf8_entities.h index 658a0141c6..dc5deba554 100644 --- a/wsutil/utf8_entities.h +++ b/wsutil/utf8_entities.h @@ -46,7 +46,6 @@ #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 */