Skip to content

rb_str_resize(Qfalse, 0) with NKF and without C extensions lock #3625

Open
@eregon

Description

@eregon

Found by @mohamedhafez and reported on Slack:

class: TypeError
TruffleRuby doesn't have a case for the org.truffleruby.cext.CExtNodesFactory$RbStrResizeNodeFactory$RbStrResizeNodeGen node with values of type java.lang.Boolean=false java.lang.Integer=0
	from org.truffleruby.cext.CExtNodesFactory$RbStrResizeNodeFactory$RbStrResizeNodeGen.executeAndSpecialize(CExtNodesFactory.java:4234)
	from org.truffleruby.cext.CExtNodesFactory$RbStrResizeNodeFactory$RbStrResizeNodeGen.execute(CExtNodesFactory.java:4212)
	from org.truffleruby.language.RubyCoreMethodRootNode.execute(RubyCoreMethodRootNode.java:58)
string.c:197:in `rb_str_resize': TruffleRuby doesn't have a case for the org.truffleruby.cext.CExtNodesFactory$RbStrResizeNodeFactory$RbStrResizeNodeGen node with values of type java.lang.Boolean=false java.lang.Integer=0 (TypeError)
	from org.truffleruby.cext.CExtNodesFactory$RbStrResizeNodeFactory$RbStrResizeNodeGen.executeAndSpecialize(CExtNodesFactory.java:4234)
	from org.truffleruby.cext.CExtNodesFactory$RbStrResizeNodeFactory$RbStrResizeNodeGen.execute(CExtNodesFactory.java:4212)
	from org.truffleruby.language.RubyCoreMethodRootNode.execute(RubyCoreMethodRootNode.java:58)
	from string.c:197:in `rb_str_resize'
	from /Users/mohamed/.rbenv/versions/truffleruby+graalvm-24.0.1/lib/truffle/truffle/cext_ruby.rb:40:in `guess'
	from /Users/mohamed/rubyprojects/sa-mechanize/lib/mechanize/util.rb:58:in `detect_charset'
	from /Users/mohamed/rubyprojects/substitutealert/lib/ext/mechanize_additions.rb:22:in `initialize'

So this must be a call to rb_str_resize(str, 0) with str=0 but of course it shouldn't be 0.

Looking at NKF sources, there is a single call to rb_str_resize:

rb_str_resize(result, o_len);

result is a global variable 😨

static VALUE result;

/* use _result_ begin*/
result = tmp;
kanji_convert(NULL);
result = Qnil;
/* use _result_ end */

So that is very likely the issue.
One solution is to use a native thread-local variable instead.
Or pass it as an extra parameter but that would require touching more of the upstream nkf code.

Or, always use the C extensions lock/a lock for NKF.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions