Skip to content

Commit 44674a7

Browse files
committed
Fix arity checking and NULL arguments to rb_scan_args to match MRI.
1 parent 8949ef1 commit 44674a7

File tree

3 files changed

+47
-13
lines changed

3 files changed

+47
-13
lines changed

lib/cext/include/truffleruby/truffleruby.h

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,8 @@ MUST_INLINE int rb_tr_scan_args(int argc, VALUE *argv, const char *format, VALUE
228228
const char *formatp = format;
229229
int pre = 0;
230230
int optional = 0;
231+
int n_mand = 0;
232+
int n_opt = 0;
231233
bool rest;
232234
int post = 0;
233235
bool kwargs;
@@ -281,6 +283,9 @@ MUST_INLINE int rb_tr_scan_args(int argc, VALUE *argv, const char *format, VALUE
281283
rb_raise(rb_eArgError, "not enough arguments for required");
282284
}
283285

286+
n_mand = pre + post;
287+
n_opt = optional;
288+
284289
// Read arguments
285290

286291
int argn = 0;
@@ -360,26 +365,30 @@ MUST_INLINE int rb_tr_scan_args(int argc, VALUE *argv, const char *format, VALUE
360365
// Don't assign the correct v to a temporary VALUE* and then assign arg to it - this doesn't optimise well
361366

362367
switch (valuen) {
363-
case 1: *v1 = arg; break;
364-
case 2: *v2 = arg; break;
365-
case 3: *v3 = arg; break;
366-
case 4: *v4 = arg; break;
367-
case 5: *v5 = arg; break;
368-
case 6: *v6 = arg; break;
369-
case 7: *v7 = arg; break;
370-
case 8: *v8 = arg; break;
371-
case 9: *v9 = arg; break;
372-
case 10: *v10 = arg; break;
368+
case 1: if (v1 != NULL) { *v1 = arg; } break;
369+
case 2: if (v2 != NULL) { *v2 = arg; } break;
370+
case 3: if (v3 != NULL) { *v3 = arg; } break;
371+
case 4: if (v4 != NULL) { *v4 = arg; } break;
372+
case 5: if (v5 != NULL) { *v5 = arg; } break;
373+
case 6: if (v6 != NULL) { *v6 = arg; } break;
374+
case 7: if (v7 != NULL) { *v7 = arg; } break;
375+
case 8: if (v8 != NULL) { *v8 = arg; } break;
376+
case 9: if (v9 != NULL) { *v9 = arg; } break;
377+
case 10: if (v10 != NULL) { *v10 = arg; } break;
373378
}
374379

375380
valuen++;
376381
}
377382

378383
if (found_kwargs) {
379-
return argc - 1;
380-
} else {
381-
return argc;
384+
argc = argc - 1;
382385
}
386+
387+
if (argn < argc) {
388+
rb_error_arity(argc, pre, rest ? UNLIMITED_ARGUMENTS : pre + optional);
389+
}
390+
391+
return argc;
383392
}
384393

385394
#if defined(__cplusplus)

spec/ruby/optional/capi/util_spec.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323
lambda { @o.rb_scan_args([1, 2], "3", 0, @acc) }.should raise_error(ArgumentError)
2424
end
2525

26+
it "raises an ArgumentError if there are too many arguments" do
27+
lambda { @o.rb_scan_args([1, 2, 3, 4], "3", 0, @acc) }.should raise_error(ArgumentError)
28+
end
29+
2630
it "assigns the required and optional arguments scanned" do
2731
@o.rb_scan_args([1, 2], "11", 2, @acc).should == 2
2832
ScratchPad.recorded.should == [1, 2]

src/main/c/cext/ruby.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3468,6 +3468,27 @@ VALUE rb_enum_values_pack(int argc, const VALUE *argv) {
34683468
rb_tr_error("rb_enum_values_pack not implemented");
34693469
}
34703470

3471+
static inline VALUE
3472+
rb_arity_error_new(int argc, int min, int max)
3473+
{
3474+
VALUE err_mess = 0;
3475+
if (min == max) {
3476+
err_mess = rb_sprintf("wrong number of arguments (given %d, expected %d)", argc, min);
3477+
}
3478+
else if (max == UNLIMITED_ARGUMENTS) {
3479+
err_mess = rb_sprintf("wrong number of arguments (given %d, expected %d+)", argc, min);
3480+
}
3481+
else {
3482+
err_mess = rb_sprintf("wrong number of arguments (given %d, expected %d..%d)", argc, min, max);
3483+
}
3484+
return rb_exc_new3(rb_eArgError, err_mess);
3485+
}
3486+
3487+
NORETURN(void rb_error_arity(int argc, int min, int max))
3488+
{
3489+
rb_exc_raise(rb_arity_error_new(argc, min, max));
3490+
}
3491+
34713492
void rb_error_untrusted(VALUE obj) {
34723493
rb_tr_error("rb_error_untrusted not implemented");
34733494
}

0 commit comments

Comments
 (0)