diff options
author | tomoya ishida <[email protected]> | 2024-10-02 02:01:31 +0900 |
---|---|---|
committer | git <[email protected]> | 2024-10-01 17:01:38 +0000 |
commit | e320da60976f6818c8667afb98fe88142c3073d2 (patch) | |
tree | 3b056188af6c69387799b656a1e6aebf972255d2 /lib/reline/unicode.rb | |
parent | ec230ac6432ea89f1ee53d82a62337d4883dc83a (diff) |
[ruby/reline] Fix Reline crash with invalid encoding history
(https://github.com/ruby/reline/pull/751)
https://github.com/ruby/reline/commit/e9d4b37e34
Diffstat (limited to 'lib/reline/unicode.rb')
-rw-r--r-- | lib/reline/unicode.rb | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/lib/reline/unicode.rb b/lib/reline/unicode.rb index ef239d5e9e..0ec815aeea 100644 --- a/lib/reline/unicode.rb +++ b/lib/reline/unicode.rb @@ -54,6 +54,22 @@ class Reline::Unicode }.join end + def self.safe_encode(str, encoding) + # Reline only supports utf-8 convertible string. + converted = str.encode(encoding, invalid: :replace, undef: :replace) + return converted if str.encoding == Encoding::UTF_8 || converted.encoding == Encoding::UTF_8 || converted.ascii_only? + + # This code is essentially doing the same thing as + # `str.encode(utf8, **replace_options).encode(encoding, **replace_options)` + # but also avoids unneccesary irreversible encoding conversion. + converted.gsub(/\X/) do |c| + c.encode(Encoding::UTF_8) + c + rescue Encoding::UndefinedConversionError + '?' + end + end + require 'reline/unicode/east_asian_width' def self.get_mbchar_width(mbchar) |