🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

json

Package Overview
Dependencies
Maintainers
1
Versions
131
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

json - rubygems Package Compare versions

Comparing version
2.19.3
to
2.19.4
+13
-1
CHANGES.md

@@ -5,2 +5,6 @@ # Changes

### 2026-04-19 (2.19.4)
* Fix parsing of out of range floats (very large exponents that lead ot either `0.0` or `Inf`).
### 2026-03-25 (2.19.3)

@@ -12,3 +16,3 @@

* Fix a format string injection vulnerability in `JSON.parse(doc, allow_duplicate_key: false)`.
* Fix a format string injection vulnerability in `JSON.parse(doc, allow_duplicate_key: false)`. `CVE-2026-33210`.

@@ -33,2 +37,6 @@ ### 2026-03-08 (2.19.1)

### 2026-03-18 (2.17.1.2) - Security Backport
* Fix a format string injection vulnerability in `JSON.parse(doc, allow_duplicate_key: false)`. `CVE-2026-33210`.
### 2025-12-04 (2.17.1)

@@ -60,2 +68,6 @@

### 2026-03-18 (2.15.2.1) - Security Backport
* Fix a format string injection vulnerability in `JSON.parse(doc, allow_duplicate_key: false)`. `CVE-2026-33210`.
### 2025-10-25 (2.15.2)

@@ -62,0 +74,0 @@

@@ -8,2 +8,4 @@ require 'mkmf'

append_cflags("-std=c99")
have_const("RUBY_TYPED_EMBEDDABLE", "ruby.h") # RUBY_VERSION >= 3.3
$defs << "-DJSON_GENERATOR"

@@ -10,0 +12,0 @@ $defs << "-DJSON_DEBUG" if ENV.fetch("JSON_DEBUG", "0") != "0"

@@ -57,2 +57,13 @@ #ifndef _JSON_H_

#ifdef RUBY_TYPED_EMBEDDABLE
# define HAVE_RUBY_TYPED_EMBEDDABLE 1
#else
# ifdef HAVE_CONST_RUBY_TYPED_EMBEDDABLE
# define RUBY_TYPED_EMBEDDABLE RUBY_TYPED_EMBEDDABLE
# define HAVE_RUBY_TYPED_EMBEDDABLE 1
# else
# define RUBY_TYPED_EMBEDDABLE 0
# endif
#endif
#ifndef NORETURN

@@ -59,0 +70,0 @@ #if defined(__has_attribute) && __has_attribute(noreturn)

@@ -10,2 +10,6 @@ # frozen_string_literal: true

if RUBY_ENGINE == "ruby"
have_const("RUBY_TYPED_EMBEDDABLE", "ruby.h") # RUBY_VERSION >= 3.3
end
append_cflags("-std=c99")

@@ -12,0 +16,0 @@

+45
-33

@@ -244,7 +244,15 @@ #include "../json.h"

long index;
for (index = 0; index < stack->head; index++) {
rb_gc_mark(stack->ptr[index]);
if (stack && stack->ptr) {
for (index = 0; index < stack->head; index++) {
rb_gc_mark(stack->ptr[index]);
}
}
}
static void rvalue_stack_free_buffer(rvalue_stack *stack)
{
ruby_xfree(stack->ptr);
stack->ptr = NULL;
}
static void rvalue_stack_free(void *ptr)

@@ -254,4 +262,6 @@ {

if (stack) {
ruby_xfree(stack->ptr);
rvalue_stack_free_buffer(stack);
#ifndef HAVE_RUBY_TYPED_EMBEDDABLE
ruby_xfree(stack);
#endif
}

@@ -267,4 +277,4 @@ }

static const rb_data_type_t JSON_Parser_rvalue_stack_type = {
"JSON::Ext::Parser/rvalue_stack",
{
.wrap_struct_name = "JSON::Ext::Parser/rvalue_stack",
.function = {
.dmark = rvalue_stack_mark,

@@ -274,4 +284,3 @@ .dfree = rvalue_stack_free,

},
0, 0,
RUBY_TYPED_FREE_IMMEDIATELY,
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_EMBEDDABLE,
};

@@ -298,4 +307,8 @@

TypedData_Get_Struct(handle, rvalue_stack, &JSON_Parser_rvalue_stack_type, stack);
#ifdef HAVE_RUBY_TYPED_EMBEDDABLE
rvalue_stack_free_buffer(stack);
#else
rvalue_stack_free(stack);
RTYPEDDATA_DATA(handle) = NULL;
rvalue_stack_free(stack);
#endif
}

@@ -351,3 +364,3 @@ }

typedef struct JSON_ParserStateStruct {
VALUE stack_handle;
VALUE *stack_handle;
const char *start;

@@ -445,5 +458,4 @@ const char *cursor;

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 message = rb_enc_sprintf(enc_utf8, format, ptr);
rb_str_catf(message, " at line %ld column %ld", line, column);
return message;

@@ -853,3 +865,3 @@ }

*/
static inline VALUE json_decode_float(JSON_ParserConfig *config, uint64_t mantissa, int mantissa_digits, int32_t exponent, bool negative,
static inline VALUE json_decode_float(JSON_ParserConfig *config, uint64_t mantissa, int mantissa_digits, int64_t exponent, bool negative,
const char *start, const char *end)

@@ -862,2 +874,10 @@ {

if (RB_UNLIKELY(exponent > INT32_MAX)) {
return negative ? CMinusInfinity : CInfinity;
}
if (RB_UNLIKELY(exponent < INT32_MIN)) {
return rb_float_new(negative ? -0.0 : 0.0);
}
// Fall back to rb_cstr_to_dbl for potential subnormals (rare edge case)

@@ -869,3 +889,3 @@ // Ryu has rounding issues with subnormals around 1e-310 (< 2.225e-308)

return DBL2NUM(ryu_s2d_from_parts(mantissa, mantissa_digits, exponent, negative));
return DBL2NUM(ryu_s2d_from_parts(mantissa, mantissa_digits, (int32_t)exponent, negative));
}

@@ -924,5 +944,2 @@

rb_exc_raise(parse_error_new(message, line, column));
raise_parse_error(RSTRING_PTR(message), state);
RB_GC_GUARD(message);
}

@@ -964,3 +981,3 @@

}
rvalue_stack_push(state->stack, value, &state->stack_handle, &state->stack);
rvalue_stack_push(state->stack, value, state->stack_handle, &state->stack);
return value;

@@ -1150,3 +1167,3 @@ }

// Variables for Ryu optimization - extract digits during parsing
int32_t exponent = 0;
int64_t exponent = 0;
int decimal_point_pos = -1;

@@ -1195,3 +1212,3 @@ uint64_t mantissa = 0;

exponent = negative_exponent ? -((int32_t)abs_exponent) : ((int32_t)abs_exponent);
exponent = negative_exponent ? -abs_exponent : abs_exponent;
}

@@ -1577,2 +1594,3 @@

VALUE stack_handle = 0;
JSON_ParserState _state = {

@@ -1583,2 +1601,3 @@ .start = start,

.stack = &stack,
.stack_handle = &stack_handle,
};

@@ -1591,4 +1610,4 @@ JSON_ParserState *state = &_state;

// it won't cause a leak.
rvalue_stack_eagerly_release(state->stack_handle);
rvalue_stack_eagerly_release(stack_handle);
RB_GC_GUARD(stack_handle);
json_ensure_eof(state);

@@ -1631,8 +1650,2 @@

static void JSON_ParserConfig_free(void *ptr)
{
JSON_ParserConfig *config = ptr;
ruby_xfree(config);
}
static size_t JSON_ParserConfig_memsize(const void *ptr)

@@ -1644,10 +1657,9 @@ {

static const rb_data_type_t JSON_ParserConfig_type = {
"JSON::Ext::Parser/ParserConfig",
{
.wrap_struct_name = "JSON::Ext::Parser/ParserConfig",
.function = {
JSON_ParserConfig_mark,
JSON_ParserConfig_free,
RUBY_DEFAULT_FREE,
JSON_ParserConfig_memsize,
},
0, 0,
RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE,
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE | RUBY_TYPED_EMBEDDABLE,
};

@@ -1654,0 +1666,0 @@

@@ -338,4 +338,4 @@ # frozen_string_literal: true

# Allow:
# ruby = [Float::NaN, Float::Infinity, Float::MinusInfinity]
# JSON.generate(ruby, allow_nan: true) # => '[NaN,Infinity,-Infinity]'
# ruby = [Float::NAN, Float::INFINITY, JSON::NaN, JSON::Infinity, JSON::MinusInfinity]
# JSON.generate(ruby, allow_nan: true) # => '[NaN,Infinity,NaN,Infinity,-Infinity]'
#

@@ -342,0 +342,0 @@ # ---

@@ -51,3 +51,3 @@ # frozen_string_literal: true

def self.native_type?(value) # :nodoc:
(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value)
(false == value || true == value || nil == value || String === value || Symbol === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value)
end

@@ -521,7 +521,7 @@

state.depth -= 1
return '{}'
return +'{}'
end
delim = ",#{state.object_nl}"
result = +"{#{state.object_nl}"
result = "{#{state.object_nl}"
first = true

@@ -563,3 +563,3 @@ key_type = nil

result = +"#{result}#{key_json}#{state.space_before}:#{state.space}"
result = "#{result}#{key_json}#{state.space_before}:#{state.space}"
if state.strict? && !Generator.native_type?(value)

@@ -615,3 +615,3 @@ if state.as_json

state.depth -= 1
return '[]'
return +'[]'
end

@@ -741,3 +741,3 @@

# Returns a JSON string for true: 'true'.
def to_json(*) 'true' end
def to_json(*) +'true' end
end

@@ -747,3 +747,3 @@

# Returns a JSON string for false: 'false'.
def to_json(*) 'false' end
def to_json(*) +'false' end
end

@@ -753,3 +753,3 @@

# Returns a JSON string for nil: 'null'.
def to_json(*) 'null' end
def to_json(*) +'null' end
end

@@ -756,0 +756,0 @@ end

# frozen_string_literal: true
module JSON
VERSION = '2.19.3'
VERSION = '2.19.4'
end

Sorry, the diff of this file is too big to display