1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
|
From 57dca63b564bff8daf0be249b70ffbabf0467b18 Mon Sep 17 00:00:00 2001
From: Matt Brictson <matt@mattbrictson.com>
Date: Thu, 13 Jun 2019 12:46:03 -0700
Subject: [PATCH] Handle console output that is improperly encoded
Not sure why, but in some cases the data received from SSHKit claims to
be encoded as UTF-8 but is actually invalid. This causes `gsub` to blow
up with `ArgumentError: invalid byte sequence in UTF-8` when airbrussh
calls `strip_ascii_color`.
Work around this by detected invalid encoding and stripping out the
offending code points from string before calling `gsub`.
---
CHANGELOG.md | 1 +
lib/airbrussh/console.rb | 10 +++++++++-
test/airbrussh/console_test.rb | 11 +++++++++++
3 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f759adf..48519c1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file. This projec
## [Unreleased]
* Your contribution here!
+* [#121](https://github.com/mattbrictson/airbrussh/pull/121): Gracefully handle SSH output that has invalid UTF-8 encoding instead of raising an exception - [@mattbrictson](https://github.com/mattbrictson)
## [1.3.1][] (2018-11-04)
diff --git a/lib/airbrussh/console.rb b/lib/airbrussh/console.rb
index f470c62..3da1e81 100644
--- a/lib/airbrussh/console.rb
+++ b/lib/airbrussh/console.rb
@@ -53,7 +53,10 @@ def truncate_to_console_width(string)
end
def strip_ascii_color(string)
- (string || "").gsub(/\033\[[0-9;]*m/, "")
+ string ||= ""
+ string = to_utf8(string) unless string.valid_encoding?
+
+ string.gsub(/\033\[[0-9;]*m/, "")
end
def console_width
@@ -85,5 +88,10 @@ def utf8_supported?(string)
rescue Encoding::UndefinedConversionError
false
end
+
+ def to_utf8(string)
+ string.force_encoding("ASCII-8BIT")
+ .encode("UTF-8", :invalid => :replace, :undef => :replace)
+ end
end
end
diff --git a/test/airbrussh/console_test.rb b/test/airbrussh/console_test.rb
index 1ffb256..52e6f52 100644
--- a/test/airbrussh/console_test.rb
+++ b/test/airbrussh/console_test.rb
@@ -106,6 +106,17 @@ def test_truncates_improperly_encoded_ascii_string
assert_equal(ascii_8bit("The ‘...\n"), ascii_8bit(output))
end
+ def test_print_line_handles_invalid_utf8
+ console = configured_console(:tty => false)
+
+ invalid_utf8 = "The ‘quick’ brown fox"
+ .encode("Windows-1255")
+ .force_encoding("UTF-8")
+
+ console.print_line(invalid_utf8)
+ assert_equal("The �quick� brown fox\n", output)
+ end
+
def test_doesnt_truncates_to_zero_width
console = configured_console(:tty => true) do |config|
config.color = false
|