aboutsummaryrefslogtreecommitdiffstats
path: root/epan/print_stream.c
diff options
context:
space:
mode:
authorGerald Combs <gerald@wireshark.org>2016-05-06 10:25:02 -0700
committerAnders Broman <a.broman58@gmail.com>2016-05-09 04:11:29 +0000
commitae4a912af04456a6fc4022150485be541f65d96c (patch)
tree2d98b9431e142cebb945aa4649872d83480d3c1c /epan/print_stream.c
parent6bd2e29358d6d9dbd334b263aae6a5ae2c049db3 (diff)
TShark: Convert TTY output.
If we detect that we're writing to a TTY and that it doesn't support UTF-8, convert our output to the current code page on UNIX/Linux or to UTF-16LE on Windows. This helps to ensure that we don't fill users' screens with mojibake, along with scrubbing invalid output. Add a note about our output behavior to the TShark man page. Add a note about the glyphs we should and shouldn't be using to utf8_entities.h. Bug: 12393 Change-Id: I52b6dd240173b80ffb6d35b5950a46a565c97ce8 Reviewed-on: https://code.wireshark.org/review/15277 Reviewed-by: Gerald Combs <gerald@wireshark.org> Petri-Dish: Gerald Combs <gerald@wireshark.org> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Graham Bloice <graham.bloice@trihedral.com> Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'epan/print_stream.c')
-rw-r--r--epan/print_stream.c49
1 files changed, 48 insertions, 1 deletions
diff --git a/epan/print_stream.c b/epan/print_stream.c
index f53965c75b..740773af2e 100644
--- a/epan/print_stream.c
+++ b/epan/print_stream.c
@@ -26,6 +26,12 @@
#include <stdio.h>
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <string.h>
+#endif
+
#include <glib.h>
#include <epan/print_stream.h>
@@ -104,6 +110,13 @@ typedef struct {
#define MAX_INDENT 160
+#ifdef _WIN32
+static char *to_codeset = "UTF-16LE";
+#else
+static char *tty_codeset = NULL;
+static char *to_codeset = NULL;
+#endif
+
static gboolean
print_line_text(print_stream_t *self, int indent, const char *line)
{
@@ -128,7 +141,41 @@ print_line_text(print_stream_t *self, int indent, const char *line)
ret = fwrite(spaces, 1, num_spaces, output->fh);
if (ret == num_spaces) {
- fputs(line, output->fh);
+ gchar *tty_out = NULL;
+
+#ifndef _WIN32
+ /* Is there a more reliable way to do this? */
+ if (!tty_codeset) {
+ gchar *upper_codeset;
+
+ tty_codeset = g_get_codeset();
+ upper_codeset = g_ascii_strup(tty_codeset, -1);
+ if (!strstr(upper_codeset, "UTF-8") && !strstr(upper_codeset, "UTF8")) {
+ to_codeset = tty_codeset;
+ }
+ g_free(upper_codeset);
+ }
+#endif
+
+ if (ws_isatty(ws_fileno(output->fh)) && to_codeset) {
+ /* XXX Allocating a fresh buffer every line probably isn't the
+ * most efficient way to do this. However, this has the side
+ * effect of scrubbing invalid output.
+ */
+ tty_out = g_convert_with_fallback(line, -1, to_codeset, "UTF-8", "?", NULL, NULL, NULL);
+ }
+
+ if (tty_out) {
+#ifdef _WIN32
+ DWORD out_len = (DWORD) wcslen((wchar_t *) tty_out);
+ WriteConsoleW((HANDLE)_get_osfhandle(_fileno(output->fh)), tty_out, out_len, &out_len, NULL);
+#else
+ fputs(tty_out, output->fh);
+#endif
+ g_free(tty_out);
+ } else {
+ fputs(line, output->fh);
+ }
putc('\n', output->fh);
}
return !ferror(output->fh);