Skip to content

Java generator: raise TypeError for a String key whose to_s is broken - #1129

Merged
byroot merged 1 commit into
ruby:masterfrom
sferik:java-string-subclass-key-to-s
Nov 5, 2026
Merged

byroot merged 1 commit into
ruby:masterfrom
sferik:java-string-subclass-key-to-s

Conversation

@sferik

@sferik sferik commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

On JRuby, a String subclass used as a Hash key whose to_s doesn't return a String is silently accepted:

require 'json'
klass = Class.new(String) { def to_s = false }
JSON.generate(klass.new("test") => 1)
# MRI:   TypeError: can't convert #<Class:0x...> to String (#<Class:0x...>#to_s gives FalseClass)
# JRuby: {"test":1}

generator.c raises in convert_string_subclass. The Java generator passed the result of to_s on and then fell back to TypeConverter.convertToType, which returned the key unchanged because it already is a String.

castKey now raises the same TypeError with the same message. Class names go through to_s, as PRIsVALUE does, so anonymous classes look the same as on CRuby. The pure-Ruby generator already raised a TypeError, so TruffleRuby needs no change.

When a Hash key is a String subclass, both generators call its to_s.
generator.c raises a TypeError in convert_string_subclass if to_s
doesn't return a String. The Java generator passed the result on, then
fell back to TypeConverter.convertToType, which returned the key itself
because it already is a String. So JSON.generate(s => 1) produced
{"test":1} on JRuby instead of raising.

Raise the same TypeError, with the same message, in castKey. The class
names go through to_s like PRIsVALUE does, so anonymous classes show as
#<Class:0x...> the way they do on CRuby.

This lets test_string_subclass_with_broken_to_s run on JRuby.

Part of ruby#1123
@byroot
byroot merged commit cf987b1 into ruby:master Nov 5, 2026
42 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants