Skip to content
Merged
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
2 changes: 1 addition & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ releases.

* RubyGems 4.1.0.dev
* bundler 4.1.0.dev
* json 2.18.1
* json 2.19.0
* 2.18.0 to [v2.18.1][json-v2.18.1]
* openssl 4.0.1
* 4.0.0 to [v4.0.1][openssl-v4.0.1]
Expand Down
30 changes: 15 additions & 15 deletions ext/json/fbuffer/fbuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ enum fbuffer_type {

typedef struct FBufferStruct {
enum fbuffer_type type;
unsigned long initial_length;
unsigned long len;
unsigned long capa;
size_t initial_length;
size_t len;
size_t capa;
#if JSON_DEBUG
unsigned long requested;
size_t requested;
#endif
char *ptr;
VALUE io;
Expand All @@ -32,12 +32,12 @@ typedef struct FBufferStruct {

static void fbuffer_free(FBuffer *fb);
static void fbuffer_clear(FBuffer *fb);
static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len);
static void fbuffer_append(FBuffer *fb, const char *newstr, size_t len);
static void fbuffer_append_long(FBuffer *fb, long number);
static inline void fbuffer_append_char(FBuffer *fb, char newchr);
static VALUE fbuffer_finalize(FBuffer *fb);

static void fbuffer_stack_init(FBuffer *fb, unsigned long initial_length, char *stack_buffer, long stack_buffer_size)
static void fbuffer_stack_init(FBuffer *fb, size_t initial_length, char *stack_buffer, size_t stack_buffer_size)
{
fb->initial_length = (initial_length > 0) ? initial_length : FBUFFER_INITIAL_LENGTH_DEFAULT;
if (stack_buffer) {
Expand All @@ -50,7 +50,7 @@ static void fbuffer_stack_init(FBuffer *fb, unsigned long initial_length, char *
#endif
}

static inline void fbuffer_consumed(FBuffer *fb, unsigned long consumed)
static inline void fbuffer_consumed(FBuffer *fb, size_t consumed)
{
#if JSON_DEBUG
if (consumed > fb->requested) {
Expand Down Expand Up @@ -79,7 +79,7 @@ static void fbuffer_flush(FBuffer *fb)
fbuffer_clear(fb);
}

static void fbuffer_realloc(FBuffer *fb, unsigned long required)
static void fbuffer_realloc(FBuffer *fb, size_t required)
{
if (required > fb->capa) {
if (fb->type == FBUFFER_STACK_ALLOCATED) {
Expand All @@ -94,7 +94,7 @@ static void fbuffer_realloc(FBuffer *fb, unsigned long required)
}
}

static void fbuffer_do_inc_capa(FBuffer *fb, unsigned long requested)
static void fbuffer_do_inc_capa(FBuffer *fb, size_t requested)
{
if (RB_UNLIKELY(fb->io)) {
if (fb->capa < FBUFFER_IO_BUFFER_SIZE) {
Expand All @@ -108,7 +108,7 @@ static void fbuffer_do_inc_capa(FBuffer *fb, unsigned long requested)
}
}

unsigned long required;
size_t required;

if (RB_UNLIKELY(!fb->ptr)) {
fb->ptr = ALLOC_N(char, fb->initial_length);
Expand All @@ -120,7 +120,7 @@ static void fbuffer_do_inc_capa(FBuffer *fb, unsigned long requested)
fbuffer_realloc(fb, required);
}

static inline void fbuffer_inc_capa(FBuffer *fb, unsigned long requested)
static inline void fbuffer_inc_capa(FBuffer *fb, size_t requested)
{
#if JSON_DEBUG
fb->requested = requested;
Expand All @@ -131,13 +131,13 @@ static inline void fbuffer_inc_capa(FBuffer *fb, unsigned long requested)
}
}

static inline void fbuffer_append_reserved(FBuffer *fb, const char *newstr, unsigned long len)
static inline void fbuffer_append_reserved(FBuffer *fb, const char *newstr, size_t len)
{
MEMCPY(fb->ptr + fb->len, newstr, char, len);
fbuffer_consumed(fb, len);
}

static inline void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len)
static inline void fbuffer_append(FBuffer *fb, const char *newstr, size_t len)
{
if (len > 0) {
fbuffer_inc_capa(fb, len);
Expand All @@ -162,7 +162,7 @@ static inline void fbuffer_append_reserved_char(FBuffer *fb, char chr)
static void fbuffer_append_str(FBuffer *fb, VALUE str)
{
const char *ptr;
unsigned long len;
size_t len;
RSTRING_GETMEM(str, ptr, len);

fbuffer_append(fb, ptr, len);
Expand All @@ -171,7 +171,7 @@ static void fbuffer_append_str(FBuffer *fb, VALUE str)
static void fbuffer_append_str_repeat(FBuffer *fb, VALUE str, size_t repeat)
{
const char *ptr;
unsigned long len;
size_t len;
RSTRING_GETMEM(str, ptr, len);

fbuffer_inc_capa(fb, repeat * len);
Expand Down
15 changes: 13 additions & 2 deletions ext/json/generator/generator.c
Original file line number Diff line number Diff line change
Expand Up @@ -1575,6 +1575,17 @@ static long long_config(VALUE num)
return RTEST(num) ? FIX2LONG(num) : 0;
}

// depth must never be negative; reject early with a clear error.
static long depth_config(VALUE num)
{
if (!RTEST(num)) return 0;
long d = NUM2LONG(num);
if (RB_UNLIKELY(d < 0)) {
rb_raise(rb_eArgError, "depth must be >= 0 (got %ld)", d);
}
return d;
}

/*
* call-seq: max_nesting=(depth)
*
Expand Down Expand Up @@ -1731,7 +1742,7 @@ static VALUE cState_depth_set(VALUE self, VALUE depth)
{
rb_check_frozen(self);
GET_STATE(self);
state->depth = long_config(depth);
state->depth = depth_config(depth);
return Qnil;
}

Expand Down Expand Up @@ -1796,7 +1807,7 @@ static int configure_state_i(VALUE key, VALUE val, VALUE _arg)
else if (key == sym_max_nesting) { state->max_nesting = long_config(val); }
else if (key == sym_allow_nan) { state->allow_nan = RTEST(val); }
else if (key == sym_ascii_only) { state->ascii_only = RTEST(val); }
else if (key == sym_depth) { state->depth = long_config(val); }
else if (key == sym_depth) { state->depth = depth_config(val); }
else if (key == sym_buffer_initial_length) { buffer_initial_length_set(state, val); }
else if (key == sym_script_safe) { state->script_safe = RTEST(val); }
else if (key == sym_escape_slash) { state->script_safe = RTEST(val); }
Expand Down
2 changes: 1 addition & 1 deletion ext/json/lib/json/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module JSON
VERSION = '2.18.1'
VERSION = '2.19.0'
end
54 changes: 32 additions & 22 deletions parse.y
Original file line number Diff line number Diff line change
Expand Up @@ -2773,7 +2773,7 @@ rb_parser_ary_free(rb_parser_t *p, rb_parser_ary_t *ary)
%type <node> if_tail opt_else case_body case_args cases opt_rescue exc_list exc_var opt_ensure
%type <node> args arg_splat call_args opt_call_args
%type <node> paren_args opt_paren_args
%type <node_args> args_tail block_args_tail f_args-opt_tail block_args-opt_tail
%type <node_args> args_tail block_args_tail block_args-opt_tail
%type <node> command_args aref_args
%type <node_block_pass> opt_block_arg block_arg
%type <node> var_ref var_lhs
Expand All @@ -2788,7 +2788,7 @@ rb_parser_ary_free(rb_parser_t *p, rb_parser_ary_t *ary)
%type <id> do bv_decls opt_bv_decl bvar
%type <node> lambda brace_body do_body
%type <locations_lambda_body> lambda_body
%type <node_args> f_larglist
%type <node_args> f_larglist f_largs largs_tail
%type <node> brace_block cmd_brace_block do_block lhs none fitem
%type <node> mlhs_head mlhs_item mlhs_node
%type <node_masgn> mlhs mlhs_basic mlhs_inner
Expand Down Expand Up @@ -5103,19 +5103,19 @@ lambda : tLAMBDA[lpar]
}
;

f_larglist : '(' f_args opt_bv_decl ')'
f_larglist : '(' f_largs[args] opt_bv_decl ')'
{
p->ctxt.in_argdef = 0;
$$ = $f_args;
$$ = $args;
p->max_numparam = ORDINAL_PARAM;
/*% ripper: paren!($:f_args) %*/
/*% ripper: paren!($:args) %*/
}
| f_args
| f_largs[args]
{
p->ctxt.in_argdef = 0;
if (!args_info_empty_p(&$f_args->nd_ainfo))
if (!args_info_empty_p(&$args->nd_ainfo))
p->max_numparam = ORDINAL_PARAM;
$$ = $f_args;
$$ = $args;
}
;

Expand Down Expand Up @@ -6243,16 +6243,18 @@ f_arglist : f_paren_args
args_tail : args_tail_basic(arg_value)
| args_forward
{
ID fwd = $args_forward;
if (lambda_beginning_p() ||
(p->lex.lpar_beg >= 0 && p->lex.lpar_beg+1 == p->lex.paren_nest)) {
yyerror0("unexpected ... in lambda argument");
fwd = 0;
}
else {
add_forwarding_args(p);
}
$$ = new_args_tail(p, 0, fwd, arg_FWD_BLOCK, &@args_forward);
add_forwarding_args(p);
$$ = new_args_tail(p, 0, $args_forward, arg_FWD_BLOCK, &@args_forward);
$$->nd_ainfo.forwarding = 1;
/*% ripper: [Qnil, $:args_forward, Qnil] %*/
}
;

largs_tail : args_tail_basic(arg_value)
| args_forward
{
yyerror1(&@args_forward, "unexpected ... in lambda argument");
$$ = new_args_tail(p, 0, 0, 0, &@args_forward);
$$->nd_ainfo.forwarding = 1;
/*% ripper: [Qnil, $:args_forward, Qnil] %*/
}
Expand Down Expand Up @@ -6329,19 +6331,27 @@ args_tail : args_tail_basic(arg_value)
}
;

f_args-opt_tail : opt_args_tail(args_tail)
%rule f_args-opt_tail(tail) <node_args>
: opt_args_tail(tail)
;

f_args : args-list(arg_value, f_args-opt_tail)
| f_arg[pre] f_args-opt_tail[tail]

%rule f_args-list(tail) <node_args>
: args-list(arg_value, f_args-opt_tail(tail))
| f_arg[pre] opt_args_tail(tail)[tail]
{
$$ = new_args(p, $pre, 0, 0, 0, $tail, &@$);
/*% ripper: params!($:pre, Qnil, Qnil, Qnil, *$:tail[0..2]) %*/
}
| tail-only-args(args_tail)
| tail-only-args(tail)
| f_empty_arg
;

f_args : f_args-list(args_tail)
;

f_largs : f_args-list(largs_tail)
;

args_forward : tBDOT3
{
Expand Down
10 changes: 10 additions & 0 deletions test/json/json_generator_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1045,4 +1045,14 @@ def test_nesting_recovery
assert_equal 0, state.depth
assert_equal '{"a":1}', state.generate({ a: 1 })
end

def test_negative_depth_raises
assert_raise(ArgumentError) do
JSON.generate({"a" => 1}, depth: -1)
end
assert_raise(ArgumentError) do
JSON.state.new(depth: -1)
end
end

end
7 changes: 2 additions & 5 deletions test/rubygems/test_gem_dependency_installer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -677,8 +677,7 @@ def test_install_force
util_setup_gems

FileUtils.mv @b1_gem, @tempdir
si = util_setup_spec_fetcher @b1
@fetcher.data["http://gems.example.com/gems/yaml"] = si.to_yaml
util_setup_spec_fetcher @b1
inst = nil

Dir.chdir @tempdir do
Expand Down Expand Up @@ -955,9 +954,7 @@ def test_install_remote_platform_newer
s.platform = Gem::Platform.new %w[cpu other_platform 1]
end

si = util_setup_spec_fetcher @a1, a2_o

@fetcher.data["http://gems.example.com/gems/yaml"] = si.to_yaml
util_setup_spec_fetcher @a1, a2_o

a1_data = nil
a2_o_data = nil
Expand Down