Skip to content

Commit

Permalink
[GR-44710] Fix rb_enc_vsprintf and force message encoding instead o…
Browse files Browse the repository at this point in the history
…f converting

PullRequest: truffleruby/4012
  • Loading branch information
andrykonchin committed Sep 20, 2023
2 parents c77f8bb + b8766ea commit 84dcacc
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Bug fixes:
Compatibility:

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

Performance:

Expand Down
2 changes: 1 addition & 1 deletion lib/cext/ABI_check.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
5
6
14 changes: 14 additions & 0 deletions spec/ruby/optional/capi/encoding_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,20 @@
end
end

describe "rb_enc_raise" do
it "forces exception message encoding to the specified one" do
utf_8_incompatible_string = "\x81".b

-> {
@s.rb_enc_raise(Encoding::UTF_8, RuntimeError, utf_8_incompatible_string)
}.should raise_error { |e|
e.message.encoding.should == Encoding::UTF_8
e.message.valid_encoding?.should == false
e.message.bytes.should == utf_8_incompatible_string.bytes
}
end
end

describe "rb_uv_to_utf8" do
it 'converts a Unicode codepoint to a UTF-8 C string' do
str = ' ' * 6
Expand Down
8 changes: 8 additions & 0 deletions spec/ruby/optional/capi/ext/encoding_spec.c
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,13 @@ static VALUE encoding_spec_rb_enc_str_asciionly_p(VALUE self, VALUE str) {
}
}

static void encoding_spec_rb_enc_raise(VALUE self, VALUE encoding, VALUE exception_class, VALUE format) {
rb_encoding *e = rb_to_encoding(encoding);
const char *f = RSTRING_PTR(format);

rb_enc_raise(e, exception_class, f);
}

static VALUE encoding_spec_rb_uv_to_utf8(VALUE self, VALUE buf, VALUE num) {
int len = rb_uv_to_utf8(RSTRING_PTR(buf), NUM2INT(num));
RB_ENC_CODERANGE_CLEAR(buf);
Expand Down Expand Up @@ -368,6 +375,7 @@ void Init_encoding_spec(void) {
rb_define_method(cls, "rb_enc_nth", encoding_spec_rb_enc_nth, 2);
rb_define_method(cls, "rb_enc_codepoint_len", encoding_spec_rb_enc_codepoint_len, 1);
rb_define_method(cls, "rb_enc_str_asciionly_p", encoding_spec_rb_enc_str_asciionly_p, 1);
rb_define_method(cls, "rb_enc_raise", encoding_spec_rb_enc_raise, 3);
rb_define_method(cls, "rb_uv_to_utf8", encoding_spec_rb_uv_to_utf8, 2);
rb_define_method(cls, "ONIGENC_MBC_CASE_FOLD", encoding_spec_ONIGENC_MBC_CASE_FOLD, 1);
rb_define_method(cls, "rb_enc_left_char_head", encoding_spec_rb_enc_left_char_head, 2);
Expand Down
18 changes: 11 additions & 7 deletions src/main/c/cext/printf.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,17 @@ VALUE rb_enc_vsprintf(rb_encoding *enc, const char *format, va_list args) {
VALUE types = RUBY_CEXT_INVOKE("rb_tr_sprintf_types", rubyFormat);
VALUE rubyArgs = rb_tr_get_sprintf_args(args, types);

return rb_str_conv_enc(rb_tr_wrap(
polyglot_invoke(
RUBY_CEXT,
"rb_tr_sprintf",
rb_tr_unwrap(rubyFormat),
rb_tr_vsprintf_new_cstr,
rb_tr_unwrap(rubyArgs))), NULL, enc);
VALUE string = rb_tr_wrap(
polyglot_invoke(
RUBY_CEXT,
"rb_tr_sprintf",
rb_tr_unwrap(rubyFormat),
rb_tr_vsprintf_new_cstr,
rb_tr_unwrap(rubyArgs)
)
);

return rb_enc_associate(string, enc);
}

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

0 comments on commit 84dcacc

Please sign in to comment.