Skip to content

Commit

Permalink
Merge pull request #2590 from herwinw/kernel_complex_exception_argument
Browse files Browse the repository at this point in the history
Fix exception argument in kernel coercion methods
  • Loading branch information
herwinw committed Feb 9, 2025
2 parents d84ad6a + afcc4c7 commit 45ccd89
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 3 deletions.
12 changes: 9 additions & 3 deletions src/kernel_module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ extern char **environ;

namespace Natalie {

static bool exception_argument_to_bool(Env *env, Value exception) {
if (exception && !exception.is_false() && !exception.is_true())
env->raise("ArgumentError", "expected true or false as exception: {}", exception.inspect_str(env));
return !exception || exception.is_true();
}

Value KernelModule::Array(Env *env, Value value) {
return Natalie::to_ary(env, value, true);
}
Expand Down Expand Up @@ -130,7 +136,7 @@ Value KernelModule::catch_method(Env *env, Value name, Block *block) {
}

Value KernelModule::Complex(Env *env, Value real, Value imaginary, Value exception) {
return Complex(env, real, imaginary, exception ? exception.is_true() : true);
return Complex(env, real, imaginary, exception_argument_to_bool(env, exception));
}

Value KernelModule::Complex(Env *env, Value real, Value imaginary, bool exception) {
Expand Down Expand Up @@ -364,7 +370,7 @@ Value KernelModule::Integer(Env *env, Value value, Value base, Value exception)
nat_int_t base_int = 0; // default to zero if unset
if (base)
base_int = base.to_int(env).to_nat_int_t();
return Integer(env, value, base_int, exception ? exception.is_true() : true);
return Integer(env, value, base_int, exception_argument_to_bool(env, exception));
}

Value KernelModule::Integer(Env *env, Value value, nat_int_t base, bool exception) {
Expand Down Expand Up @@ -413,7 +419,7 @@ Value KernelModule::Integer(Env *env, Value value, nat_int_t base, bool exceptio
}

Value KernelModule::Float(Env *env, Value value, Value exception) {
return Float(env, value, exception ? exception.is_true() : true);
return Float(env, value, exception_argument_to_bool(env, exception));
}

Value KernelModule::Float(Env *env, Value value, bool exception) {
Expand Down
6 changes: 6 additions & 0 deletions test/natalie/kernel_complex_test.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
require_relative '../spec_helper'

describe 'Kernel.Complex' do
it 'only accepts true or false as exception argument' do
-> { Complex('1', exception: nil) }.should raise_error(ArgumentError, 'expected true or false as exception: nil')
obj = Object.new
-> { Complex('1', exception: obj) }.should raise_error(ArgumentError, "expected true or false as exception: #{obj}")
end

it 'does not accept anything nun-numeric after the real integer part' do
-> { Complex('1a') }.should raise_error(ArgumentError, 'invalid value for convert(): "1a"')
-> { Complex('+1a') }.should raise_error(ArgumentError, 'invalid value for convert(): "+1a"')
Expand Down
6 changes: 6 additions & 0 deletions test/natalie/kernel_integer_test.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
require_relative '../spec_helper'

describe 'Kernel.Integer' do
it 'only accepts true or false as exception argument' do
-> { Integer('1', exception: nil) }.should raise_error(ArgumentError, 'expected true or false as exception: nil')
obj = Object.new
-> { Integer('1', exception: obj) }.should raise_error(ArgumentError, "expected true or false as exception: #{obj}")
end

it 'Does not accept a any whitespace after a sign mark' do
-> { Integer("+\x001".b) }.should raise_error(ArgumentError, 'invalid value for Integer(): "+\\x001"')
-> { Integer("+\t1") }.should raise_error(ArgumentError, 'invalid value for Integer(): "+\\t1"')
Expand Down
6 changes: 6 additions & 0 deletions test/natalie/kernel_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,12 @@
end

describe '#Float' do
it 'only accepts true or false as exception argument' do
-> { Float('1.0', exception: nil) }.should raise_error(ArgumentError, 'expected true or false as exception: nil')
obj = Object.new
-> { Float('1.0', exception: obj) }.should raise_error(ArgumentError, "expected true or false as exception: #{obj}")
end

it 'raises error with extra keywords' do
-> { Float(1, foo: 2, bar: 3) }.should raise_error(ArgumentError, 'unknown keywords: :foo, :bar')
end
Expand Down

0 comments on commit 45ccd89

Please sign in to comment.