diff options
Diffstat (limited to 'ext')
-rw-r--r-- | ext/-test-/thread_fd/depend | 161 | ||||
-rw-r--r-- | ext/-test-/thread_fd/extconf.rb | 2 | ||||
-rw-r--r-- | ext/-test-/thread_fd/thread_fd.c | 30 | ||||
-rw-r--r-- | ext/erb/escape/escape.c | 9 | ||||
-rw-r--r-- | ext/json/lib/json/common.rb | 4 | ||||
-rw-r--r-- | ext/json/lib/json/version.rb | 2 | ||||
-rw-r--r-- | ext/json/parser/parser.c | 251 | ||||
-rw-r--r-- | ext/json/vendor/fpconv.c | 4 | ||||
-rw-r--r-- | ext/psych/lib/psych/versions.rb | 2 | ||||
-rw-r--r-- | ext/psych/lib/psych/visitors/yaml_tree.rb | 2 | ||||
-rw-r--r-- | ext/stringio/depend | 1 | ||||
-rw-r--r-- | ext/stringio/stringio.c | 10 |
12 files changed, 175 insertions, 303 deletions
diff --git a/ext/-test-/thread_fd/depend b/ext/-test-/thread_fd/depend deleted file mode 100644 index 0fda9f6dbf..0000000000 --- a/ext/-test-/thread_fd/depend +++ /dev/null @@ -1,161 +0,0 @@ -# AUTOGENERATED DEPENDENCIES START -thread_fd.o: $(RUBY_EXTCONF_H) -thread_fd.o: $(arch_hdrdir)/ruby/config.h -thread_fd.o: $(hdrdir)/ruby/assert.h -thread_fd.o: $(hdrdir)/ruby/backward.h -thread_fd.o: $(hdrdir)/ruby/backward/2/assume.h -thread_fd.o: $(hdrdir)/ruby/backward/2/attributes.h -thread_fd.o: $(hdrdir)/ruby/backward/2/bool.h -thread_fd.o: $(hdrdir)/ruby/backward/2/inttypes.h -thread_fd.o: $(hdrdir)/ruby/backward/2/limits.h -thread_fd.o: $(hdrdir)/ruby/backward/2/long_long.h -thread_fd.o: $(hdrdir)/ruby/backward/2/stdalign.h -thread_fd.o: $(hdrdir)/ruby/backward/2/stdarg.h -thread_fd.o: $(hdrdir)/ruby/defines.h -thread_fd.o: $(hdrdir)/ruby/intern.h -thread_fd.o: $(hdrdir)/ruby/internal/abi.h -thread_fd.o: $(hdrdir)/ruby/internal/anyargs.h -thread_fd.o: $(hdrdir)/ruby/internal/arithmetic.h -thread_fd.o: $(hdrdir)/ruby/internal/arithmetic/char.h -thread_fd.o: $(hdrdir)/ruby/internal/arithmetic/double.h -thread_fd.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h -thread_fd.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h -thread_fd.o: $(hdrdir)/ruby/internal/arithmetic/int.h -thread_fd.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h -thread_fd.o: $(hdrdir)/ruby/internal/arithmetic/long.h -thread_fd.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h -thread_fd.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h -thread_fd.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h -thread_fd.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h -thread_fd.o: $(hdrdir)/ruby/internal/arithmetic/short.h -thread_fd.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h -thread_fd.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h -thread_fd.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h -thread_fd.o: $(hdrdir)/ruby/internal/assume.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/alloc_size.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/artificial.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/cold.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/const.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/constexpr.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/deprecated.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/error.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/flag_enum.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/forceinline.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/format.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/noalias.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/nodiscard.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/noexcept.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/noinline.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/nonnull.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/noreturn.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/packed_struct.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/pure.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/restrict.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/warning.h -thread_fd.o: $(hdrdir)/ruby/internal/attr/weakref.h -thread_fd.o: $(hdrdir)/ruby/internal/cast.h -thread_fd.o: $(hdrdir)/ruby/internal/compiler_is.h -thread_fd.o: $(hdrdir)/ruby/internal/compiler_is/apple.h -thread_fd.o: $(hdrdir)/ruby/internal/compiler_is/clang.h -thread_fd.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h -thread_fd.o: $(hdrdir)/ruby/internal/compiler_is/intel.h -thread_fd.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h -thread_fd.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h -thread_fd.o: $(hdrdir)/ruby/internal/compiler_since.h -thread_fd.o: $(hdrdir)/ruby/internal/config.h -thread_fd.o: $(hdrdir)/ruby/internal/constant_p.h -thread_fd.o: $(hdrdir)/ruby/internal/core.h -thread_fd.o: $(hdrdir)/ruby/internal/core/rarray.h -thread_fd.o: $(hdrdir)/ruby/internal/core/rbasic.h -thread_fd.o: $(hdrdir)/ruby/internal/core/rbignum.h -thread_fd.o: $(hdrdir)/ruby/internal/core/rclass.h -thread_fd.o: $(hdrdir)/ruby/internal/core/rdata.h -thread_fd.o: $(hdrdir)/ruby/internal/core/rfile.h -thread_fd.o: $(hdrdir)/ruby/internal/core/rhash.h -thread_fd.o: $(hdrdir)/ruby/internal/core/robject.h -thread_fd.o: $(hdrdir)/ruby/internal/core/rregexp.h -thread_fd.o: $(hdrdir)/ruby/internal/core/rstring.h -thread_fd.o: $(hdrdir)/ruby/internal/core/rstruct.h -thread_fd.o: $(hdrdir)/ruby/internal/core/rtypeddata.h -thread_fd.o: $(hdrdir)/ruby/internal/ctype.h -thread_fd.o: $(hdrdir)/ruby/internal/dllexport.h -thread_fd.o: $(hdrdir)/ruby/internal/dosish.h -thread_fd.o: $(hdrdir)/ruby/internal/error.h -thread_fd.o: $(hdrdir)/ruby/internal/eval.h -thread_fd.o: $(hdrdir)/ruby/internal/event.h -thread_fd.o: $(hdrdir)/ruby/internal/fl_type.h -thread_fd.o: $(hdrdir)/ruby/internal/gc.h -thread_fd.o: $(hdrdir)/ruby/internal/glob.h -thread_fd.o: $(hdrdir)/ruby/internal/globals.h -thread_fd.o: $(hdrdir)/ruby/internal/has/attribute.h -thread_fd.o: $(hdrdir)/ruby/internal/has/builtin.h -thread_fd.o: $(hdrdir)/ruby/internal/has/c_attribute.h -thread_fd.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h -thread_fd.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h -thread_fd.o: $(hdrdir)/ruby/internal/has/extension.h -thread_fd.o: $(hdrdir)/ruby/internal/has/feature.h -thread_fd.o: $(hdrdir)/ruby/internal/has/warning.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/array.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/bignum.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/class.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/compar.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/complex.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/cont.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/dir.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/enum.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/enumerator.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/error.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/eval.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/file.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/hash.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/io.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/load.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/marshal.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/numeric.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/object.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/parse.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/proc.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/process.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/random.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/range.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/rational.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/re.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/ruby.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/select.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/select/largesize.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/signal.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/sprintf.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/string.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/struct.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/thread.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/time.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/variable.h -thread_fd.o: $(hdrdir)/ruby/internal/intern/vm.h -thread_fd.o: $(hdrdir)/ruby/internal/interpreter.h -thread_fd.o: $(hdrdir)/ruby/internal/iterator.h -thread_fd.o: $(hdrdir)/ruby/internal/memory.h -thread_fd.o: $(hdrdir)/ruby/internal/method.h -thread_fd.o: $(hdrdir)/ruby/internal/module.h -thread_fd.o: $(hdrdir)/ruby/internal/newobj.h -thread_fd.o: $(hdrdir)/ruby/internal/scan_args.h -thread_fd.o: $(hdrdir)/ruby/internal/special_consts.h -thread_fd.o: $(hdrdir)/ruby/internal/static_assert.h -thread_fd.o: $(hdrdir)/ruby/internal/stdalign.h -thread_fd.o: $(hdrdir)/ruby/internal/stdbool.h -thread_fd.o: $(hdrdir)/ruby/internal/stdckdint.h -thread_fd.o: $(hdrdir)/ruby/internal/symbol.h -thread_fd.o: $(hdrdir)/ruby/internal/value.h -thread_fd.o: $(hdrdir)/ruby/internal/value_type.h -thread_fd.o: $(hdrdir)/ruby/internal/variable.h -thread_fd.o: $(hdrdir)/ruby/internal/warning_push.h -thread_fd.o: $(hdrdir)/ruby/internal/xmalloc.h -thread_fd.o: $(hdrdir)/ruby/missing.h -thread_fd.o: $(hdrdir)/ruby/ruby.h -thread_fd.o: $(hdrdir)/ruby/st.h -thread_fd.o: $(hdrdir)/ruby/subst.h -thread_fd.o: thread_fd.c -# AUTOGENERATED DEPENDENCIES END diff --git a/ext/-test-/thread_fd/extconf.rb b/ext/-test-/thread_fd/extconf.rb deleted file mode 100644 index a8bbe9d169..0000000000 --- a/ext/-test-/thread_fd/extconf.rb +++ /dev/null @@ -1,2 +0,0 @@ -# frozen_string_literal: true -create_makefile('-test-/thread_fd') diff --git a/ext/-test-/thread_fd/thread_fd.c b/ext/-test-/thread_fd/thread_fd.c deleted file mode 100644 index 042b799dc8..0000000000 --- a/ext/-test-/thread_fd/thread_fd.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "ruby/ruby.h" - -static VALUE -thread_fd_close(VALUE ign, VALUE fd) -{ - rb_thread_fd_close(NUM2INT(fd)); - return Qnil; -} - -static VALUE -thread_fd_wait(VALUE ign, VALUE fd) -{ - int ret = rb_thread_wait_fd(NUM2INT(fd)); - return INT2NUM(ret); -} - -static VALUE -thread_fd_writable(VALUE ign, VALUE fd) -{ - int ret = rb_thread_fd_writable(NUM2INT(fd)); - return INT2NUM(ret); -} - -void -Init_thread_fd(void) -{ - rb_define_singleton_method(rb_cIO, "thread_fd_close", thread_fd_close, 1); - rb_define_singleton_method(rb_cIO, "thread_fd_wait", thread_fd_wait, 1); - rb_define_singleton_method(rb_cIO, "thread_fd_writable", thread_fd_writable, 1); -} diff --git a/ext/erb/escape/escape.c b/ext/erb/escape/escape.c index 67b2d1ef34..db2abd9773 100644 --- a/ext/erb/escape/escape.c +++ b/ext/erb/escape/escape.c @@ -65,9 +65,12 @@ optimized_escape_html(VALUE str) return escaped; } -// ERB::Util.html_escape is different from CGI.escapeHTML in the following two parts: -// * ERB::Util.html_escape converts an argument with #to_s first (only if it's not T_STRING) -// * ERB::Util.html_escape does not allocate a new string when nothing needs to be escaped +/* + * ERB::Util.html_escape is similar to CGI.escapeHTML but different in the following two parts: + * + * * ERB::Util.html_escape converts an argument with #to_s first (only if it's not T_STRING) + * * ERB::Util.html_escape does not allocate a new string when nothing needs to be escaped + */ static VALUE erb_escape_html(VALUE self, VALUE str) { diff --git a/ext/json/lib/json/common.rb b/ext/json/lib/json/common.rb index 98bc0ac85a..7627761b52 100644 --- a/ext/json/lib/json/common.rb +++ b/ext/json/lib/json/common.rb @@ -230,7 +230,9 @@ module JSON class JSONError < StandardError; end # This exception is raised if a parser error occurs. - class ParserError < JSONError; end + class ParserError < JSONError + attr_reader :line, :column + end # This exception is raised if the nesting of parsed data structures is too # deep. diff --git a/ext/json/lib/json/version.rb b/ext/json/lib/json/version.rb index c8744c9732..45d2b0a1fb 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 = '2.11.3' + VERSION = '2.12.0' end diff --git a/ext/json/parser/parser.c b/ext/json/parser/parser.c index f20769a365..c5f300183d 100644 --- a/ext/json/parser/parser.c +++ b/ext/json/parser/parser.c @@ -337,33 +337,128 @@ static size_t strnlen(const char *s, size_t maxlen) } #endif +static int convert_UTF32_to_UTF8(char *buf, uint32_t ch) +{ + int len = 1; + if (ch <= 0x7F) { + buf[0] = (char) ch; + } else if (ch <= 0x07FF) { + buf[0] = (char) ((ch >> 6) | 0xC0); + buf[1] = (char) ((ch & 0x3F) | 0x80); + len++; + } else if (ch <= 0xFFFF) { + buf[0] = (char) ((ch >> 12) | 0xE0); + buf[1] = (char) (((ch >> 6) & 0x3F) | 0x80); + buf[2] = (char) ((ch & 0x3F) | 0x80); + len += 2; + } else if (ch <= 0x1fffff) { + buf[0] =(char) ((ch >> 18) | 0xF0); + buf[1] =(char) (((ch >> 12) & 0x3F) | 0x80); + buf[2] =(char) (((ch >> 6) & 0x3F) | 0x80); + buf[3] =(char) ((ch & 0x3F) | 0x80); + len += 3; + } else { + buf[0] = '?'; + } + return len; +} + +typedef struct JSON_ParserStruct { + VALUE on_load_proc; + VALUE decimal_class; + ID decimal_method_id; + int max_nesting; + bool allow_nan; + bool allow_trailing_comma; + bool parsing_name; + bool symbolize_names; + bool freeze; +} JSON_ParserConfig; + +typedef struct JSON_ParserStateStruct { + VALUE stack_handle; + const char *start; + const char *cursor; + const char *end; + rvalue_stack *stack; + rvalue_cache name_cache; + int in_array; + int current_nesting; +} JSON_ParserState; + + #define PARSE_ERROR_FRAGMENT_LEN 32 #ifdef RBIMPL_ATTR_NORETURN RBIMPL_ATTR_NORETURN() #endif -static void raise_parse_error(const char *format, const char *start) +static void raise_parse_error(const char *format, JSON_ParserState *state) { - unsigned char buffer[PARSE_ERROR_FRAGMENT_LEN + 1]; + unsigned char buffer[PARSE_ERROR_FRAGMENT_LEN + 3]; - size_t len = start ? strnlen(start, PARSE_ERROR_FRAGMENT_LEN) : 0; - const char *ptr = start; + const char *cursor = state->cursor; + long column = 0; + long line = 1; - if (len == PARSE_ERROR_FRAGMENT_LEN) { - MEMCPY(buffer, start, char, PARSE_ERROR_FRAGMENT_LEN); + while (cursor >= state->start) { + if (*cursor-- == '\n') { + break; + } + column++; + } - while (buffer[len - 1] >= 0x80 && buffer[len - 1] < 0xC0) { // Is continuation byte - len--; + while (cursor >= state->start) { + if (*cursor-- == '\n') { + line++; } + } - if (buffer[len - 1] >= 0xC0) { // multibyte character start - len--; + const char *ptr = "EOF"; + if (state->cursor && state->cursor < state->end) { + ptr = state->cursor; + size_t len = 0; + while (len < PARSE_ERROR_FRAGMENT_LEN) { + char ch = ptr[len]; + if (!ch || ch == '\n' || ch == ' ' || ch == '\t' || ch == '\r') { + break; + } + len++; } - buffer[len] = '\0'; - ptr = (const char *)buffer; + if (len) { + buffer[0] = '\''; + MEMCPY(buffer + 1, ptr, char, len); + + while (buffer[len] >= 0x80 && buffer[len] < 0xC0) { // Is continuation byte + len--; + } + + if (buffer[len] >= 0xC0) { // multibyte character start + len--; + } + + buffer[len + 1] = '\''; + buffer[len + 2] = '\0'; + ptr = (const char *)buffer; + } } - rb_enc_raise(enc_utf8, rb_path2class("JSON::ParserError"), format, ptr); + VALUE msg = rb_sprintf(format, ptr); + VALUE message = rb_enc_sprintf(enc_utf8, "%s at line %ld column %ld", RSTRING_PTR(msg), line, column); + RB_GC_GUARD(msg); + + VALUE exc = rb_exc_new_str(rb_path2class("JSON::ParserError"), message); + rb_ivar_set(exc, rb_intern("@line"), LONG2NUM(line)); + rb_ivar_set(exc, rb_intern("@column"), LONG2NUM(column)); + rb_exc_raise(exc); +} + +#ifdef RBIMPL_ATTR_NORETURN +RBIMPL_ATTR_NORETURN() +#endif +static void raise_parse_error_at(const char *format, JSON_ParserState *state, const char *at) +{ + state->cursor = at; + raise_parse_error(format, state); } /* unicode */ @@ -385,73 +480,25 @@ static const signed char digit_values[256] = { -1, -1, -1, -1, -1, -1, -1 }; -static uint32_t unescape_unicode(const unsigned char *p) +static uint32_t unescape_unicode(JSON_ParserState *state, const unsigned char *p) { signed char b; uint32_t result = 0; b = digit_values[p[0]]; - if (b < 0) raise_parse_error("incomplete unicode character escape sequence at '%s'", (char *)p - 2); + if (b < 0) raise_parse_error_at("incomplete unicode character escape sequence at %s", state, (char *)p - 2); result = (result << 4) | (unsigned char)b; b = digit_values[p[1]]; - if (b < 0) raise_parse_error("incomplete unicode character escape sequence at '%s'", (char *)p - 2); + if (b < 0) raise_parse_error_at("incomplete unicode character escape sequence at %s", state, (char *)p - 2); result = (result << 4) | (unsigned char)b; b = digit_values[p[2]]; - if (b < 0) raise_parse_error("incomplete unicode character escape sequence at '%s'", (char *)p - 2); + if (b < 0) raise_parse_error_at("incomplete unicode character escape sequence at %s", state, (char *)p - 2); result = (result << 4) | (unsigned char)b; b = digit_values[p[3]]; - if (b < 0) raise_parse_error("incomplete unicode character escape sequence at '%s'", (char *)p - 2); + if (b < 0) raise_parse_error_at("incomplete unicode character escape sequence at %s", state, (char *)p - 2); result = (result << 4) | (unsigned char)b; return result; } -static int convert_UTF32_to_UTF8(char *buf, uint32_t ch) -{ - int len = 1; - if (ch <= 0x7F) { - buf[0] = (char) ch; - } else if (ch <= 0x07FF) { - buf[0] = (char) ((ch >> 6) | 0xC0); - buf[1] = (char) ((ch & 0x3F) | 0x80); - len++; - } else if (ch <= 0xFFFF) { - buf[0] = (char) ((ch >> 12) | 0xE0); - buf[1] = (char) (((ch >> 6) & 0x3F) | 0x80); - buf[2] = (char) ((ch & 0x3F) | 0x80); - len += 2; - } else if (ch <= 0x1fffff) { - buf[0] =(char) ((ch >> 18) | 0xF0); - buf[1] =(char) (((ch >> 12) & 0x3F) | 0x80); - buf[2] =(char) (((ch >> 6) & 0x3F) | 0x80); - buf[3] =(char) ((ch & 0x3F) | 0x80); - len += 3; - } else { - buf[0] = '?'; - } - return len; -} - -typedef struct JSON_ParserStruct { - VALUE on_load_proc; - VALUE decimal_class; - ID decimal_method_id; - int max_nesting; - bool allow_nan; - bool allow_trailing_comma; - bool parsing_name; - bool symbolize_names; - bool freeze; -} JSON_ParserConfig; - -typedef struct JSON_ParserStateStruct { - VALUE stack_handle; - const char *cursor; - const char *end; - rvalue_stack *stack; - rvalue_cache name_cache; - int in_array; - int current_nesting; -} JSON_ParserState; - #define GET_PARSER_CONFIG \ JSON_ParserConfig *config; \ TypedData_Get_Struct(self, JSON_ParserConfig, &JSON_ParserConfig_type, config) @@ -485,8 +532,7 @@ json_eat_comments(JSON_ParserState *state) while (true) { state->cursor = memchr(state->cursor, '*', state->end - state->cursor); if (!state->cursor) { - state->cursor = state->end; - raise_parse_error("unexpected end of input, expected closing '*/'", state->cursor); + raise_parse_error_at("unexpected end of input, expected closing '*/'", state, state->end); } else { state->cursor++; if (state->cursor < state->end && *state->cursor == '/') { @@ -498,11 +544,11 @@ json_eat_comments(JSON_ParserState *state) break; } default: - raise_parse_error("unexpected token at '%s'", state->cursor); + raise_parse_error("unexpected token %s", state); break; } } else { - raise_parse_error("unexpected token at '%s'", state->cursor); + raise_parse_error("unexpected token %s", state); } } @@ -621,9 +667,9 @@ static VALUE json_string_unescape(JSON_ParserState *state, const char *string, c break; case 'u': if (pe > stringEnd - 5) { - raise_parse_error("incomplete unicode character escape sequence at '%s'", p); + raise_parse_error_at("incomplete unicode character escape sequence at %s", state, p); } else { - uint32_t ch = unescape_unicode((unsigned char *) ++pe); + uint32_t ch = unescape_unicode(state, (unsigned char *) ++pe); pe += 3; /* To handle values above U+FFFF, we take a sequence of * \uXXXX escapes in the U+D800..U+DBFF then @@ -638,10 +684,10 @@ static VALUE json_string_unescape(JSON_ParserState *state, const char *string, c if ((ch & 0xFC00) == 0xD800) { pe++; if (pe > stringEnd - 6) { - raise_parse_error("incomplete surrogate pair at '%s'", p); + raise_parse_error_at("incomplete surrogate pair at %s", state, p); } if (pe[0] == '\\' && pe[1] == 'u') { - uint32_t sur = unescape_unicode((unsigned char *) pe + 2); + uint32_t sur = unescape_unicode(state, (unsigned char *) pe + 2); ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16) | (sur & 0x3FF)); pe += 5; @@ -829,12 +875,12 @@ static inline VALUE json_parse_string(JSON_ParserState *state, JSON_ParserConfig state->cursor++; escaped = true; if ((unsigned char)*state->cursor < 0x20) { - raise_parse_error("invalid ASCII control character in string: %s", state->cursor); + raise_parse_error("invalid ASCII control character in string: %s", state); } break; } default: - raise_parse_error("invalid ASCII control character in string: %s", state->cursor); + raise_parse_error("invalid ASCII control character in string: %s", state); break; } } @@ -842,7 +888,7 @@ static inline VALUE json_parse_string(JSON_ParserState *state, JSON_ParserConfig state->cursor++; } - raise_parse_error("unexpected end of input, expected closing \"", state->cursor); + raise_parse_error("unexpected end of input, expected closing \"", state); return Qfalse; } @@ -850,7 +896,7 @@ static VALUE json_parse_any(JSON_ParserState *state, JSON_ParserConfig *config) { json_eat_whitespace(state); if (state->cursor >= state->end) { - raise_parse_error("unexpected end of input", state->cursor); + raise_parse_error("unexpected end of input", state); } switch (*state->cursor) { @@ -860,7 +906,7 @@ static VALUE json_parse_any(JSON_ParserState *state, JSON_ParserConfig *config) return json_push_value(state, config, Qnil); } - raise_parse_error("unexpected token at '%s'", state->cursor); + raise_parse_error("unexpected token %s", state); break; case 't': if ((state->end - state->cursor >= 4) && (memcmp(state->cursor, "true", 4) == 0)) { @@ -868,7 +914,7 @@ static VALUE json_parse_any(JSON_ParserState *state, JSON_ParserConfig *config) return json_push_value(state, config, Qtrue); } - raise_parse_error("unexpected token at '%s'", state->cursor); + raise_parse_error("unexpected token %s", state); break; case 'f': // Note: memcmp with a small power of two compile to an integer comparison @@ -877,7 +923,7 @@ static VALUE json_parse_any(JSON_ParserState *state, JSON_ParserConfig *config) return json_push_value(state, config, Qfalse); } - raise_parse_error("unexpected token at '%s'", state->cursor); + raise_parse_error("unexpected token %s", state); break; case 'N': // Note: memcmp with a small power of two compile to an integer comparison @@ -886,7 +932,7 @@ static VALUE json_parse_any(JSON_ParserState *state, JSON_ParserConfig *config) return json_push_value(state, config, CNaN); } - raise_parse_error("unexpected token at '%s'", state->cursor); + raise_parse_error("unexpected token %s", state); break; case 'I': if (config->allow_nan && (state->end - state->cursor >= 8) && (memcmp(state->cursor, "Infinity", 8) == 0)) { @@ -894,7 +940,7 @@ static VALUE json_parse_any(JSON_ParserState *state, JSON_ParserConfig *config) return json_push_value(state, config, CInfinity); } - raise_parse_error("unexpected token at '%s'", state->cursor); + raise_parse_error("unexpected token %s", state); break; case '-': // Note: memcmp with a small power of two compile to an integer comparison @@ -903,7 +949,7 @@ static VALUE json_parse_any(JSON_ParserState *state, JSON_ParserConfig *config) state->cursor += 9; return json_push_value(state, config, CMinusInfinity); } else { - raise_parse_error("unexpected token at '%s'", state->cursor); + raise_parse_error("unexpected token %s", state); } } // Fallthrough @@ -921,11 +967,11 @@ static VALUE json_parse_any(JSON_ParserState *state, JSON_ParserConfig *config) long integer_length = state->cursor - start; if (RB_UNLIKELY(start[0] == '0' && integer_length > 1)) { - raise_parse_error("invalid number: %s", start); + raise_parse_error_at("invalid number: %s", state, start); } else if (RB_UNLIKELY(integer_length > 2 && start[0] == '-' && start[1] == '0')) { - raise_parse_error("invalid number: %s", start); + raise_parse_error_at("invalid number: %s", state, start); } else if (RB_UNLIKELY(integer_length == 1 && start[0] == '-')) { - raise_parse_error("invalid number: %s", start); + raise_parse_error_at("invalid number: %s", state, start); } if ((state->cursor < state->end) && (*state->cursor == '.')) { @@ -933,7 +979,7 @@ static VALUE json_parse_any(JSON_ParserState *state, JSON_ParserConfig *config) state->cursor++; if (state->cursor == state->end || *state->cursor < '0' || *state->cursor > '9') { - raise_parse_error("invalid number: %s", state->cursor); + raise_parse_error("invalid number: %s", state); } while ((state->cursor < state->end) && (*state->cursor >= '0') && (*state->cursor <= '9')) { @@ -949,7 +995,7 @@ static VALUE json_parse_any(JSON_ParserState *state, JSON_ParserConfig *config) } if (state->cursor == state->end || *state->cursor < '0' || *state->cursor > '9') { - raise_parse_error("invalid number: %s", state->cursor); + raise_parse_error("invalid number: %s", state); } while ((state->cursor < state->end) && (*state->cursor >= '0') && (*state->cursor <= '9')) { @@ -1009,7 +1055,7 @@ static VALUE json_parse_any(JSON_ParserState *state, JSON_ParserConfig *config) } } - raise_parse_error("expected ',' or ']' after array value", state->cursor); + raise_parse_error("expected ',' or ']' after array value", state); } break; } @@ -1028,13 +1074,13 @@ static VALUE json_parse_any(JSON_ParserState *state, JSON_ParserConfig *config) } if (*state->cursor != '"') { - raise_parse_error("expected object key, got '%s", state->cursor); + raise_parse_error("expected object key, got %s", state); } json_parse_string(state, config, true); json_eat_whitespace(state); if ((state->cursor >= state->end) || (*state->cursor != ':')) { - raise_parse_error("expected ':' after object key", state->cursor); + raise_parse_error("expected ':' after object key", state); } state->cursor++; @@ -1063,13 +1109,13 @@ static VALUE json_parse_any(JSON_ParserState *state, JSON_ParserConfig *config) } if (*state->cursor != '"') { - raise_parse_error("expected object key, got: '%s'", state->cursor); + raise_parse_error("expected object key, got: %s", state); } json_parse_string(state, config, true); json_eat_whitespace(state); if ((state->cursor >= state->end) || (*state->cursor != ':')) { - raise_parse_error("expected ':' after object key, got: '%s", state->cursor); + raise_parse_error("expected ':' after object key, got: %s", state); } state->cursor++; @@ -1079,24 +1125,24 @@ static VALUE json_parse_any(JSON_ParserState *state, JSON_ParserConfig *config) } } - raise_parse_error("expected ',' or '}' after object value, got: '%s'", state->cursor); + raise_parse_error("expected ',' or '}' after object value, got: %s", state); } break; } default: - raise_parse_error("unexpected character: '%s'", state->cursor); + raise_parse_error("unexpected character: %s", state); break; } - raise_parse_error("unreacheable: '%s'", state->cursor); + raise_parse_error("unreacheable: %s", state); } static void json_ensure_eof(JSON_ParserState *state) { json_eat_whitespace(state); if (state->cursor != state->end) { - raise_parse_error("unexpected token at end of stream '%s'", state->cursor); + raise_parse_error("unexpected token at end of stream %s", state); } } @@ -1232,9 +1278,14 @@ static VALUE cParser_parse(JSON_ParserConfig *config, VALUE Vsource) .capa = RVALUE_STACK_INITIAL_CAPA, }; + long len; + const char *start; + RSTRING_GETMEM(Vsource, start, len); + JSON_ParserState _state = { - .cursor = RSTRING_PTR(Vsource), - .end = RSTRING_END(Vsource), + .start = start, + .cursor = start, + .end = start + len, .stack = &stack, }; JSON_ParserState *state = &_state; diff --git a/ext/json/vendor/fpconv.c b/ext/json/vendor/fpconv.c index 854cae288c..1bbca28739 100644 --- a/ext/json/vendor/fpconv.c +++ b/ext/json/vendor/fpconv.c @@ -92,7 +92,7 @@ static Fp find_cachedpow10(int exp, int* k) { const double one_log_ten = 0.30102999566398114; - int approx = -(exp + npowers) * one_log_ten; + int approx = (int)(-(exp + npowers) * one_log_ten); int idx = (approx - firstpower) / steppowers; while(1) { @@ -340,7 +340,7 @@ static int emit_digits(char* digits, int ndigits, char* dest, int K, bool neg) } /* write decimal w/o scientific notation */ - if(K < 0 && (K > -7 || exp < 4)) { + if(K < 0 && (K > -7 || exp < 10)) { int offset = ndigits - absv(K); /* fp < 1.0 -> write leading zero */ if(offset <= 0) { diff --git a/ext/psych/lib/psych/versions.rb b/ext/psych/lib/psych/versions.rb index 6c892fbcb4..3202b10296 100644 --- a/ext/psych/lib/psych/versions.rb +++ b/ext/psych/lib/psych/versions.rb @@ -2,7 +2,7 @@ module Psych # The version of Psych you are using - VERSION = '5.2.5' + VERSION = '5.2.6' if RUBY_ENGINE == 'jruby' DEFAULT_SNAKEYAML_VERSION = '2.9'.freeze diff --git a/ext/psych/lib/psych/visitors/yaml_tree.rb b/ext/psych/lib/psych/visitors/yaml_tree.rb index d7958a8431..b6c86f4c94 100644 --- a/ext/psych/lib/psych/visitors/yaml_tree.rb +++ b/ext/psych/lib/psych/visitors/yaml_tree.rb @@ -198,7 +198,7 @@ module Psych @emitter.end_mapping end - end + end unless RUBY_VERSION < "3.2" def visit_Struct o tag = ['!ruby/struct', o.class.name].compact.join(':') diff --git a/ext/stringio/depend b/ext/stringio/depend index b9fba7e9fa..9a8979829b 100644 --- a/ext/stringio/depend +++ b/ext/stringio/depend @@ -171,5 +171,6 @@ stringio.o: $(hdrdir)/ruby/oniguruma.h stringio.o: $(hdrdir)/ruby/ruby.h stringio.o: $(hdrdir)/ruby/st.h stringio.o: $(hdrdir)/ruby/subst.h +stringio.o: $(hdrdir)/ruby/version.h stringio.o: stringio.c # AUTOGENERATED DEPENDENCIES END diff --git a/ext/stringio/stringio.c b/ext/stringio/stringio.c index dd23daa776..26287dd1b8 100644 --- a/ext/stringio/stringio.c +++ b/ext/stringio/stringio.c @@ -20,6 +20,7 @@ STRINGIO_VERSION = "3.1.8.dev"; #include "ruby.h" #include "ruby/io.h" #include "ruby/encoding.h" +#include "ruby/version.h" #if defined(HAVE_FCNTL_H) || defined(_WIN32) #include <fcntl.h> #elif defined(HAVE_SYS_FCNTL_H) @@ -1864,7 +1865,14 @@ strio_set_encoding(int argc, VALUE *argv, VALUE self) } } ptr->enc = enc; - if (!NIL_P(ptr->string) && WRITABLE(self)) { + if (!NIL_P(ptr->string) && WRITABLE(self) +#if (RUBY_API_VERSION_MAJOR == 3 && RUBY_API_VERSION_MINOR >= 4) || RUBY_API_VERSION_MAJOR >= 4 + // Do not attempt to modify chilled strings on Ruby 3.4+ + // RUBY_FL_USER2 == STR_CHILLED_LITERAL + // RUBY_FL_USER3 == STR_CHILLED_SYMBOL_TO_S + && !FL_TEST_RAW(ptr->string, RUBY_FL_USER2 | RUBY_FL_USER3) +#endif + ) { rb_enc_associate(ptr->string, enc); } |