From 995bac1f73f3c4af967931c89beeab7cd84aa75c Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Mon, 30 May 2022 15:55:38 +0300 Subject: [PATCH] Common: ntoa fixes --- pkgs/mruby/src/ntoa.c | 24 ++++++++++++++++++++++-- pkgs/mruby/test/ntoa.rb | 12 +++++++++--- pkgs/ruby/ext/default/ntoa.c | 10 ++++++---- pkgs/ruby/lib/kernaux.rb | 16 ++++++++++++++-- pkgs/ruby/spec/lib/kernaux/itoa_spec.rb | 2 +- pkgs/ruby/spec/lib/kernaux/utoa_spec.rb | 2 +- 6 files changed, 53 insertions(+), 13 deletions(-) diff --git a/pkgs/mruby/src/ntoa.c b/pkgs/mruby/src/ntoa.c index a176bc2..362914b 100644 --- a/pkgs/mruby/src/ntoa.c +++ b/pkgs/mruby/src/ntoa.c @@ -16,6 +16,7 @@ static mrb_value rb_KernAux_itoa(mrb_state *mrb, mrb_value self); static mrb_value rb_KernAux_utoa10(mrb_state *mrb, mrb_value self); static mrb_value rb_KernAux_itoa10(mrb_state *mrb, mrb_value self); + static mrb_value rb_KernAux_utoa16(mrb_state *mrb, mrb_value self); static mrb_value rb_KernAux_itoa16(mrb_state *mrb, mrb_value self); @@ -29,6 +30,8 @@ void init_ntoa(mrb_state *const mrb) mrb_define_class_under_id(mrb, rb_KernAux, MRB_SYM(InvalidNtoaBaseError), rb_KernAux_Error); + mrb_define_class_under_id(mrb, rb_KernAux, MRB_SYM(TooLongNtoaPrefixError), + rb_KernAux_Error); mrb_define_class_method(mrb, rb_KernAux, "utoa", rb_KernAux_utoa, MRB_ARGS_REQ(2) | MRB_ARGS_OPT(1)); @@ -39,6 +42,7 @@ void init_ntoa(mrb_state *const mrb) rb_KernAux_utoa10, MRB_ARGS_REQ(1)); mrb_define_class_method(mrb, rb_KernAux, "itoa10", rb_KernAux_itoa10, MRB_ARGS_REQ(1)); + mrb_define_class_method(mrb, rb_KernAux, "utoa16", rb_KernAux_utoa16, MRB_ARGS_REQ(1)); mrb_define_class_method(mrb, rb_KernAux, "itoa16", @@ -58,7 +62,15 @@ mrb_value rb_KernAux_utoa(mrb_state *mrb, mrb_value self) "can't convert negative number to uint64_t"); } if (prefix_len > MAX_PREFIX_LEN || prefix_len < 0) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, + struct RClass *const rb_KernAux = + mrb_module_get_id(mrb, MRB_SYM(KernAux)); + struct RClass *const rb_KernAux_TooLongNtoaPrefixError = + mrb_class_get_under_id( + mrb, + rb_KernAux, + MRB_SYM(TooLongNtoaPrefixError) + ); + mrb_raisef(mrb, rb_KernAux_TooLongNtoaPrefixError, "prefix length %d is too long", prefix_len); } @@ -81,7 +93,15 @@ mrb_value rb_KernAux_itoa(mrb_state *mrb, mrb_value self) mrb_get_args(mrb, "io|s!", &value, &base, &prefix, &prefix_len); if (prefix_len > MAX_PREFIX_LEN || prefix_len < 0) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, + struct RClass *const rb_KernAux = + mrb_module_get_id(mrb, MRB_SYM(KernAux)); + struct RClass *const rb_KernAux_TooLongNtoaPrefixError = + mrb_class_get_under_id( + mrb, + rb_KernAux, + MRB_SYM(TooLongNtoaPrefixError) + ); + mrb_raisef(mrb, rb_KernAux_TooLongNtoaPrefixError, "prefix length %d is too long", prefix_len); } diff --git a/pkgs/mruby/test/ntoa.rb b/pkgs/mruby/test/ntoa.rb index 62f3d1c..53f9c90 100644 --- a/pkgs/mruby/test/ntoa.rb +++ b/pkgs/mruby/test/ntoa.rb @@ -52,8 +52,8 @@ assert 'KernAux.utoa' do base = 2 + Random.rand(36 - 2) test_utoa number, base, number.to_s(base) - base = 2 + Random.rand(36 - 2) assert_raise RangeError, 'can\'t convert negative number to uint64_t' do + base = 2 + Random.rand(36 - 2) KernAux.utoa(-1, base) end @@ -101,7 +101,10 @@ assert 'KernAux.utoa' do prefix = 'a' * 100 test_utoax number, base, prefix, "#{prefix}#{number.abs.to_s(base)}" - assert_raise ArgumentError, 'prefix length 101 is too long' do + assert_raise( + KernAux::TooLongNtoaPrefixError, + 'prefix length 101 is too long', + ) do number = Random.rand(2**32 - 1) base = 2 + Random.rand(36 - 2) prefix = 'a' * 101 @@ -181,7 +184,10 @@ assert 'KernAux.itoa' do sign = number < 0 ? '-' : '' test_itoax number, base, prefix, "#{sign}#{prefix}#{number.abs.to_s(base)}" - assert_raise ArgumentError, 'prefix length 101 is too long' do + assert_raise( + KernAux::TooLongNtoaPrefixError, + 'prefix length 101 is too long', + ) do number = Random.rand(2**31 - 1) * [1, -1].sample base = 2 + Random.rand(36 - 2) prefix = 'a' * 101 diff --git a/pkgs/ruby/ext/default/ntoa.c b/pkgs/ruby/ext/default/ntoa.c index 51665e1..668ec95 100644 --- a/pkgs/ruby/ext/default/ntoa.c +++ b/pkgs/ruby/ext/default/ntoa.c @@ -9,7 +9,6 @@ static VALUE rb_KernAux_utoa(VALUE self, VALUE number, VALUE base, VALUE prefix) #ifdef HAVE_KERNAUX_ITOA static VALUE rb_KernAux_itoa(VALUE self, VALUE number, VALUE base, VALUE prefix); #endif - #ifdef HAVE_KERNAUX_UTOA10 static VALUE rb_KernAux_utoa10(VALUE self, VALUE number); #endif @@ -39,6 +38,7 @@ static ID rb_intern_X = Qnil; static VALUE rb_KernAux = Qnil; static VALUE rb_KernAux_Error = Qnil; static VALUE rb_KernAux_InvalidNtoaBaseError = Qnil; +static VALUE rb_KernAux_TooLongNtoaPrefixError = Qnil; #if defined(HAVE_KERNAUX_UTOA) || defined(HAVE_KERNAUX_ITOA) static int convert_base(VALUE base); @@ -65,6 +65,9 @@ void init_ntoa() rb_gc_register_mark_object(rb_KernAux_InvalidNtoaBaseError = rb_define_class_under(rb_KernAux, "InvalidNtoaBaseError", rb_KernAux_Error)); + rb_gc_register_mark_object(rb_KernAux_TooLongNtoaPrefixError = + rb_define_class_under(rb_KernAux, "TooLongNtoaPrefixError", + rb_KernAux_Error)); #ifdef HAVE_KERNAUX_UTOA rb_define_singleton_method(rb_KernAux, "utoa", rb_KernAux_utoa, 3); @@ -72,7 +75,6 @@ void init_ntoa() #ifdef HAVE_KERNAUX_ITOA rb_define_singleton_method(rb_KernAux, "itoa", rb_KernAux_itoa, 3); #endif - #ifdef HAVE_KERNAUX_UTOA10 rb_define_singleton_method(rb_KernAux, "utoa10", rb_KernAux_utoa10, 1); #endif @@ -107,7 +109,7 @@ VALUE rb_KernAux_utoa( if (prefix_len > MAX_PREFIX_LEN || prefix_len < 0) { rb_raise( - rb_eArgError, + rb_KernAux_TooLongNtoaPrefixError, "prefix length %ld is too long", prefix_len ); @@ -137,7 +139,7 @@ VALUE rb_KernAux_itoa( if (prefix_len > MAX_PREFIX_LEN || prefix_len < 0) { rb_raise( - rb_eArgError, + rb_KernAux_TooLongNtoaPrefixError, "prefix length %ld is too long", prefix_len ); diff --git a/pkgs/ruby/lib/kernaux.rb b/pkgs/ruby/lib/kernaux.rb index a616f99..ad8d75a 100644 --- a/pkgs/ruby/lib/kernaux.rb +++ b/pkgs/ruby/lib/kernaux.rb @@ -127,7 +127,7 @@ module KernAux # @!parse [ruby] ## - # @!method utoa(number, base) + # @!method utoa(number, base, prefix) # Convert `uint64_t` to a string in multiple numeral systems. # # Base can be a positive or negative integer between 2 and 36, or a symbol @@ -139,16 +139,18 @@ module KernAux # # @param number [Integer] a number between 0 and `UINT64_MAX` # @param base [Integer, Symbol] base of a numeral system + # @param prefix [nil, String] string to put before a number # @return [String] # # @raise [RangeError] number is out of range # @raise [InvalidNtoaBaseError] base is invalid + # @raise [TooLongNtoaPrefixError] prefix is too long # # @see .itoa Convert signed integers ## ## - # @!method itoa(number, base) + # @!method itoa(number, base, prefix) # Convert `int64_t` to a string in multiple numeral systems. # # Base can be a positive or negative integer between 2 and 36, or a symbol @@ -160,10 +162,12 @@ module KernAux # # @param number [Integer] a number between `INT64_MIN` and `INT64_MAX` # @param base [Integer, Symbol] base of a numeral system + # @param prefix [nil, String] string to put between a sign and a number # @return [String] # # @raise [RangeError] number is out of range # @raise [InvalidNtoaBaseError] base is invalid + # @raise [TooLongNtoaPrefixError] prefix is too long # # @see .utoa Convert unsigned integers ## @@ -235,4 +239,12 @@ module KernAux # @see .itoa # class InvalidNtoaBaseError < Error; end + + ## + # Raised when prefix is too long. + # + # @see .utoa + # @see .itoa + # + class TooLongNtoaPrefixError < Error; end end diff --git a/pkgs/ruby/spec/lib/kernaux/itoa_spec.rb b/pkgs/ruby/spec/lib/kernaux/itoa_spec.rb index 8f8a71d..2c3f618 100644 --- a/pkgs/ruby/spec/lib/kernaux/itoa_spec.rb +++ b/pkgs/ruby/spec/lib/kernaux/itoa_spec.rb @@ -221,7 +221,7 @@ RSpec.describe KernAux, '.itoa' do specify do expect { itoa }.to raise_error( - ArgumentError, + described_class::TooLongNtoaPrefixError, "prefix length #{prefix.length} is too long", ) end diff --git a/pkgs/ruby/spec/lib/kernaux/utoa_spec.rb b/pkgs/ruby/spec/lib/kernaux/utoa_spec.rb index 2ded118..ed46369 100644 --- a/pkgs/ruby/spec/lib/kernaux/utoa_spec.rb +++ b/pkgs/ruby/spec/lib/kernaux/utoa_spec.rb @@ -193,7 +193,7 @@ RSpec.describe KernAux, '.utoa' do specify do expect { utoa }.to raise_error( - ArgumentError, + described_class::TooLongNtoaPrefixError, "prefix length #{prefix.length} is too long", ) end