Package: ruby-airbrussh / 1.3.1-2+deb10u1

utf8-encoding.patch Patch series | download
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