From 73faeda2a33f252c5e8d9e93fd384a813ba6e469 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Thu, 16 Jun 2022 16:56:32 +0300 Subject: [PATCH] Ruby: fix ntoa exceptions and add tests --- bindings/ruby/ext/default/ntoa.c | 41 ++++++++++--------- .../ruby/spec/lib/kernaux/ntoa/itoa10_spec.rb | 9 ++++ .../ruby/spec/lib/kernaux/ntoa/itoa16_spec.rb | 9 ++++ .../ruby/spec/lib/kernaux/ntoa/itoa2_spec.rb | 9 ++++ .../ruby/spec/lib/kernaux/ntoa/itoa8_spec.rb | 9 ++++ .../ruby/spec/lib/kernaux/ntoa/itoa_spec.rb | 9 ++++ .../ruby/spec/lib/kernaux/ntoa/utoa10_spec.rb | 9 ++++ .../ruby/spec/lib/kernaux/ntoa/utoa16_spec.rb | 9 ++++ .../ruby/spec/lib/kernaux/ntoa/utoa2_spec.rb | 9 ++++ .../ruby/spec/lib/kernaux/ntoa/utoa8_spec.rb | 9 ++++ .../ruby/spec/lib/kernaux/ntoa/utoa_spec.rb | 9 ++++ 11 files changed, 111 insertions(+), 20 deletions(-) diff --git a/bindings/ruby/ext/default/ntoa.c b/bindings/ruby/ext/default/ntoa.c index 5bee1f6..251243d 100644 --- a/bindings/ruby/ext/default/ntoa.c +++ b/bindings/ruby/ext/default/ntoa.c @@ -75,7 +75,8 @@ VALUE rb_KernAux_utoa(const int argc, const VALUE *argv, const VALUE self) VALUE base_rb = argv[1]; VALUE prefix_rb = argc == 3 ? argv[2] : Qnil; - RB_INTEGER_TYPE_P(number_rb); + const uint64_t number = NUM2ULL(number_rb); + if (rb_funcall(number_rb, rb_intern_LESS, 1, INT2FIX(0))) { rb_raise(rb_eRangeError, "can't convert negative number to uint64_t"); } @@ -96,7 +97,7 @@ VALUE rb_KernAux_utoa(const int argc, const VALUE *argv, const VALUE self) } char buffer[KERNAUX_UTOA_MIN_BUFFER_SIZE + prefix_len]; - kernaux_utoa(NUM2ULL(number_rb), buffer, convert_base(base_rb), prefix); + kernaux_utoa(number, buffer, convert_base(base_rb), prefix); return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0); } @@ -114,7 +115,7 @@ VALUE rb_KernAux_itoa(const int argc, const VALUE *argv, const VALUE self) VALUE base_rb = argv[1]; VALUE prefix_rb = argc == 3 ? argv[2] : Qnil; - RB_INTEGER_TYPE_P(number_rb); + const int64_t number = NUM2LL(number_rb); const char *prefix = NULL; long prefix_len = 0; @@ -132,7 +133,7 @@ VALUE rb_KernAux_itoa(const int argc, const VALUE *argv, const VALUE self) } char buffer[KERNAUX_ITOA_MIN_BUFFER_SIZE + prefix_len]; - kernaux_itoa(NUM2LL(number_rb), buffer, convert_base(base_rb), prefix); + kernaux_itoa(number, buffer, convert_base(base_rb), prefix); return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0); } @@ -140,12 +141,12 @@ VALUE rb_KernAux_utoa2( const VALUE self_rb __attribute__((unused)), const VALUE number_rb ) { - RB_INTEGER_TYPE_P(number_rb); + const uint64_t number = NUM2ULL(number_rb); if (rb_funcall(number_rb, rb_intern_LESS, 1, INT2FIX(0))) { rb_raise(rb_eRangeError, "can't convert negative number to uint64_t"); } char buffer[KERNAUX_UTOA2_BUFFER_SIZE]; - kernaux_utoa2(NUM2ULL(number_rb), buffer); + kernaux_utoa2(number, buffer); return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0); } @@ -153,9 +154,9 @@ VALUE rb_KernAux_itoa2( const VALUE self_rb __attribute__((unused)), const VALUE number_rb ) { - RB_INTEGER_TYPE_P(number_rb); + const int64_t number = NUM2LL(number_rb); char buffer[KERNAUX_ITOA2_BUFFER_SIZE]; - kernaux_itoa2(NUM2LL(number_rb), buffer); + kernaux_itoa2(number, buffer); return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0); } @@ -163,12 +164,12 @@ VALUE rb_KernAux_utoa8( const VALUE self_rb __attribute__((unused)), const VALUE number_rb ) { - RB_INTEGER_TYPE_P(number_rb); + const uint64_t number = NUM2ULL(number_rb); if (rb_funcall(number_rb, rb_intern_LESS, 1, INT2FIX(0))) { rb_raise(rb_eRangeError, "can't convert negative number to uint64_t"); } char buffer[KERNAUX_UTOA8_BUFFER_SIZE]; - kernaux_utoa8(NUM2ULL(number_rb), buffer); + kernaux_utoa8(number, buffer); return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0); } @@ -176,9 +177,9 @@ VALUE rb_KernAux_itoa8( const VALUE self_rb __attribute__((unused)), const VALUE number_rb ) { - RB_INTEGER_TYPE_P(number_rb); + const int64_t number = NUM2LL(number_rb); char buffer[KERNAUX_ITOA8_BUFFER_SIZE]; - kernaux_itoa8(NUM2LL(number_rb), buffer); + kernaux_itoa8(number, buffer); return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0); } @@ -186,12 +187,12 @@ VALUE rb_KernAux_utoa10( const VALUE self_rb __attribute__((unused)), const VALUE number_rb ) { - RB_INTEGER_TYPE_P(number_rb); + const uint64_t number = NUM2ULL(number_rb); if (rb_funcall(number_rb, rb_intern_LESS, 1, INT2FIX(0))) { rb_raise(rb_eRangeError, "can't convert negative number to uint64_t"); } char buffer[KERNAUX_UTOA10_BUFFER_SIZE]; - kernaux_utoa10(NUM2ULL(number_rb), buffer); + kernaux_utoa10(number, buffer); return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0); } @@ -199,9 +200,9 @@ VALUE rb_KernAux_itoa10( const VALUE self_rb __attribute__((unused)), const VALUE number_rb ) { - RB_INTEGER_TYPE_P(number_rb); + const int64_t number = NUM2LL(number_rb); char buffer[KERNAUX_ITOA10_BUFFER_SIZE]; - kernaux_itoa10(NUM2LL(number_rb), buffer); + kernaux_itoa10(number, buffer); return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0); } @@ -209,12 +210,12 @@ VALUE rb_KernAux_utoa16( const VALUE self_rb __attribute__((unused)), const VALUE number_rb ) { - RB_INTEGER_TYPE_P(number_rb); + const uint64_t number = NUM2ULL(number_rb); if (rb_funcall(number_rb, rb_intern_LESS, 1, INT2FIX(0))) { rb_raise(rb_eRangeError, "can't convert negative number to uint64_t"); } char buffer[KERNAUX_UTOA16_BUFFER_SIZE]; - kernaux_utoa16(NUM2ULL(number_rb), buffer); + kernaux_utoa16(number, buffer); return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0); } @@ -222,9 +223,9 @@ VALUE rb_KernAux_itoa16( const VALUE self_rb __attribute__((unused)), const VALUE number_rb ) { - RB_INTEGER_TYPE_P(number_rb); + const int64_t number = NUM2LL(number_rb); char buffer[KERNAUX_ITOA16_BUFFER_SIZE]; - kernaux_itoa16(NUM2LL(number_rb), buffer); + kernaux_itoa16(number, buffer); return rb_funcall(rb_str_new2(buffer), rb_intern_freeze, 0); } diff --git a/bindings/ruby/spec/lib/kernaux/ntoa/itoa10_spec.rb b/bindings/ruby/spec/lib/kernaux/ntoa/itoa10_spec.rb index 697db61..74bf680 100644 --- a/bindings/ruby/spec/lib/kernaux/ntoa/itoa10_spec.rb +++ b/bindings/ruby/spec/lib/kernaux/ntoa/itoa10_spec.rb @@ -58,4 +58,13 @@ KernAux::Version.with_ntoa? and RSpec.describe KernAux, '.itoa10' do RangeError, 'bignum too big to convert into `long long\'' end end + + context 'when number is not numeric' do + let(:number) { rand((-2**63)..(2**63 - 1)).to_s } + + specify do + expect { itoa10 }.to raise_error \ + TypeError, 'no implicit conversion from string' + end + end end diff --git a/bindings/ruby/spec/lib/kernaux/ntoa/itoa16_spec.rb b/bindings/ruby/spec/lib/kernaux/ntoa/itoa16_spec.rb index 738d15f..30a235b 100644 --- a/bindings/ruby/spec/lib/kernaux/ntoa/itoa16_spec.rb +++ b/bindings/ruby/spec/lib/kernaux/ntoa/itoa16_spec.rb @@ -60,4 +60,13 @@ KernAux::Version.with_ntoa? and RSpec.describe KernAux, '.itoa16' do RangeError, 'bignum too big to convert into `long long\'' end end + + context 'when number is not numeric' do + let(:number) { rand((-2**63)..(2**63 - 1)).to_s } + + specify do + expect { itoa16 }.to raise_error \ + TypeError, 'no implicit conversion from string' + end + end end diff --git a/bindings/ruby/spec/lib/kernaux/ntoa/itoa2_spec.rb b/bindings/ruby/spec/lib/kernaux/ntoa/itoa2_spec.rb index c3d60fa..3e8d680 100644 --- a/bindings/ruby/spec/lib/kernaux/ntoa/itoa2_spec.rb +++ b/bindings/ruby/spec/lib/kernaux/ntoa/itoa2_spec.rb @@ -60,4 +60,13 @@ KernAux::Version.with_ntoa? and RSpec.describe KernAux, '.itoa2' do RangeError, 'bignum too big to convert into `long long\'' end end + + context 'when number is not numeric' do + let(:number) { rand((-2**63)..(2**63 - 1)).to_s } + + specify do + expect { itoa2 }.to raise_error \ + TypeError, 'no implicit conversion from string' + end + end end diff --git a/bindings/ruby/spec/lib/kernaux/ntoa/itoa8_spec.rb b/bindings/ruby/spec/lib/kernaux/ntoa/itoa8_spec.rb index afe85cb..41b0cfb 100644 --- a/bindings/ruby/spec/lib/kernaux/ntoa/itoa8_spec.rb +++ b/bindings/ruby/spec/lib/kernaux/ntoa/itoa8_spec.rb @@ -60,4 +60,13 @@ KernAux::Version.with_ntoa? and RSpec.describe KernAux, '.itoa8' do RangeError, 'bignum too big to convert into `long long\'' end end + + context 'when number is not numeric' do + let(:number) { rand((-2**63)..(2**63 - 1)).to_s } + + specify do + expect { itoa8 }.to raise_error \ + TypeError, 'no implicit conversion from string' + end + end end diff --git a/bindings/ruby/spec/lib/kernaux/ntoa/itoa_spec.rb b/bindings/ruby/spec/lib/kernaux/ntoa/itoa_spec.rb index 1907dfb..86bb230 100644 --- a/bindings/ruby/spec/lib/kernaux/ntoa/itoa_spec.rb +++ b/bindings/ruby/spec/lib/kernaux/ntoa/itoa_spec.rb @@ -71,6 +71,15 @@ KernAux::Version.with_ntoa? and RSpec.describe KernAux, '.itoa' do end end + context 'when number is not numeric' do + let(:number) { rand((-2**63)..(2**63 - 1)).to_s } + + specify do + expect { itoa }.to raise_error \ + TypeError, 'no implicit conversion from string' + end + end + context 'when base is negative' do let(:base) { -rand(2..36) } diff --git a/bindings/ruby/spec/lib/kernaux/ntoa/utoa10_spec.rb b/bindings/ruby/spec/lib/kernaux/ntoa/utoa10_spec.rb index 2ece655..3f287ee 100644 --- a/bindings/ruby/spec/lib/kernaux/ntoa/utoa10_spec.rb +++ b/bindings/ruby/spec/lib/kernaux/ntoa/utoa10_spec.rb @@ -40,4 +40,13 @@ KernAux::Version.with_ntoa? and RSpec.describe KernAux, '.utoa10' do RangeError, 'bignum too big to convert into `unsigned long long\'' end end + + context 'when number is not numeric' do + let(:number) { rand(0..(2**64 - 1)).to_s } + + specify do + expect { utoa10 }.to raise_error \ + TypeError, 'no implicit conversion from string' + end + end end diff --git a/bindings/ruby/spec/lib/kernaux/ntoa/utoa16_spec.rb b/bindings/ruby/spec/lib/kernaux/ntoa/utoa16_spec.rb index b7002f4..21b02b7 100644 --- a/bindings/ruby/spec/lib/kernaux/ntoa/utoa16_spec.rb +++ b/bindings/ruby/spec/lib/kernaux/ntoa/utoa16_spec.rb @@ -40,4 +40,13 @@ KernAux::Version.with_ntoa? and RSpec.describe KernAux, '.utoa16' do RangeError, 'bignum too big to convert into `unsigned long long\'' end end + + context 'when number is not numeric' do + let(:number) { rand(0..(2**64 - 1)).to_s } + + specify do + expect { utoa16 }.to raise_error \ + TypeError, 'no implicit conversion from string' + end + end end diff --git a/bindings/ruby/spec/lib/kernaux/ntoa/utoa2_spec.rb b/bindings/ruby/spec/lib/kernaux/ntoa/utoa2_spec.rb index f0e002c..cb90180 100644 --- a/bindings/ruby/spec/lib/kernaux/ntoa/utoa2_spec.rb +++ b/bindings/ruby/spec/lib/kernaux/ntoa/utoa2_spec.rb @@ -40,4 +40,13 @@ KernAux::Version.with_ntoa? and RSpec.describe KernAux, '.utoa2' do RangeError, 'bignum too big to convert into `unsigned long long\'' end end + + context 'when number is not numeric' do + let(:number) { rand(0..(2**64 - 1)).to_s } + + specify do + expect { utoa2 }.to raise_error \ + TypeError, 'no implicit conversion from string' + end + end end diff --git a/bindings/ruby/spec/lib/kernaux/ntoa/utoa8_spec.rb b/bindings/ruby/spec/lib/kernaux/ntoa/utoa8_spec.rb index e384aaa..164252e 100644 --- a/bindings/ruby/spec/lib/kernaux/ntoa/utoa8_spec.rb +++ b/bindings/ruby/spec/lib/kernaux/ntoa/utoa8_spec.rb @@ -40,4 +40,13 @@ KernAux::Version.with_ntoa? and RSpec.describe KernAux, '.utoa8' do RangeError, 'bignum too big to convert into `unsigned long long\'' end end + + context 'when number is not numeric' do + let(:number) { rand(0..(2**64 - 1)).to_s } + + specify do + expect { utoa8 }.to raise_error \ + TypeError, 'no implicit conversion from string' + end + end end diff --git a/bindings/ruby/spec/lib/kernaux/ntoa/utoa_spec.rb b/bindings/ruby/spec/lib/kernaux/ntoa/utoa_spec.rb index 99e0129..3ba6fce 100644 --- a/bindings/ruby/spec/lib/kernaux/ntoa/utoa_spec.rb +++ b/bindings/ruby/spec/lib/kernaux/ntoa/utoa_spec.rb @@ -47,6 +47,15 @@ KernAux::Version.with_ntoa? and RSpec.describe KernAux, '.utoa' do end end + context 'when number is not numeric' do + let(:number) { rand(0..(2**64 - 1)).to_s } + + specify do + expect { utoa }.to raise_error \ + TypeError, 'no implicit conversion from string' + end + end + context 'when base is negative' do let(:base) { -rand(2..36) }