Skip to content

Escape HTML Entities #763

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 54 additions & 7 deletions ext/json/ext/generator/generator.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ typedef struct JSON_Generator_StateStruct {
bool ascii_only;
bool script_safe;
bool strict;
bool escape_html_entities;
} JSON_Generator_State;

#ifndef RB_UNLIKELY
Expand All @@ -32,7 +33,7 @@ static VALUE mJSON, cState, cFragment, mString_Extend, eGeneratorError, eNesting

static ID i_to_s, i_to_json, i_new, i_pack, i_unpack, i_create_id, i_extend, i_encode;
static VALUE sym_indent, sym_space, sym_space_before, sym_object_nl, sym_array_nl, sym_max_nesting, sym_allow_nan,
sym_ascii_only, sym_depth, sym_buffer_initial_length, sym_script_safe, sym_escape_slash, sym_strict, sym_as_json;
sym_ascii_only, sym_depth, sym_buffer_initial_length, sym_script_safe, sym_escape_slash, sym_strict, sym_as_json, sym_escape_html_entities;


#define GET_STATE_TO(self, state) \
Expand Down Expand Up @@ -251,11 +252,11 @@ static const unsigned char script_safe_escape_table[256] = {
4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 9, 9,
};

static inline unsigned char search_script_safe_escape(search_state *search)
static inline unsigned char search_with_escape_table(search_state *search, unsigned char *table)
{
while (search->ptr < search->end) {
unsigned char ch = (unsigned char)*search->ptr;
unsigned char ch_len = script_safe_escape_table[ch];
unsigned char ch_len = table[ch];

if (RB_UNLIKELY(ch_len)) {
if (ch_len & ESCAPE_MASK) {
Expand All @@ -279,14 +280,39 @@ static inline unsigned char search_script_safe_escape(search_state *search)
return 0;
}

static void convert_UTF8_to_script_safe_JSON(search_state *search)
static inline void convert_UTF8_to_JSON_with_table(search_state *search, const unsigned char table[256])
{
unsigned char ch_len;
while ((ch_len = search_script_safe_escape(search))) {
while ((ch_len = search_with_escape_table(search, (unsigned char *)table))) {
escape_UTF8_char(search, ch_len);
}
}

static const unsigned char escape_html_entities_escape_table[256] = {
// ASCII Control Characters
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
// ASCII Characters
0, 0, 9, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, // '"', '&', and '/'
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 9, 0, // < and >
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, // '\\'
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// Continuation byte
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
// First byte of a 2-byte code point
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
// First byte of a 3-byte code point
3, 3,11, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xE2 is the start of \u2028 and \u2029
//First byte of a 4+ byte code point
4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 9, 9,
};
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This table is copy/pasted from script_safe with the exception of characters &, <, >.


static const unsigned char ascii_only_escape_table[256] = {
// ASCII Control Characters
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
Expand Down Expand Up @@ -977,9 +1003,11 @@ static void generate_json_string(FBuffer *buffer, struct generate_json_data *dat
case ENC_CODERANGE_7BIT:
case ENC_CODERANGE_VALID:
if (RB_UNLIKELY(state->ascii_only)) {
convert_UTF8_to_ASCII_only_JSON(&search, state->script_safe ? script_safe_escape_table : ascii_only_escape_table);
convert_UTF8_to_ASCII_only_JSON(&search, state->escape_html_entities ? escape_html_entities_escape_table : (state->script_safe ? script_safe_escape_table : ascii_only_escape_table));
} else if (RB_UNLIKELY(state->escape_html_entities)) {
convert_UTF8_to_JSON_with_table(&search, escape_html_entities_escape_table);
} else if (RB_UNLIKELY(state->script_safe)) {
convert_UTF8_to_script_safe_JSON(&search);
convert_UTF8_to_JSON_with_table(&search, script_safe_escape_table);
} else {
convert_UTF8_to_JSON(&search);
}
Expand Down Expand Up @@ -1609,6 +1637,19 @@ static VALUE cState_buffer_initial_length_set(VALUE self, VALUE buffer_initial_l
return Qnil;
}

static VALUE cState_escape_html_entities(VALUE self)
{
GET_STATE(self);
return state->escape_html_entities ? Qtrue : Qfalse;
}

static VALUE cState_escape_html_entities_set(VALUE self, VALUE val)
{
GET_STATE(self);
state->escape_html_entities = RTEST(val);
return val;
}

static int configure_state_i(VALUE key, VALUE val, VALUE _arg)
{
JSON_Generator_State *state = (JSON_Generator_State *)_arg;
Expand All @@ -1627,6 +1668,8 @@ static int configure_state_i(VALUE key, VALUE val, VALUE _arg)
else if (key == sym_escape_slash) { state->script_safe = RTEST(val); }
else if (key == sym_strict) { state->strict = RTEST(val); }
else if (key == sym_as_json) { state->as_json = RTEST(val) ? rb_convert_type(val, T_DATA, "Proc", "to_proc") : Qfalse; }
else if (key == sym_escape_html_entities) { state->escape_html_entities = RTEST(val); }

return ST_CONTINUE;
}

Expand Down Expand Up @@ -1740,6 +1783,9 @@ void Init_generator(void)
rb_define_method(cState, "depth=", cState_depth_set, 1);
rb_define_method(cState, "buffer_initial_length", cState_buffer_initial_length, 0);
rb_define_method(cState, "buffer_initial_length=", cState_buffer_initial_length_set, 1);
rb_define_method(cState, "escape_html_entities", cState_escape_html_entities, 0);
rb_define_method(cState, "escape_html_entities?", cState_escape_html_entities, 0);
rb_define_method(cState, "escape_html_entities=", cState_escape_html_entities_set, 1);
rb_define_method(cState, "generate", cState_generate, -1);
rb_define_alias(cState, "generate_new", "generate"); // :nodoc:

Expand Down Expand Up @@ -1813,6 +1859,7 @@ void Init_generator(void)
sym_escape_slash = ID2SYM(rb_intern("escape_slash"));
sym_strict = ID2SYM(rb_intern("strict"));
sym_as_json = ID2SYM(rb_intern("as_json"));
sym_escape_html_entities = ID2SYM(rb_intern("escape_html_entities"));

usascii_encindex = rb_usascii_encindex();
utf8_encindex = rb_utf8_encindex();
Expand Down
1 change: 1 addition & 0 deletions lib/json/ext/generator/state.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ def to_h
strict: strict?,
depth: depth,
buffer_initial_length: buffer_initial_length,
escape_html_entities: escape_html_entities?,
}

instance_variables.each do |iv|
Expand Down
65 changes: 65 additions & 0 deletions test/json/json_generator_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@

def test_pretty_state
state = JSON.create_pretty_state
assert_equal({

Check failure on line 204 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / macos-latest truffleruby-head

Failure

<[[:allow_nan, false], [:array_nl, "\n"], [:as_json, false], [:ascii_only, false], [:buffer_initial_length, 1024], [:depth, 0], [:escape_html_entities, false], [:indent, " "], [:max_nesting, 100], [:object_nl, "\n"], [:script_safe, false], [:space, " "], [:space_before, ""], [:strict, false]]> expected but was <[[:allow_nan, false], [:array_nl, "\n"], [:as_json, false], [:ascii_only, false], [:buffer_initial_length, 1024], [:depth, 0], [:indent, " "], [:max_nesting, 100], [:object_nl, "\n"], [:script_safe, false], [:space, " "], [:space_before, ""], [:strict, false]]>. diff: [[:allow_nan, false], [:array_nl, "\n"], [:as_json, false], [:ascii_only, false], [:buffer_initial_length, 1024], [:depth, 0], - [:escape_html_entities, false], [:indent, " "], [:max_nesting, 100], [:object_nl, "\n"], [:script_safe, false], [:space, " "], [:space_before, ""], [:strict, false]]

Check failure on line 204 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / macos-14 jruby-head

Error

NoMethodError: undefined method `escape_html_entities?' for #<JSON::Ext::Generator::State:0x28295554> Did you mean? escape_slash? /Users/runner/work/json/json/lib/json/ext/generator/state.rb:55:in `to_h' /Users/runner/work/json/json/test/json/json_generator_test.rb:204:in `test_pretty_state' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch'

Check failure on line 204 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / macos-14 jruby

Error

NoMethodError: undefined method `escape_html_entities?' for #<JSON::Ext::Generator::State:0x2904bc56> Did you mean? escape_slash? /Users/runner/work/json/json/lib/json/ext/generator/state.rb:55:in `to_h' /Users/runner/work/json/json/test/json/json_generator_test.rb:204:in `test_pretty_state' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch'

Check failure on line 204 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / ubuntu-latest jruby-9.4

Error

NoMethodError: undefined method `escape_html_entities?' for #<JSON::Ext::Generator::State:0x7981963f> Did you mean? escape_slash? /home/runner/work/json/json/lib/json/ext/generator/state.rb:55:in `to_h' /home/runner/work/json/json/test/json/json_generator_test.rb:204:in `test_pretty_state' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch'

Check failure on line 204 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / ubuntu-latest jruby

Error

NoMethodError: undefined method `escape_html_entities?' for #<JSON::Ext::Generator::State:0x79273a4f> Did you mean? escape_slash? /home/runner/work/json/json/lib/json/ext/generator/state.rb:55:in `to_h' /home/runner/work/json/json/test/json/json_generator_test.rb:204:in `test_pretty_state' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch'

Check failure on line 204 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / ubuntu-latest jruby-head

Error

NoMethodError: undefined method `escape_html_entities?' for #<JSON::Ext::Generator::State:0x31531d0d> Did you mean? escape_slash? /home/runner/work/json/json/lib/json/ext/generator/state.rb:55:in `to_h' /home/runner/work/json/json/test/json/json_generator_test.rb:204:in `test_pretty_state' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch'

Check failure on line 204 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / ubuntu-latest truffleruby-head

Failure

<[[:allow_nan, false], [:array_nl, "\n"], [:as_json, false], [:ascii_only, false], [:buffer_initial_length, 1024], [:depth, 0], [:escape_html_entities, false], [:indent, " "], [:max_nesting, 100], [:object_nl, "\n"], [:script_safe, false], [:space, " "], [:space_before, ""], [:strict, false]]> expected but was <[[:allow_nan, false], [:array_nl, "\n"], [:as_json, false], [:ascii_only, false], [:buffer_initial_length, 1024], [:depth, 0], [:indent, " "], [:max_nesting, 100], [:object_nl, "\n"], [:script_safe, false], [:space, " "], [:space_before, ""], [:strict, false]]>. diff: [[:allow_nan, false], [:array_nl, "\n"], [:as_json, false], [:ascii_only, false], [:buffer_initial_length, 1024], [:depth, 0], - [:escape_html_entities, false], [:indent, " "], [:max_nesting, 100], [:object_nl, "\n"], [:script_safe, false], [:space, " "], [:space_before, ""], [:strict, false]]
:allow_nan => false,
:array_nl => "\n",
:as_json => false,
Expand All @@ -215,12 +215,13 @@
:object_nl => "\n",
:space => " ",
:space_before => "",
:escape_html_entities => false,
}.sort_by { |n,| n.to_s }, state.to_h.sort_by { |n,| n.to_s })
end

def test_safe_state
state = JSON::State.new
assert_equal({

Check failure on line 224 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / macos-latest truffleruby-head

Failure

<[[:allow_nan, false], [:array_nl, ""], [:as_json, false], [:ascii_only, false], [:buffer_initial_length, 1024], [:depth, 0], [:escape_html_entities, false], [:indent, ""], [:max_nesting, 100], [:object_nl, ""], [:script_safe, false], [:space, ""], [:space_before, ""], [:strict, false]]> expected but was <[[:allow_nan, false], [:array_nl, ""], [:as_json, false], [:ascii_only, false], [:buffer_initial_length, 1024], [:depth, 0], [:indent, ""], [:max_nesting, 100], [:object_nl, ""], [:script_safe, false], [:space, ""], [:space_before, ""], [:strict, false]]>. diff: [[:allow_nan, false], [:array_nl, ""], [:as_json, false], [:ascii_only, false], [:buffer_initial_length, 1024], [:depth, 0], - [:escape_html_entities, false], [:indent, ""], [:max_nesting, 100], [:object_nl, ""], [:script_safe, false], [:space, ""], [:space_before, ""], [:strict, false]]

Check failure on line 224 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / macos-14 jruby-head

Error

NoMethodError: undefined method `escape_html_entities?' for #<JSON::Ext::Generator::State:0x3fe24670> Did you mean? escape_slash? /Users/runner/work/json/json/lib/json/ext/generator/state.rb:55:in `to_h' /Users/runner/work/json/json/test/json/json_generator_test.rb:224:in `test_safe_state' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch'

Check failure on line 224 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / macos-14 jruby

Error

NoMethodError: undefined method `escape_html_entities?' for #<JSON::Ext::Generator::State:0x662713b6> Did you mean? escape_slash? /Users/runner/work/json/json/lib/json/ext/generator/state.rb:55:in `to_h' /Users/runner/work/json/json/test/json/json_generator_test.rb:224:in `test_safe_state' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch'

Check failure on line 224 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / ubuntu-latest jruby-9.4

Error

NoMethodError: undefined method `escape_html_entities?' for #<JSON::Ext::Generator::State:0xc83ed77> Did you mean? escape_slash? /home/runner/work/json/json/lib/json/ext/generator/state.rb:55:in `to_h' /home/runner/work/json/json/test/json/json_generator_test.rb:224:in `test_safe_state' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch'

Check failure on line 224 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / ubuntu-latest jruby

Error

NoMethodError: undefined method `escape_html_entities?' for #<JSON::Ext::Generator::State:0x774c5e5c> Did you mean? escape_slash? /home/runner/work/json/json/lib/json/ext/generator/state.rb:55:in `to_h' /home/runner/work/json/json/test/json/json_generator_test.rb:224:in `test_safe_state' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch'

Check failure on line 224 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / ubuntu-latest jruby-head

Error

NoMethodError: undefined method `escape_html_entities?' for #<JSON::Ext::Generator::State:0x20afd96f> Did you mean? escape_slash? /home/runner/work/json/json/lib/json/ext/generator/state.rb:55:in `to_h' /home/runner/work/json/json/test/json/json_generator_test.rb:224:in `test_safe_state' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch'

Check failure on line 224 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / ubuntu-latest truffleruby-head

Failure

<[[:allow_nan, false], [:array_nl, ""], [:as_json, false], [:ascii_only, false], [:buffer_initial_length, 1024], [:depth, 0], [:escape_html_entities, false], [:indent, ""], [:max_nesting, 100], [:object_nl, ""], [:script_safe, false], [:space, ""], [:space_before, ""], [:strict, false]]> expected but was <[[:allow_nan, false], [:array_nl, ""], [:as_json, false], [:ascii_only, false], [:buffer_initial_length, 1024], [:depth, 0], [:indent, ""], [:max_nesting, 100], [:object_nl, ""], [:script_safe, false], [:space, ""], [:space_before, ""], [:strict, false]]>. diff: [[:allow_nan, false], [:array_nl, ""], [:as_json, false], [:ascii_only, false], [:buffer_initial_length, 1024], [:depth, 0], - [:escape_html_entities, false], [:indent, ""], [:max_nesting, 100], [:object_nl, ""], [:script_safe, false], [:space, ""], [:space_before, ""], [:strict, false]]
:allow_nan => false,
:array_nl => "",
:as_json => false,
Expand All @@ -234,12 +235,13 @@
:object_nl => "",
:space => "",
:space_before => "",
:escape_html_entities => false,
}.sort_by { |n,| n.to_s }, state.to_h.sort_by { |n,| n.to_s })
end

def test_fast_state
state = JSON.create_fast_state
assert_equal({

Check failure on line 244 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / macos-latest truffleruby-head

Failure

<[[:allow_nan, false], [:array_nl, ""], [:as_json, false], [:ascii_only, false], [:buffer_initial_length, 1024], [:depth, 0], [:escape_html_entities, false], [:indent, ""], [:max_nesting, 0], [:object_nl, ""], [:script_safe, false], [:space, ""], [:space_before, ""], [:strict, false]]> expected but was <[[:allow_nan, false], [:array_nl, ""], [:as_json, false], [:ascii_only, false], [:buffer_initial_length, 1024], [:depth, 0], [:indent, ""], [:max_nesting, 0], [:object_nl, ""], [:script_safe, false], [:space, ""], [:space_before, ""], [:strict, false]]>. diff: [[:allow_nan, false], [:array_nl, ""], [:as_json, false], [:ascii_only, false], [:buffer_initial_length, 1024], [:depth, 0], - [:escape_html_entities, false], [:indent, ""], [:max_nesting, 0], [:object_nl, ""], [:script_safe, false], [:space, ""], [:space_before, ""], [:strict, false]]

Check failure on line 244 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / macos-14 jruby-head

Error

NoMethodError: undefined method `escape_html_entities?' for #<JSON::Ext::Generator::State:0x13d5606c> Did you mean? escape_slash? /Users/runner/work/json/json/lib/json/ext/generator/state.rb:55:in `to_h' /Users/runner/work/json/json/test/json/json_generator_test.rb:244:in `test_fast_state' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch'

Check failure on line 244 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / macos-14 jruby

Error

NoMethodError: undefined method `escape_html_entities?' for #<JSON::Ext::Generator::State:0x6eb00cbe> Did you mean? escape_slash? /Users/runner/work/json/json/lib/json/ext/generator/state.rb:55:in `to_h' /Users/runner/work/json/json/test/json/json_generator_test.rb:244:in `test_fast_state' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch'

Check failure on line 244 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / ubuntu-latest jruby-9.4

Error

NoMethodError: undefined method `escape_html_entities?' for #<JSON::Ext::Generator::State:0x30133a11> Did you mean? escape_slash? /home/runner/work/json/json/lib/json/ext/generator/state.rb:55:in `to_h' /home/runner/work/json/json/test/json/json_generator_test.rb:244:in `test_fast_state' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch'

Check failure on line 244 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / ubuntu-latest jruby

Error

NoMethodError: undefined method `escape_html_entities?' for #<JSON::Ext::Generator::State:0x45e69324> Did you mean? escape_slash? /home/runner/work/json/json/lib/json/ext/generator/state.rb:55:in `to_h' /home/runner/work/json/json/test/json/json_generator_test.rb:244:in `test_fast_state' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch'

Check failure on line 244 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / ubuntu-latest jruby-head

Error

NoMethodError: undefined method `escape_html_entities?' for #<JSON::Ext::Generator::State:0x5621a671> Did you mean? escape_slash? /home/runner/work/json/json/lib/json/ext/generator/state.rb:55:in `to_h' /home/runner/work/json/json/test/json/json_generator_test.rb:244:in `test_fast_state' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch'

Check failure on line 244 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / ubuntu-latest truffleruby-head

Failure

<[[:allow_nan, false], [:array_nl, ""], [:as_json, false], [:ascii_only, false], [:buffer_initial_length, 1024], [:depth, 0], [:escape_html_entities, false], [:indent, ""], [:max_nesting, 0], [:object_nl, ""], [:script_safe, false], [:space, ""], [:space_before, ""], [:strict, false]]> expected but was <[[:allow_nan, false], [:array_nl, ""], [:as_json, false], [:ascii_only, false], [:buffer_initial_length, 1024], [:depth, 0], [:indent, ""], [:max_nesting, 0], [:object_nl, ""], [:script_safe, false], [:space, ""], [:space_before, ""], [:strict, false]]>. diff: [[:allow_nan, false], [:array_nl, ""], [:as_json, false], [:ascii_only, false], [:buffer_initial_length, 1024], [:depth, 0], - [:escape_html_entities, false], [:indent, ""], [:max_nesting, 0], [:object_nl, ""], [:script_safe, false], [:space, ""], [:space_before, ""], [:strict, false]]
:allow_nan => false,
:array_nl => "",
:as_json => false,
Expand All @@ -253,6 +255,7 @@
:object_nl => "",
:space => "",
:space_before => "",
:escape_html_entities => false,
}.sort_by { |n,| n.to_s }, state.to_h.sort_by { |n,| n.to_s })
end

Expand Down Expand Up @@ -382,7 +385,7 @@
state[:foo] = :bar
assert_equal :bar, state[:foo]
assert_equal :bar, state['foo']
state_hash = state.to_hash

Check failure on line 388 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / macos-14 jruby-head

Error

NoMethodError: undefined method `escape_html_entities?' for #<JSON::Ext::Generator::State:0x20be793a @foo=:bar> Did you mean? escape_slash? /Users/runner/work/json/json/lib/json/ext/generator/state.rb:55:in `to_h' /Users/runner/work/json/json/test/json/json_generator_test.rb:388:in `test_hash_likeness_set_symbol' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch'

Check failure on line 388 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / macos-14 jruby

Error

NoMethodError: undefined method `escape_html_entities?' for #<JSON::Ext::Generator::State:0x2567c091 @foo=:bar> Did you mean? escape_slash? /Users/runner/work/json/json/lib/json/ext/generator/state.rb:55:in `to_h' /Users/runner/work/json/json/test/json/json_generator_test.rb:388:in `test_hash_likeness_set_symbol' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch'

Check failure on line 388 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / ubuntu-latest jruby-9.4

Error

NoMethodError: undefined method `escape_html_entities?' for #<JSON::Ext::Generator::State:0x9f48198 @foo=:bar> Did you mean? escape_slash? /home/runner/work/json/json/lib/json/ext/generator/state.rb:55:in `to_h' /home/runner/work/json/json/test/json/json_generator_test.rb:388:in `test_hash_likeness_set_symbol' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch'

Check failure on line 388 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / ubuntu-latest jruby

Error

NoMethodError: undefined method `escape_html_entities?' for #<JSON::Ext::Generator::State:0x50fa5938 @foo=:bar> Did you mean? escape_slash? /home/runner/work/json/json/lib/json/ext/generator/state.rb:55:in `to_h' /home/runner/work/json/json/test/json/json_generator_test.rb:388:in `test_hash_likeness_set_symbol' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch'

Check failure on line 388 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / ubuntu-latest jruby-head

Error

NoMethodError: undefined method `escape_html_entities?' for #<JSON::Ext::Generator::State:0x16a499d1 @foo=:bar> Did you mean? escape_slash? /home/runner/work/json/json/lib/json/ext/generator/state.rb:55:in `to_h' /home/runner/work/json/json/test/json/json_generator_test.rb:388:in `test_hash_likeness_set_symbol' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch'
assert_kind_of Hash, state_hash
assert_equal :bar, state_hash[:foo]
end
Expand All @@ -394,14 +397,14 @@
state['foo'] = :bar
assert_equal :bar, state[:foo]
assert_equal :bar, state['foo']
state_hash = state.to_hash

Check failure on line 400 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / macos-14 jruby-head

Error

NoMethodError: undefined method `escape_html_entities?' for #<JSON::Ext::Generator::State:0x79e90571 @foo=:bar> Did you mean? escape_slash? /Users/runner/work/json/json/lib/json/ext/generator/state.rb:55:in `to_h' /Users/runner/work/json/json/test/json/json_generator_test.rb:400:in `test_hash_likeness_set_string' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch'

Check failure on line 400 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / macos-14 jruby

Error

NoMethodError: undefined method `escape_html_entities?' for #<JSON::Ext::Generator::State:0x5cdda548 @foo=:bar> Did you mean? escape_slash? /Users/runner/work/json/json/lib/json/ext/generator/state.rb:55:in `to_h' /Users/runner/work/json/json/test/json/json_generator_test.rb:400:in `test_hash_likeness_set_string' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch'

Check failure on line 400 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / ubuntu-latest jruby-9.4

Error

NoMethodError: undefined method `escape_html_entities?' for #<JSON::Ext::Generator::State:0x2bd2430f @foo=:bar> Did you mean? escape_slash? /home/runner/work/json/json/lib/json/ext/generator/state.rb:55:in `to_h' /home/runner/work/json/json/test/json/json_generator_test.rb:400:in `test_hash_likeness_set_string' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch'

Check failure on line 400 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / ubuntu-latest jruby

Error

NoMethodError: undefined method `escape_html_entities?' for #<JSON::Ext::Generator::State:0x41026e5c @foo=:bar> Did you mean? escape_slash? /home/runner/work/json/json/lib/json/ext/generator/state.rb:55:in `to_h' /home/runner/work/json/json/test/json/json_generator_test.rb:400:in `test_hash_likeness_set_string' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch'

Check failure on line 400 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / ubuntu-latest jruby-head

Error

NoMethodError: undefined method `escape_html_entities?' for #<JSON::Ext::Generator::State:0x44d84313 @foo=:bar> Did you mean? escape_slash? /home/runner/work/json/json/lib/json/ext/generator/state.rb:55:in `to_h' /home/runner/work/json/json/test/json/json_generator_test.rb:400:in `test_hash_likeness_set_string' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch'
assert_kind_of Hash, state_hash
assert_equal :bar, state_hash[:foo]
end

def test_json_state_to_h_roundtrip
state = JSON.state.new
assert_equal state.to_h, JSON.state.new(state.to_h).to_h

Check failure on line 407 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / macos-14 jruby-head

Error

NoMethodError: undefined method `escape_html_entities?' for #<JSON::Ext::Generator::State:0x5fafa76d> Did you mean? escape_slash? /Users/runner/work/json/json/lib/json/ext/generator/state.rb:55:in `to_h' /Users/runner/work/json/json/test/json/json_generator_test.rb:407:in `test_json_state_to_h_roundtrip' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch'

Check failure on line 407 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / macos-14 jruby

Error

NoMethodError: undefined method `escape_html_entities?' for #<JSON::Ext::Generator::State:0x67784537> Did you mean? escape_slash? /Users/runner/work/json/json/lib/json/ext/generator/state.rb:55:in `to_h' /Users/runner/work/json/json/test/json/json_generator_test.rb:407:in `test_json_state_to_h_roundtrip' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch'

Check failure on line 407 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / ubuntu-latest jruby-9.4

Error

NoMethodError: undefined method `escape_html_entities?' for #<JSON::Ext::Generator::State:0x115ef673> Did you mean? escape_slash? /home/runner/work/json/json/lib/json/ext/generator/state.rb:55:in `to_h' /home/runner/work/json/json/test/json/json_generator_test.rb:407:in `test_json_state_to_h_roundtrip' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch'

Check failure on line 407 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / ubuntu-latest jruby

Error

NoMethodError: undefined method `escape_html_entities?' for #<JSON::Ext::Generator::State:0x32d1d6c5> Did you mean? escape_slash? /home/runner/work/json/json/lib/json/ext/generator/state.rb:55:in `to_h' /home/runner/work/json/json/test/json/json_generator_test.rb:407:in `test_json_state_to_h_roundtrip' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch'

Check failure on line 407 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / ubuntu-latest jruby-head

Error

NoMethodError: undefined method `escape_html_entities?' for #<JSON::Ext::Generator::State:0x70e1aa20> Did you mean? escape_slash? /home/runner/work/json/json/lib/json/ext/generator/state.rb:55:in `to_h' /home/runner/work/json/json/test/json/json_generator_test.rb:407:in `test_json_state_to_h_roundtrip' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyArray.java:2009:in `each' org/jruby/RubyKernel.java:1426:in `catch' org/jruby/RubyKernel.java:1421:in `catch'
end

def test_json_generate
Expand Down Expand Up @@ -481,6 +484,68 @@
assert_equal json, generate(data, script_safe: true)
end

def test_escape_html_entities
data = [ '/' ]
json = '["\/"]'
assert_equal json, generate(data, :escape_html_entities => true)

Check failure on line 490 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / macos-latest truffleruby-head

Failure

<"[\"\\/\"]"> expected but was <"[\"/\"]">. diff: - ["\/"] ? - + ["/"]

Check failure on line 490 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / macos-14 jruby-head

Failure

<"[\"\\/\"]"> expected but was <"[\"/\"]">. diff: - ["\/"] ? - + ["/"]

Check failure on line 490 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / macos-14 jruby

Failure

<"[\"\\/\"]"> expected but was <"[\"/\"]">. diff: - ["\/"] ? - + ["/"]

Check failure on line 490 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / ubuntu-latest jruby-9.4

Failure

<"[\"\\/\"]"> expected but was <"[\"/\"]">. diff: - ["\/"] ? - + ["/"]

Check failure on line 490 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / ubuntu-latest jruby

Failure

<"[\"\\/\"]"> expected but was <"[\"/\"]">. diff: - ["\/"] ? - + ["/"]

Check failure on line 490 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / ubuntu-latest jruby-head

Failure

<"[\"\\/\"]"> expected but was <"[\"/\"]">. diff: - ["\/"] ? - + ["/"]

Check failure on line 490 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / ubuntu-latest truffleruby-head

Failure

<"[\"\\/\"]"> expected but was <"[\"/\"]">. diff: - ["\/"] ? - + ["/"]
#
data = [ "\u2028\u2029" ]
json = '["\u2028\u2029"]'
assert_equal json, generate(data, :escape_html_entities => true)
#
data = ['&']
json = '["\\u0026"]'
assert_equal json, generate(data, escape_html_entities: true)
#
data = ['<']
json = '["\\u003c"]'
assert_equal json, generate(data, escape_html_entities: true)
#
data = ['>']
json = '["\\u003e"]'
assert_equal json, generate(data, escape_html_entities: true)
#
data = ["倩", "瀨"]
json = '["倩","瀨"]'
assert_equal json, generate(data, escape_html_entities: true)
end

def test_escape_html_entities_priority_over_script_safe
data = ['&']
json = '["\\u0026"]'
assert_equal json, generate(data, escape_html_entities: true, script_safe: true)

Check failure on line 516 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / macos-latest truffleruby-head

Failure

<"[\"\\u0026\"]"> expected but was <"[\"&\"]">.

Check failure on line 516 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / macos-14 jruby-head

Failure

<"[\"\\u0026\"]"> expected but was <"[\"&\"]">.

Check failure on line 516 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / macos-14 jruby

Failure

<"[\"\\u0026\"]"> expected but was <"[\"&\"]">.

Check failure on line 516 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / ubuntu-latest jruby-9.4

Failure

<"[\"\\u0026\"]"> expected but was <"[\"&\"]">.

Check failure on line 516 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / ubuntu-latest jruby

Failure

<"[\"\\u0026\"]"> expected but was <"[\"&\"]">.

Check failure on line 516 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / ubuntu-latest jruby-head

Failure

<"[\"\\u0026\"]"> expected but was <"[\"&\"]">.

Check failure on line 516 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / ubuntu-latest truffleruby-head

Failure

<"[\"\\u0026\"]"> expected but was <"[\"&\"]">.
#
data = ['<']
json = '["\\u003c"]'
assert_equal json, generate(data, escape_html_entities: true, script_safe: true)
#
data = ['>']
json = '["\\u003e"]'
assert_equal json, generate(data, escape_html_entities: true, script_safe: true)
#
data = ['/']
json = '["\/"]'
assert_equal json, generate(data, escape_html_entities: true, script_safe: true)
#
data = ['&<>/']
json = '["\\u0026\\u003c\\u003e\/"]'
assert_equal json, generate(data, escape_html_entities: true, script_safe: true)
end

def test_ascii_only_with_escape_html_entities
data = ['é&<>']
json = '["\\u00e9\\u0026\\u003c\\u003e"]'
assert_equal json, generate(data, ascii_only: true, escape_html_entities: true)

Check failure on line 538 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / macos-latest truffleruby-head

Failure

<"[\"\\u00e9\\u0026\\u003c\\u003e\"]"> expected but was <"[\"\\u00e9&<>\"]">.

Check failure on line 538 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / macos-14 jruby-head

Failure

<"[\"\\u00e9\\u0026\\u003c\\u003e\"]"> expected but was <"[\"\\u00e9&<>\"]">.

Check failure on line 538 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / macos-14 jruby

Failure

<"[\"\\u00e9\\u0026\\u003c\\u003e\"]"> expected but was <"[\"\\u00e9&<>\"]">.

Check failure on line 538 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / ubuntu-latest jruby-9.4

Failure

<"[\"\\u00e9\\u0026\\u003c\\u003e\"]"> expected but was <"[\"\\u00e9&<>\"]">.

Check failure on line 538 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / ubuntu-latest jruby

Failure

<"[\"\\u00e9\\u0026\\u003c\\u003e\"]"> expected but was <"[\"\\u00e9&<>\"]">.

Check failure on line 538 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / ubuntu-latest jruby-head

Failure

<"[\"\\u00e9\\u0026\\u003c\\u003e\"]"> expected but was <"[\"\\u00e9&<>\"]">.

Check failure on line 538 in test/json/json_generator_test.rb

View workflow job for this annotation

GitHub Actions / ubuntu-latest truffleruby-head

Failure

<"[\"\\u00e9\\u0026\\u003c\\u003e\"]"> expected but was <"[\"\\u00e9&<>\"]">.
#
data = ['abc123']
json = '["abc123"]'
assert_equal json, generate(data, ascii_only: true, escape_html_entities: true)
#
data = ['倩瀨']
json = '["\\u5029\\u7028"]'
assert_equal json, generate(data, ascii_only: true, escape_html_entities: true)
end

def test_string_subclass
s = Class.new(String) do
def to_s; self; end
Expand Down
Loading