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

ruby-changes:31409

From: usa <ko1@a...>
Date: Thu, 31 Oct 2013 23:36:42 +0900 (JST)
Subject: [ruby-changes:31409] usa:r43488 (ruby_1_9_3): merge revision(s) 42908, 42918: [Backport #8864]

usa	2013-10-31 23:36:35 +0900 (Thu, 31 Oct 2013)

  New Revision: 43488

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

  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_1_9_3/
  Modified files:
    branches/ruby_1_9_3/ChangeLog
    branches/ruby_1_9_3/test/ruby/test_sprintf_comb.rb
    branches/ruby_1_9_3/version.h
    branches/ruby_1_9_3/vsnprintf.c
Index: ruby_1_9_3/ChangeLog
===================================================================
--- ruby_1_9_3/ChangeLog	(revision 43487)
+++ ruby_1_9_3/ChangeLog	(revision 43488)
@@ -1,3 +1,13 @@ https://github.com/ruby/ruby/blob/trunk/ruby_1_9_3/ChangeLog#L1
+Thu Oct 31 23:35:12 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.
+
 Thu Oct 31 23:32:41 2013  Michal Rokos  <michal@r...>
 
 	* configure.in (sys/pstat.h): fix missing header check for
Index: ruby_1_9_3/vsnprintf.c
===================================================================
--- ruby_1_9_3/vsnprintf.c	(revision 43487)
+++ ruby_1_9_3/vsnprintf.c	(revision 43488)
@@ -489,14 +489,19 @@ BSD__ultoa(register u_long val, char *en https://github.com/ruby/ruby/blob/trunk/ruby_1_9_3/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_1_9_3/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] */
@@ -813,6 +819,7 @@ reswitch:	switch (ch) { https://github.com/ruby/ruby/blob/trunk/ruby_1_9_3/vsnprintf.c#L819
 			if (prec > 0) {
 				flags |= ALT;
 				prec++;
+				fprec = prec;
 			}
 			goto fp_begin;
 		case 'e':		/* anomalous precision */
@@ -820,7 +827,7 @@ reswitch:	switch (ch) { https://github.com/ruby/ruby/blob/trunk/ruby_1_9_3/vsnprintf.c#L827
 			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 */
@@ -830,6 +837,8 @@ reswitch:	switch (ch) { https://github.com/ruby/ruby/blob/trunk/ruby_1_9_3/vsnprintf.c#L837
 		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)) {
@@ -845,7 +854,7 @@ fp_begin:		_double = va_arg(ap, double); https://github.com/ruby/ruby/blob/trunk/ruby_1_9_3/vsnprintf.c#L854
 				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))
@@ -867,7 +876,7 @@ fp_begin:		_double = va_arg(ap, double); https://github.com/ruby/ruby/blob/trunk/ruby_1_9_3/vsnprintf.c#L876
 				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;
@@ -1099,6 +1108,7 @@ long_len: https://github.com/ruby/ruby/blob/trunk/ruby_1_9_3/vsnprintf.c#L1108
 					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' */
@@ -1109,7 +1119,8 @@ long_len: https://github.com/ruby/ruby/blob/trunk/ruby_1_9_3/vsnprintf.c#L1119
 						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);
@@ -1117,6 +1128,8 @@ long_len: https://github.com/ruby/ruby/blob/trunk/ruby_1_9_3/vsnprintf.c#L1128
 					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);
@@ -1127,6 +1140,8 @@ long_len: https://github.com/ruby/ruby/blob/trunk/ruby_1_9_3/vsnprintf.c#L1140
 					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) {
@@ -1138,6 +1153,7 @@ long_len: https://github.com/ruby/ruby/blob/trunk/ruby_1_9_3/vsnprintf.c#L1153
 					} 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);
@@ -1222,7 +1238,7 @@ exponent(p0, exp, fmtch) https://github.com/ruby/ruby/blob/trunk/ruby_1_9_3/vsnprintf.c#L1238
 	int exp, 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;
@@ -1232,13 +1248,13 @@ exponent(p0, exp, fmtch) https://github.com/ruby/ruby/blob/trunk/ruby_1_9_3/vsnprintf.c#L1248
 	}
 	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_1_9_3/version.h
===================================================================
--- ruby_1_9_3/version.h	(revision 43487)
+++ ruby_1_9_3/version.h	(revision 43488)
@@ -1,5 +1,5 @@ https://github.com/ruby/ruby/blob/trunk/ruby_1_9_3/version.h#L1
 #define RUBY_VERSION "1.9.3"
-#define RUBY_PATCHLEVEL 476
+#define RUBY_PATCHLEVEL 477
 
 #define RUBY_RELEASE_DATE "2013-10-31"
 #define RUBY_RELEASE_YEAR 2013
Index: ruby_1_9_3/test/ruby/test_sprintf_comb.rb
===================================================================
--- ruby_1_9_3/test/ruby/test_sprintf_comb.rb	(revision 43487)
+++ ruby_1_9_3/test/ruby/test_sprintf_comb.rb	(revision 43488)
@@ -107,7 +107,9 @@ class TestSprintfComb < Test::Unit::Test https://github.com/ruby/ruby/blob/trunk/ruby_1_9_3/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_1_9_3/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_1_9_3/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_1_9_3/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_1_9_3/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_1_9_3
___________________________________________________________________
Modified: svn:mergeinfo
   Merged /trunk:r42908,42918


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

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