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/