[前][次][番号順一覧][スレッド一覧]

ruby-changes:44629

From: nobu <ko1@a...>
Date: Fri, 11 Nov 2016 16:26:19 +0900 (JST)
Subject: [ruby-changes:44629] nobu:r56702 (trunk): rational.c: check load

nobu	2016-11-11 16:26:14 +0900 (Fri, 11 Nov 2016)

  New Revision: 56702

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=56702

  Log:
    rational.c: check load
    
    * rational.c (nurat_loader, nurat_marshal_load): check if loading
      values are Integer.  [ruby-core:78071] [Bug #12918]

  Modified files:
    trunk/rational.c
    trunk/test/ruby/test_rational.rb
Index: test/ruby/test_rational.rb
===================================================================
--- test/ruby/test_rational.rb	(revision 56701)
+++ test/ruby/test_rational.rb	(revision 56702)
@@ -646,6 +646,10 @@ class Rational_Test < Test::Unit::TestCa https://github.com/ruby/ruby/blob/trunk/test/ruby/test_rational.rb#L646
     assert_equal(9, c2.instance_variable_get(:@ivar))
     assert_instance_of(Rational, c2)
 
+    assert_raise(TypeError){
+      Marshal.load("\x04\bU:\rRational[\ai\x060")
+    }
+
     assert_raise(ZeroDivisionError){
       Marshal.load("\x04\bU:\rRational[\ai\x06i\x05")
     }
@@ -664,6 +668,10 @@ class Rational_Test < Test::Unit::TestCa https://github.com/ruby/ruby/blob/trunk/test/ruby/test_rational.rb#L668
     assert_nothing_raised(bug6625) do
       assert_equal(Rational(1, 2), Marshal.load(dump), bug6625)
     end
+    dump = "\x04\x08o:\x0dRational\x07:\x11@denominatori\x07:\x0f@numerator0"
+    assert_raise(TypeError) do
+      Marshal.load(dump)
+    end
   end
 
   def test_parse
Index: rational.c
===================================================================
--- rational.c	(revision 56701)
+++ rational.c	(revision 56702)
@@ -485,21 +485,24 @@ nurat_int_value(VALUE num) https://github.com/ruby/ruby/blob/trunk/rational.c#L485
     return num;
 }
 
+static void
+nurat_canonicalize(VALUE *num, VALUE *den)
+{
+    if (f_negative_p(*den)) {
+	*num = f_negate(*num);
+	*den = f_negate(*den);
+    }
+    else if (f_zero_p(*den)) {
+	rb_raise_zerodiv();
+    }
+}
+
 inline static VALUE
 nurat_s_canonicalize_internal(VALUE klass, VALUE num, VALUE den)
 {
     VALUE gcd;
 
-    switch (FIX2INT(f_cmp(den, ZERO))) {
-      case -1:
-	num = f_negate(num);
-	den = f_negate(den);
-	break;
-      case 0:
-	rb_raise_zerodiv();
-	break;
-    }
-
+    nurat_canonicalize(&num, &den);
     gcd = f_gcd(num, den);
     num = f_idiv(num, gcd);
     den = f_idiv(den, gcd);
@@ -514,15 +517,7 @@ nurat_s_canonicalize_internal(VALUE klas https://github.com/ruby/ruby/blob/trunk/rational.c#L517
 inline static VALUE
 nurat_s_canonicalize_internal_no_reduce(VALUE klass, VALUE num, VALUE den)
 {
-    switch (FIX2INT(f_cmp(den, ZERO))) {
-      case -1:
-	num = f_negate(num);
-	den = f_negate(den);
-	break;
-      case 0:
-	rb_raise_zerodiv();
-	break;
-    }
+    nurat_canonicalize(&num, &den);
 
 #ifdef CANON
     if (f_one_p(den) && canonicalization)
@@ -1675,10 +1670,16 @@ nurat_dumper(VALUE self) https://github.com/ruby/ruby/blob/trunk/rational.c#L1670
 static VALUE
 nurat_loader(VALUE self, VALUE a)
 {
-    get_dat1(self);
+    VALUE num, den;
 
-    RRATIONAL_SET_NUM(dat, rb_ivar_get(a, id_i_num));
-    RRATIONAL_SET_DEN(dat, rb_ivar_get(a, id_i_den));
+    get_dat1(self);
+    num = rb_ivar_get(a, id_i_num);
+    den = rb_ivar_get(a, id_i_den);
+    nurat_int_check(num);
+    nurat_int_check(den);
+    nurat_canonicalize(&num, &den);
+    RRATIONAL_SET_NUM(dat, num);
+    RRATIONAL_SET_DEN(dat, den);
 
     return self;
 }
@@ -1699,17 +1700,22 @@ nurat_marshal_dump(VALUE self) https://github.com/ruby/ruby/blob/trunk/rational.c#L1700
 static VALUE
 nurat_marshal_load(VALUE self, VALUE a)
 {
+    VALUE num, den;
+
     rb_check_frozen(self);
     rb_check_trusted(self);
 
     Check_Type(a, T_ARRAY);
     if (RARRAY_LEN(a) != 2)
 	rb_raise(rb_eArgError, "marshaled rational must have an array whose length is 2 but %ld", RARRAY_LEN(a));
-    if (f_zero_p(RARRAY_AREF(a, 1)))
-	rb_raise_zerodiv();
 
-    rb_ivar_set(self, id_i_num, RARRAY_AREF(a, 0));
-    rb_ivar_set(self, id_i_den, RARRAY_AREF(a, 1));
+    num = RARRAY_AREF(a, 0);
+    den = RARRAY_AREF(a, 1);
+    nurat_int_check(num);
+    nurat_int_check(den);
+    nurat_canonicalize(&num, &den);
+    rb_ivar_set(self, id_i_num, num);
+    rb_ivar_set(self, id_i_den, den);
 
     return self;
 }

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]