summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rw-r--r--ext/-test-/thread_fd/depend161
-rw-r--r--ext/-test-/thread_fd/extconf.rb2
-rw-r--r--ext/-test-/thread_fd/thread_fd.c30
-rw-r--r--ext/erb/escape/escape.c9
-rw-r--r--ext/json/lib/json/common.rb4
-rw-r--r--ext/json/lib/json/version.rb2
-rw-r--r--ext/json/parser/parser.c251
-rw-r--r--ext/json/vendor/fpconv.c4
-rw-r--r--ext/psych/lib/psych/versions.rb2
-rw-r--r--ext/psych/lib/psych/visitors/yaml_tree.rb2
-rw-r--r--ext/stringio/depend1
-rw-r--r--ext/stringio/stringio.c10
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);
}