Skip to content

Commit b8766ea

Browse files
committed
Fix rb_enc_vsprintf and force message encoding instead of converting
1 parent c77f8bb commit b8766ea

File tree

5 files changed

+35
-8
lines changed

5 files changed

+35
-8
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Bug fixes:
1010
Compatibility:
1111

1212
* Add `Exception#detailed_message` method (#3257, @andrykonchin).
13+
* Fix `rb_enc_vsprintf` and force String encoding instead of converting it (@andrykonchin).
1314

1415
Performance:
1516

lib/cext/ABI_check.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
5
1+
6

spec/ruby/optional/capi/encoding_spec.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,20 @@
657657
end
658658
end
659659

660+
describe "rb_enc_raise" do
661+
it "forces exception message encoding to the specified one" do
662+
utf_8_incompatible_string = "\x81".b
663+
664+
-> {
665+
@s.rb_enc_raise(Encoding::UTF_8, RuntimeError, utf_8_incompatible_string)
666+
}.should raise_error { |e|
667+
e.message.encoding.should == Encoding::UTF_8
668+
e.message.valid_encoding?.should == false
669+
e.message.bytes.should == utf_8_incompatible_string.bytes
670+
}
671+
end
672+
end
673+
660674
describe "rb_uv_to_utf8" do
661675
it 'converts a Unicode codepoint to a UTF-8 C string' do
662676
str = ' ' * 6

spec/ruby/optional/capi/ext/encoding_spec.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,13 @@ static VALUE encoding_spec_rb_enc_str_asciionly_p(VALUE self, VALUE str) {
271271
}
272272
}
273273

274+
static void encoding_spec_rb_enc_raise(VALUE self, VALUE encoding, VALUE exception_class, VALUE format) {
275+
rb_encoding *e = rb_to_encoding(encoding);
276+
const char *f = RSTRING_PTR(format);
277+
278+
rb_enc_raise(e, exception_class, f);
279+
}
280+
274281
static VALUE encoding_spec_rb_uv_to_utf8(VALUE self, VALUE buf, VALUE num) {
275282
int len = rb_uv_to_utf8(RSTRING_PTR(buf), NUM2INT(num));
276283
RB_ENC_CODERANGE_CLEAR(buf);
@@ -368,6 +375,7 @@ void Init_encoding_spec(void) {
368375
rb_define_method(cls, "rb_enc_nth", encoding_spec_rb_enc_nth, 2);
369376
rb_define_method(cls, "rb_enc_codepoint_len", encoding_spec_rb_enc_codepoint_len, 1);
370377
rb_define_method(cls, "rb_enc_str_asciionly_p", encoding_spec_rb_enc_str_asciionly_p, 1);
378+
rb_define_method(cls, "rb_enc_raise", encoding_spec_rb_enc_raise, 3);
371379
rb_define_method(cls, "rb_uv_to_utf8", encoding_spec_rb_uv_to_utf8, 2);
372380
rb_define_method(cls, "ONIGENC_MBC_CASE_FOLD", encoding_spec_ONIGENC_MBC_CASE_FOLD, 1);
373381
rb_define_method(cls, "rb_enc_left_char_head", encoding_spec_rb_enc_left_char_head, 2);

src/main/c/cext/printf.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,17 @@ VALUE rb_enc_vsprintf(rb_encoding *enc, const char *format, va_list args) {
5656
VALUE types = RUBY_CEXT_INVOKE("rb_tr_sprintf_types", rubyFormat);
5757
VALUE rubyArgs = rb_tr_get_sprintf_args(args, types);
5858

59-
return rb_str_conv_enc(rb_tr_wrap(
60-
polyglot_invoke(
61-
RUBY_CEXT,
62-
"rb_tr_sprintf",
63-
rb_tr_unwrap(rubyFormat),
64-
rb_tr_vsprintf_new_cstr,
65-
rb_tr_unwrap(rubyArgs))), NULL, enc);
59+
VALUE string = rb_tr_wrap(
60+
polyglot_invoke(
61+
RUBY_CEXT,
62+
"rb_tr_sprintf",
63+
rb_tr_unwrap(rubyFormat),
64+
rb_tr_vsprintf_new_cstr,
65+
rb_tr_unwrap(rubyArgs)
66+
)
67+
);
68+
69+
return rb_enc_associate(string, enc);
6670
}
6771

6872
VALUE rb_enc_sprintf(rb_encoding *enc, const char *format, ...) {

0 commit comments

Comments
 (0)