diff --git a/NEWS.md b/NEWS.md index b626d697e3efcf..8478a47caa3637 100644 --- a/NEWS.md +++ b/NEWS.md @@ -188,8 +188,8 @@ They are still available on rubygems.org and can be installed with * 0.8.2 to [v0.9.0][io-console-v0.9.0], [v0.9.1][io-console-v0.9.1], [v0.9.2][io-console-v0.9.2] * ipaddr 1.2.9 * 1.2.8 to [v1.2.9][ipaddr-v1.2.9] -* json 3.0.0.rc1 - * 2.18.0 to [v2.18.1][json-v2.18.1], [v2.19.0][json-v2.19.0], [v2.19.1][json-v2.19.1], [v2.19.2][json-v2.19.2], [v2.19.3][json-v2.19.3], [v2.19.4][json-v2.19.4], [v2.19.5][json-v2.19.5], [v2.19.6][json-v2.19.6], [v2.19.7][json-v2.19.7], [v2.19.8][json-v2.19.8], [v2.19.9][json-v2.19.9], [v2.20.0][json-v2.20.0], [v2.21.0][json-v2.21.0], [v2.21.2][json-v2.21.2], [v3.0.0.rc1][json-v3.0.0.rc1] +* json 3.0.0 + * 2.18.0 to [v2.18.1][json-v2.18.1], [v2.19.0][json-v2.19.0], [v2.19.1][json-v2.19.1], [v2.19.2][json-v2.19.2], [v2.19.3][json-v2.19.3], [v2.19.4][json-v2.19.4], [v2.19.5][json-v2.19.5], [v2.19.6][json-v2.19.6], [v2.19.7][json-v2.19.7], [v2.19.8][json-v2.19.8], [v2.19.9][json-v2.19.9], [v2.20.0][json-v2.20.0], [v2.21.0][json-v2.21.0], [v2.21.2][json-v2.21.2], [v3.0.0.rc1][json-v3.0.0.rc1], [v3.0.0][json-v3.0.0] * net-protocol 0.3.0 * 0.2.2 to [v0.3.0][net-protocol-v0.3.0] * openssl 4.0.2 @@ -442,6 +442,7 @@ A lot of work has gone into making Ractors more stable, performant, and usable. [json-v2.21.0]: https://github.com/ruby/json/releases/tag/v2.21.0 [json-v2.21.2]: https://github.com/ruby/json/releases/tag/v2.21.2 [json-v3.0.0.rc1]: https://github.com/ruby/json/releases/tag/v3.0.0.rc1 +[json-v3.0.0]: https://github.com/ruby/json/releases/tag/v3.0.0 [net-protocol-v0.3.0]: https://github.com/ruby/net-protocol/releases/tag/v0.3.0 [openssl-v4.0.1]: https://github.com/ruby/openssl/releases/tag/v4.0.1 [openssl-v4.0.2]: https://github.com/ruby/openssl/releases/tag/v4.0.2 diff --git a/common.mk b/common.mk index 17c1ae45358bc5..7b63cbd96db34a 100644 --- a/common.mk +++ b/common.mk @@ -1356,8 +1356,11 @@ clean-build-tool: $(srcdir)/revision.h$(no_baseruby:no=~disabled~): $(REVISION_H) +REVISION_H_CMD = $(BASERUBY) $(tooldir)/file2lastrev.rb -q --revision.h \ + --srcdir="$(srcdir)" --output=revision.h --timestamp=$(REVISION_H) + $(REVISION_H)$(no_baseruby:no=~disabled~): - $(Q) $(BASERUBY) $(tooldir)/file2lastrev.rb -q --revision.h --srcdir="$(srcdir)" --output=revision.h --timestamp=$@ + $(Q) $(REVISION_H_CMD) $(REVISION_H)$(yes_baseruby:yes=~disabled~): $(Q) exit > $@ @@ -1521,6 +1524,11 @@ update-src:: $(Q) $(RM) $(REVISION_H) revision.h "$(srcdir)/$(REVISION_H)" "$(srcdir)/revision.h" $(Q) exit > "$(srcdir)/revision.h" +# $(REVISION_H) can have been made already in this run, as a prerequisite +# of the included dependency file, and make does not make it twice. +update-src$(no_baseruby:no=~disabled~):: + $(Q) $(REVISION_H_CMD) + update-remote:: update-src update-download update-download:: $(ALWAYS_UPDATE_UNICODE:yes=update-unicode) update-download:: update-gems diff --git a/ext/json/lib/json/version.rb b/ext/json/lib/json/version.rb index 8e7e3175533fb1..eb53003aa73232 100644 --- a/ext/json/lib/json/version.rb +++ b/ext/json/lib/json/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module JSON - VERSION = '3.0.0.rc1' + VERSION = '3.0.0' end diff --git a/ext/json/parser/parser.c b/ext/json/parser/parser.c index fc6a7bbf62f626..5cba2feb6cdc1e 100644 --- a/ext/json/parser/parser.c +++ b/ext/json/parser/parser.c @@ -1041,6 +1041,9 @@ NOINLINE(static) VALUE json_string_unescape(JSON_ParserState *state, JSON_Parser raise_syntax_error_at("incomplete surrogate pair at %s", state, p); break; } + } else if ((ch & 0xFC00) == 0xDC00) { + raise_syntax_error_at("unpaired trailing surrogate at %s", state, p); + break; } int unescape_len = convert_UTF32_to_UTF8(buffer, ch); diff --git a/imemo.c b/imemo.c index 890b4ee9447a4a..8ef12feb7e8de8 100644 --- a/imemo.c +++ b/imemo.c @@ -298,7 +298,7 @@ rb_imemo_memsize(VALUE obj) case imemo_memo: break; case imemo_ment: - size += sizeof(((rb_method_entry_t *)obj)->def); + size += sizeof(struct rb_method_definition_struct); break; case imemo_svar: diff --git a/test/json/json_minefield_parser_test.rb b/test/json/json_minefield_parser_test.rb index e6dcb54b8d341b..5558014099f0d8 100644 --- a/test/json/json_minefield_parser_test.rb +++ b/test/json/json_minefield_parser_test.rb @@ -22,12 +22,9 @@ def define_test(name, &block) i_string_overlong_sequence_2_bytes i_string_not_in_unicode_range i_string_lone_utf8_continuation_byte - i_string_lone_second_surrogate i_string_iso_latin_1 i_string_invalid_utf-8 - i_string_incomplete_surrogate_pair i_string_UTF-8_invalid_sequence - i_object_key_lone_2nd_surrogate ) COMMENT_TESTS = %w( @@ -56,6 +53,9 @@ def define_test(name, &block) i_string_utf16BE_no_BOM i_string_utf16LE_no_BOM i_structure_UTF-8_BOM_empty_object + i_string_lone_second_surrogate + i_string_incomplete_surrogate_pair + i_object_key_lone_2nd_surrogate ) if RUBY_ENGINE == 'jruby' diff --git a/test/json/json_parser_test.rb b/test/json/json_parser_test.rb index 84839585fcc755..3e88442991566b 100644 --- a/test/json/json_parser_test.rb +++ b/test/json/json_parser_test.rb @@ -403,6 +403,15 @@ def test_invalid_surogates assert_raise(JSON::ParserError) { parse('"\\uD800_________________"') } assert_raise(JSON::ParserError) { parse('"\\uD800\\u0041"') } assert_raise(JSON::ParserError) { parse('"\\uD800\\u004') } + # Lone trailing surrogate (issue #1069): parser previously returned an + # invalid-UTF-8 String instead of raising. Symmetric to the leading cases + # above. + assert_raise(JSON::ParserError) { parse('"\\uDC00"') } + assert_raise(JSON::ParserError) { parse('"\\uDC00_________________"') } + assert_raise(JSON::ParserError) { parse('"\\uDC00\\uD800"') } + # Valid pair still parses to the astral codepoint U+10000. + assert_predicate JSON.parse('"\\uD800\\uDC00"'), :valid_encoding? + assert_equal "\u{10000}", JSON.parse('"\\uD800\\uDC00"') end def test_parse_big_integers