diff options
author | Nobuyoshi Nakada <[email protected]> | 2023-04-10 15:13:26 +0900 |
---|---|---|
committer | Nobuyoshi Nakada <[email protected]> | 2023-04-10 15:13:26 +0900 |
commit | c30cab8ce4d2ab21ef75e2a3218cb76b21d78407 (patch) | |
tree | 9f10a70883e1ee94c8fb3b5d8dbb1cf0942da815 | |
parent | e1d2dc4cfc44263b0159c31d6dcdfba1861b628f (diff) |
[Bug #19570] Propagate message encoding to decorated message
-rw-r--r-- | eval_error.c | 18 | ||||
-rw-r--r-- | test/ruby/test_exception.rb | 13 |
2 files changed, 25 insertions, 6 deletions
diff --git a/eval_error.c b/eval_error.c index 948a205dd9..a5c252ba1d 100644 --- a/eval_error.c +++ b/eval_error.c @@ -7,6 +7,8 @@ (NIL_P(str) ? warn_print(x) : (void)rb_str_cat_cstr(str, x)) #define write_warn2(str, x, l) \ (NIL_P(str) ? warn_print2(x, l) : (void)rb_str_cat(str, x, l)) +#define write_warn_enc(str, x, l, enc) \ + (NIL_P(str) ? warn_print2(x, l) : (void)rb_enc_str_buf_cat(str, x, l, enc)) #ifdef HAVE_BUILTIN___BUILTIN_CONSTANT_P #define warn_print(x) RB_GNUC_EXTENSION_BLOCK( \ (__builtin_constant_p(x)) ? \ @@ -127,13 +129,17 @@ rb_decorate_message(const VALUE eclass, const VALUE emesg, int highlight) { const char *einfo = ""; long elen = 0; + rb_encoding *eenc; - VALUE str = rb_str_new2(""); + VALUE str = rb_usascii_str_new_cstr(""); - if (!NIL_P(emesg)) { + if (!NIL_P(emesg) && rb_enc_asciicompat(eenc = rb_enc_get(emesg))) { einfo = RSTRING_PTR(emesg); elen = RSTRING_LEN(emesg); } + else { + eenc = NULL; + } if (eclass == rb_eRuntimeError && elen == 0) { if (highlight) write_warn(str, underline); write_warn(str, "unhandled exception"); @@ -156,7 +162,7 @@ rb_decorate_message(const VALUE eclass, const VALUE emesg, int highlight) if (RSTRING_PTR(epath)[0] == '#') epath = 0; if ((tail = memchr(einfo, '\n', elen)) != 0) { - write_warn2(str, einfo, tail - einfo); + write_warn_enc(str, einfo, tail - einfo, eenc); tail++; /* skip newline */ } else { @@ -176,7 +182,7 @@ rb_decorate_message(const VALUE eclass, const VALUE emesg, int highlight) if (tail && einfo+elen > tail) { if (!highlight) { write_warn2(str, "\n", 1); - write_warn2(str, tail, einfo+elen-tail); + write_warn_enc(str, tail, einfo+elen-tail, eenc); } else { elen -= tail - einfo; @@ -186,7 +192,7 @@ rb_decorate_message(const VALUE eclass, const VALUE emesg, int highlight) tail = memchr(einfo, '\n', elen); if (!tail || tail > einfo) { write_warn(str, bold); - write_warn2(str, einfo, tail ? tail-einfo : elen); + write_warn_enc(str, einfo, tail ? tail-einfo : elen, eenc); write_warn(str, reset); if (!tail) { break; @@ -195,7 +201,7 @@ rb_decorate_message(const VALUE eclass, const VALUE emesg, int highlight) elen -= tail - einfo; einfo = tail; do ++tail; while (tail < einfo+elen && *tail == '\n'); - write_warn2(str, einfo, tail-einfo); + write_warn_enc(str, einfo, tail-einfo, eenc); elen -= tail - einfo; einfo = tail; } diff --git a/test/ruby/test_exception.rb b/test/ruby/test_exception.rb index 51abfee18a..0f39a15b2d 100644 --- a/test/ruby/test_exception.rb +++ b/test/ruby/test_exception.rb @@ -1470,6 +1470,19 @@ $stderr = $stdout; raise "\x82\xa0"') do |outs, errs, status| assert_equal({ highlight: Exception.to_tty? }, opt_) end + def test_full_message_with_encoding + message = "\u{dc}bersicht" + begin + begin + raise message + rescue => e + raise "\n#{e.message}" + end + rescue => e + end + assert_include(e.full_message, message) + end + def test_syntax_error_detailed_message Dir.mktmpdir do |dir| File.write(File.join(dir, "detail.rb"), "#{<<~"begin;"}\n#{<<~'end;'}") |