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

ruby-changes:30865

From: nagachika <ko1@a...>
Date: Sun, 15 Sep 2013 22:51:34 +0900 (JST)
Subject: [ruby-changes:30865] nagachika:r42944 (ruby_2_0_0): merge revision(s) 42908, 42918: [Backport #8864]

nagachika	2013-09-15 22:51:27 +0900 (Sun, 15 Sep 2013)

  New Revision: 42944

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=42944

  Log:
    merge revision(s) 42908,42918: [Backport #8864]
    
    test_sprintf_comb.rb: split tests
    
    * test/ruby/test_sprintf_comb.rb (test_format_integer),
      (test_format_float): split huge tests by the formats.
    * vsnprintf.c (MAXEXP, MAXFRACT): calculate depending on constants in
      float.h.
    
    * vsnprintf.c (BSD_vfprintf): limit length for cvt() to get rid of
      buffer overflow.  [ruby-core:57023] [Bug #8864]
    
    * vsnprintf.c (exponent): make expbuf size more precise.

  Modified directories:
    branches/ruby_2_0_0/
  Modified files:
    branches/ruby_2_0_0/ChangeLog
    branches/ruby_2_0_0/test/ruby/test_sprintf_comb.rb
    branches/ruby_2_0_0/version.h
    branches/ruby_2_0_0/vsnprintf.c
Index: ruby_2_0_0/ChangeLog
===================================================================
--- ruby_2_0_0/ChangeLog	(revision 42943)
+++ ruby_2_0_0/ChangeLog	(revision 42944)
@@ -1,3 +1,13 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/ChangeLog#L1
+Sun Sep 15 22:03:01 2013  Nobuyoshi Nakada  <nobu@r...>
+
+	* vsnprintf.c (MAXEXP, MAXFRACT): calculate depending on constants in
+	  float.h.
+
+	* vsnprintf.c (BSD_vfprintf): limit length for cvt() to get rid of
+	  buffer overflow.  [ruby-core:57023] [Bug #8864]
+
+	* vsnprintf.c (exponent): make expbuf size more precise.
+
 Sat Sep 14 00:01:20 2013  CHIKANAGA Tomoyuki  <nagachika@r...>
 
 	* lib/rubygems: Update to RubyGems to 2.0.8. [ruby-core:57155]
Index: ruby_2_0_0/vsnprintf.c
===================================================================
--- ruby_2_0_0/vsnprintf.c	(revision 42943)
+++ ruby_2_0_0/vsnprintf.c	(revision 42944)
@@ -489,14 +489,19 @@ BSD__ultoa(register u_long val, char *en https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/vsnprintf.c#L489
 
 #ifdef FLOATING_POINT
 #include <math.h>
+#include <float.h>
 /* #include "floatio.h" */
 
 #ifndef MAXEXP
-# define MAXEXP 1024
+# if DBL_MAX_10_EXP > -DBL_MIN_10_EXP
+#   define MAXEXP (DBL_MAX_10_EXP)
+# else
+#   define MAXEXP (-DBL_MIN_10_EXP)
+# endif
 #endif
 
 #ifndef MAXFRACT
-# define MAXFRACT 64
+# define MAXFRACT (MAXEXP*10/3)
 #endif
 
 #define	BUF		(MAXEXP+MAXFRACT+1)	/* + decimal point */
@@ -547,6 +552,7 @@ BSD_vfprintf(FILE *fp, const char *fmt0, https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/vsnprintf.c#L552
 	int expt;		/* integer value of exponent */
 	int expsize = 0;	/* character count for expstr */
 	int ndig = 0;		/* actual number of digits returned by cvt */
+	int fprec = 0;		/* floating point precision */
 	char expstr[7];		/* buffer for exponent string */
 #endif
 	u_long UNINITIALIZED_VAR(ulval); /* integer arguments %[diouxX] */
@@ -851,6 +857,7 @@ reswitch:	switch (ch) { https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/vsnprintf.c#L857
 			if (prec > 0) {
 				flags |= ALT;
 				prec++;
+				fprec = prec;
 			}
 			goto fp_begin;
 		case 'e':		/* anomalous precision */
@@ -858,7 +865,7 @@ reswitch:	switch (ch) { https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/vsnprintf.c#L865
 			if (prec != 0)
 				flags |= ALT;
 			prec = (prec == -1) ?
-				DEFPREC + 1 : prec + 1;
+				DEFPREC + 1 : (fprec = prec + 1);
 			/* FALLTHROUGH */
 			goto fp_begin;
 		case 'f':		/* always print trailing zeroes */
@@ -868,6 +875,8 @@ reswitch:	switch (ch) { https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/vsnprintf.c#L875
 		case 'G':
 			if (prec == -1)
 				prec = DEFPREC;
+			else
+				fprec = prec;
 fp_begin:		_double = va_arg(ap, double);
 			/* do this before tricky precision changes */
 			if (isinf(_double)) {
@@ -883,7 +892,7 @@ fp_begin:		_double = va_arg(ap, double); https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/vsnprintf.c#L892
 				break;
 			}
 			flags |= FPT;
-			cp = cvt(_double, prec, flags, &softsign,
+			cp = cvt(_double, (prec < MAXFRACT ? prec : MAXFRACT), flags, &softsign,
 				&expt, ch, &ndig, buf);
 			if (ch == 'g' || ch == 'G') {
 				if (expt <= -4 || (expt > prec && expt > 1))
@@ -905,7 +914,7 @@ fp_begin:		_double = va_arg(ap, double); https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/vsnprintf.c#L914
 				expsize = exponent(expstr, expt, ch);
 				size = expsize + ndig;
 				if (ndig > 1 || flags & ALT)
-					++size;
+					++fprec, ++size;
 			} else if (ch == 'f') {		/* f fmt */
 				if (expt > 0) {
 					size = expt;
@@ -1137,6 +1146,7 @@ long_len: https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/vsnprintf.c#L1146
 					if (ndig > 0) PRINT(cp, ndig-1);
 				} else	/* XpYYY */
 					PRINT(cp, 1);
+				PAD(fprec-ndig, zeroes);
 				PRINT(expstr, expsize);
 			}
 			else if (ch >= 'f') {	/* 'f' or 'g' */
@@ -1147,7 +1157,8 @@ long_len: https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/vsnprintf.c#L1157
 						PRINT("0", 1);
 					} else {
 						PRINT("0.", 2);
-						PAD(ndig - 1, zeroes);
+						PAD((ndig >= fprec ? ndig - 1 : fprec - (ch != 'f')),
+						    zeroes);
 					}
 				} else if (expt == 0 && ndig == 0 && (flags & ALT) == 0) {
 					PRINT("0", 1);
@@ -1155,6 +1166,8 @@ long_len: https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/vsnprintf.c#L1166
 					PRINT("0.", 2);
 					PAD(-expt, zeroes);
 					PRINT(cp, ndig);
+					if (flags & ALT)
+						PAD(fprec - ndig + (ch == 'f' ? expt : 0), zeroes);
 				} else if (expt >= ndig) {
 					PRINT(cp, ndig);
 					PAD(expt - ndig, zeroes);
@@ -1165,6 +1178,8 @@ long_len: https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/vsnprintf.c#L1178
 					cp += expt;
 					PRINT(".", 1);
 					PRINT(cp, ndig-expt);
+					if (flags & ALT)
+						PAD(fprec - ndig + (ch == 'f' ? expt : 0), zeroes);
 				}
 			} else {	/* 'e' or 'E' */
 				if (ndig > 1 || flags & ALT) {
@@ -1176,6 +1191,7 @@ long_len: https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/vsnprintf.c#L1191
 					} else	/* 0.[0..] */
 						/* __dtoa irregularity */
 						PAD(ndig - 1, zeroes);
+					if (flags & ALT) PAD(fprec - ndig - 1, zeroes);
 				} else	/* XeYYY */
 					PRINT(cp, 1);
 				PRINT(expstr, expsize);
@@ -1255,7 +1271,7 @@ static int https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/vsnprintf.c#L1271
 exponent(char *p0, int exp, int fmtch)
 {
 	register char *p, *t;
-	char expbuf[MAXEXP];
+	char expbuf[2 + (MAXEXP < 1000 ? 3 : MAXEXP < 10000 ? 4 : 5)]; /* >= 2 + ceil(log10(MAXEXP)) */
 
 	p = p0;
 	*p++ = fmtch;
@@ -1265,13 +1281,13 @@ exponent(char *p0, int exp, int fmtch) https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/vsnprintf.c#L1281
 	}
 	else
 		*p++ = '+';
-	t = expbuf + MAXEXP;
+	t = expbuf + sizeof(expbuf);
 	if (exp > 9) {
 		do {
 			*--t = to_char(exp % 10);
 		} while ((exp /= 10) > 9);
 		*--t = to_char(exp);
-		for (; t < expbuf + MAXEXP; *p++ = *t++);
+		for (; t < expbuf + sizeof(expbuf); *p++ = *t++);
 	}
 	else {
 		if (fmtch & 15) *p++ = '0'; /* other than p or P */
Index: ruby_2_0_0/version.h
===================================================================
--- ruby_2_0_0/version.h	(revision 42943)
+++ ruby_2_0_0/version.h	(revision 42944)
@@ -1,10 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/version.h#L1
 #define RUBY_VERSION "2.0.0"
-#define RUBY_RELEASE_DATE "2013-09-14"
-#define RUBY_PATCHLEVEL 313
+#define RUBY_RELEASE_DATE "2013-09-15"
+#define RUBY_PATCHLEVEL 314
 
 #define RUBY_RELEASE_YEAR 2013
 #define RUBY_RELEASE_MONTH 9
-#define RUBY_RELEASE_DAY 14
+#define RUBY_RELEASE_DAY 15
 
 #include "ruby/version.h"
 
Index: ruby_2_0_0/test/ruby/test_sprintf_comb.rb
===================================================================
--- ruby_2_0_0/test/ruby/test_sprintf_comb.rb	(revision 42943)
+++ ruby_2_0_0/test/ruby/test_sprintf_comb.rb	(revision 42944)
@@ -107,7 +107,9 @@ class TestSprintfComb < Test::Unit::Test https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/test/ruby/test_sprintf_comb.rb#L107
   ]
   VS.reverse!
 
-  def combination(*args, &b)
+  FLAGS = [['', ' '], ['', '#'], ['', '+'], ['', '-'], ['', '0']]
+
+  def self.combination(*args, &b)
     #AllPairs.exhaustive_each(*args, &b)
     AllPairs.each(*args, &b)
   end
@@ -268,17 +270,8 @@ class TestSprintfComb < Test::Unit::Test https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/test/ruby/test_sprintf_comb.rb#L270
     str
   end
 
-  def test_format_integer
-    combination(
-        %w[B b d o X x],
-        [nil, 0, 5, 20],
-        ["", ".", ".0", ".8", ".20"],
-        ['', ' '],
-        ['', '#'],
-        ['', '+'],
-        ['', '-'],
-        ['', '0']) {|type, width, precision, sp, hs, pl, mi, zr|
-      format = "%#{sp}#{hs}#{pl}#{mi}#{zr}#{width}#{precision}#{type}"
+  def self.assertions_format_integer(format)
+    proc {
       VS.each {|v|
         r = sprintf format, v
         e = emu_int format, v
@@ -293,6 +286,14 @@ class TestSprintfComb < Test::Unit::Test https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/test/ruby/test_sprintf_comb.rb#L286
     }
   end
 
+  combination(%w[B b d o X x],
+              [nil, 0, 5, 20],
+              ["", ".", ".0", ".8", ".20"],
+              *FLAGS) {|type, width, precision, sp, hs, pl, mi, zr|
+    format = "%#{sp}#{hs}#{pl}#{mi}#{zr}#{width}#{precision}#{type}"
+    define_method("test_format_integer(#{format})", assertions_format_integer(format))
+  }
+
   FLOAT_VALUES = [
     -1e100,
     -123456789.0,
@@ -526,17 +527,8 @@ class TestSprintfComb < Test::Unit::Test https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/test/ruby/test_sprintf_comb.rb#L527
 
   end
 
-  def test_format_float
-    combination(
-        %w[e E f g G],
-        [nil, 0, 5, 20],
-        ["", ".", ".0", ".8", ".20", ".200"],
-        ['', ' '],
-        ['', '#'],
-        ['', '+'],
-        ['', '-'],
-        ['', '0']) {|type, width, precision, sp, hs, pl, mi, zr|
-      format = "%#{sp}#{hs}#{pl}#{mi}#{zr}#{width}#{precision}#{type}"
+  def self.assertions_format_float(format)
+    proc {
       FLOAT_VALUES.each {|v|
         r = sprintf format, v
         e = emu_float format, v
@@ -550,4 +542,12 @@ class TestSprintfComb < Test::Unit::Test https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/test/ruby/test_sprintf_comb.rb#L542
       }
     }
   end
+
+  combination(%w[e E f g G],
+              [nil, 0, 5, 20],
+              ["", ".", ".0", ".8", ".20", ".200", ".9999"],
+              *FLAGS) {|type, width, precision, sp, hs, pl, mi, zr|
+    format = "%#{sp}#{hs}#{pl}#{mi}#{zr}#{width}#{precision}#{type}"
+    define_method("test_format_float(#{format})", assertions_format_float(format))
+  }
 end

Property changes on: ruby_2_0_0
___________________________________________________________________
Modified: svn:mergeinfo
   Merged /trunk:r42908,42918


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

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