Index: include/ruby/win32.h =================================================================== --- include/ruby/win32.h (revision 19901) +++ include/ruby/win32.h (working copy) @@ -248,6 +248,12 @@ extern int rb_w32_vsnprintf(char *, size_t, const char *, va_list); extern int rb_w32_snprintf(char *, size_t, const char *, ...); +#if (defined(_MSC_VER) && defined(_DLL)) || defined(__MSVCRT__) +#undef HAVE_VSNPRINTF +#define _vsnprintf BSD_vsnprintf +extern int BSD_vsnprintf(char *, size_t, const char *, va_list); +#endif + extern int chown(const char *, int, int); extern int link(const char *, const char *); extern int gettimeofday(struct timeval *, struct timezone *); Index: numeric.c =================================================================== --- numeric.c (revision 19901) +++ numeric.c (working copy) @@ -530,12 +530,12 @@ else if(isnan(value)) return rb_usascii_str_new2("NaN"); - sprintf(buf, "%#.15g", value); /* ensure to print decimal point */ + snprintf(buf, 32, "%#.15g", value); /* ensure to print decimal point */ if (!(e = strchr(buf, 'e'))) { e = buf + strlen(buf); } if (!ISDIGIT(e[-1])) { /* reformat if ended with decimal point (ex 111111111111111.) */ - sprintf(buf, "%#.14e", value); + snprintf(buf, 32, "%#.14e", value); if (!(e = strchr(buf, 'e'))) { e = buf + strlen(buf); } @@ -1548,7 +1548,7 @@ char buf[24]; char *s; - sprintf(buf, "%-.10g", RFLOAT_VALUE(val)); + snprintf(buf, 24, "%-.10g", RFLOAT_VALUE(val)); if ((s = strchr(buf, ' ')) != 0) *s = '\0'; rb_raise(rb_eRangeError, "float %s out of range of integer", buf); } @@ -1694,7 +1694,7 @@ char buf[24]; char *s; - sprintf(buf, "%-.10g", RFLOAT_VALUE(val)); + snprintf(buf, 24, "%-.10g", RFLOAT_VALUE(val)); if ((s = strchr(buf, ' ')) != 0) *s = '\0'; rb_raise(rb_eRangeError, "float %s out of range of long long", buf); } Index: sprintf.c =================================================================== --- sprintf.c (revision 19901) +++ sprintf.c (working copy) @@ -1018,7 +1018,7 @@ need += 20; CHECK(need); - sprintf(&buf[blen], fbuf, fval); + snprintf(&buf[blen], need, fbuf, fval); blen += strlen(&buf[blen]); } break; Index: missing/vsnprintf.c =================================================================== --- missing/vsnprintf.c (revision 19901) +++ missing/vsnprintf.c (working copy) @@ -781,8 +781,10 @@ flags |= FPT; cp = cvt(_double, prec, flags, &softsign, &expt, ch, &ndig); + if ((ch == 'e' || ch == 'E') && ndig < prec) + ndig = prec; if (ch == 'g' || ch == 'G') { - if (expt <= -4 || expt > prec) + if (expt <= -4 || (expt > prec && expt > 1)) ch = (ch == 'g') ? 'e' : 'E'; else ch = 'g'; @@ -798,7 +800,9 @@ size = expt; if (prec || flags & ALT) size += prec + 1; - } else /* "0.X" */ + } else if (!prec) /* "0" */ + size = 1; + else /* "0.X" */ size = prec + 2; } else if (expt >= ndig) { /* fixed g fmt */ size = expt; @@ -1008,13 +1012,15 @@ if (ch >= 'f') { /* 'f' or 'g' */ if (_double == 0) { /* kludge for __dtoa irregularity */ - if (prec == 0 || + if (ndig <= 1 && (flags & ALT) == 0) { PRINT("0", 1); } else { PRINT("0.", 2); PAD(ndig - 1, zeroes); } + } else if (expt == 0 && ndig == 0 && (flags & ALT) == 0) { + PRINT("0", 1); } else if (expt <= 0) { PRINT("0.", 2); PAD(-expt, zeroes); @@ -1036,7 +1042,14 @@ ox[1] = '.'; PRINT(ox, 2); if (_double || flags & ALT == 0) { - PRINT(cp, ndig-1); + int i; + for (i = 0; i < ndig - 1; i++) { + if (cp[i] == '\0') + break; + } + PRINT(cp, i); + if (i < ndig - 1) + PAD(ndig - 1 - i, zeroes); } else /* 0.[0..] */ /* __dtoa irregularity */ PAD(ndig - 1, zeroes); @@ -1141,7 +1154,11 @@ #ifndef HAVE_VSNPRINTF int +#if (defined(_MSC_VER) && defined(_DLL)) || defined(__MSVCRT__) +BSD_vsnprintf(str, n, fmt, ap) +#else vsnprintf(str, n, fmt, ap) +#endif char *str; size_t n; const char *fmt;