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

ruby-changes:74501

From: Kenta <ko1@a...>
Date: Tue, 15 Nov 2022 13:02:18 +0900 (JST)
Subject: [ruby-changes:74501] 3c60e030b5 (master): [ruby/bigdecimal] Replace sprintf by snprintf

https://git.ruby-lang.org/ruby.git/commit/?id=3c60e030b5

From 3c60e030b57be556ea2002d1416fdfa6c1cb2a1b Mon Sep 17 00:00:00 2001
From: Kenta Murata <mrkn@m...>
Date: Tue, 15 Nov 2022 13:01:50 +0900
Subject: [ruby/bigdecimal] Replace sprintf by snprintf

https://github.com/ruby/bigdecimal/commit/d6f5bb40c7
---
 ext/bigdecimal/bigdecimal.c | 302 +++++++++++++++++++++++++++-----------------
 ext/bigdecimal/bigdecimal.h |   8 +-
 2 files changed, 189 insertions(+), 121 deletions(-)

diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c
index c85ef15953..9b1d33ed9d 100644
--- a/ext/bigdecimal/bigdecimal.c
+++ b/ext/bigdecimal/bigdecimal.c
@@ -420,7 +420,7 @@ GetVpValueWithPrec(VALUE v, long prec, int must) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L420
 
       case T_FIXNUM: {
         char szD[128];
-        sprintf(szD, "%ld", FIX2LONG(v));
+        snprintf(szD, 128, "%ld", FIX2LONG(v));
         v = rb_cstr_convert_to_BigDecimal(szD, VpBaseFig() * 2 + 1, must);
         break;
       }
@@ -779,13 +779,15 @@ BigDecimal_dump(int argc, VALUE *argv, VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L779
     char *psz;
     VALUE dummy;
     volatile VALUE dump;
+    size_t len;
 
     rb_scan_args(argc, argv, "01", &dummy);
     GUARD_OBJ(vp,GetVpValue(self, 1));
     dump = rb_str_new(0, VpNumOfChars(vp, "E")+50);
     psz = RSTRING_PTR(dump);
-    sprintf(psz, "%"PRIuSIZE":", VpMaxPrec(vp)*VpBaseFig());
-    VpToString(vp, psz+strlen(psz), 0, 0);
+    snprintf(psz, RSTRING_LEN(dump), "%"PRIuSIZE":", VpMaxPrec(vp)*VpBaseFig());
+    len = strlen(psz);
+    VpToString(vp, psz+len, RSTRING_LEN(dump)-len, 0, 0);
     rb_str_resize(dump, strlen(psz));
     return dump;
 }
@@ -1305,7 +1307,7 @@ BigDecimal_to_f(VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L1307
 
     str = rb_str_new(0, VpNumOfChars(p, "E"));
     buf = RSTRING_PTR(str);
-    VpToString(p, buf, 0, 0);
+    VpToString(p, buf, RSTRING_LEN(str), 0, 0);
     errno = 0;
     d = strtod(buf, 0);
     if (errno == ERANGE) {
@@ -2753,10 +2755,10 @@ BigDecimal_to_s(int argc, VALUE *argv, VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L2755
     psz = RSTRING_PTR(str);
 
     if (fmt) {
-	VpToFString(vp, psz, mc, fPlus);
+	VpToFString(vp, psz, RSTRING_LEN(str), mc, fPlus);
     }
     else {
-	VpToString (vp, psz, mc, fPlus);
+	VpToString (vp, psz, RSTRING_LEN(str), mc, fPlus);
     }
     rb_str_resize(str, strlen(psz));
     return str;
@@ -2798,7 +2800,7 @@ BigDecimal_split(VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L2800
     GUARD_OBJ(vp, GetVpValue(self, 1));
     str = rb_str_new(0, VpNumOfChars(vp, "E"));
     psz1 = RSTRING_PTR(str);
-    VpSzMantissa(vp, psz1);
+    VpSzMantissa(vp, psz1, RSTRING_LEN(str));
     s = 1;
     if(psz1[0] == '-') {
 	size_t len = strlen(psz1 + 1);
@@ -2847,7 +2849,7 @@ BigDecimal_inspect(VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L2849
     nc = VpNumOfChars(vp, "E");
 
     str = rb_str_new(0, nc);
-    VpToString(vp, RSTRING_PTR(str), 0, 0);
+    VpToString(vp, RSTRING_PTR(str), RSTRING_LEN(str), 0, 0);
     rb_str_resize(str, strlen(RSTRING_PTR(str)));
     return str;
 }
@@ -6528,188 +6530,254 @@ VpExponent10(Real *a) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L6530
 }
 
 VP_EXPORT void
-VpSzMantissa(Real *a,char *psz)
+VpSzMantissa(Real *a, char *buf, size_t buflen)
 {
     size_t i, n, ZeroSup;
     DECDIG_DBL m, e, nn;
 
     if (VpIsNaN(a)) {
-	sprintf(psz, SZ_NaN);
-	return;
+        snprintf(buf, buflen, SZ_NaN);
+        return;
     }
     if (VpIsPosInf(a)) {
-	sprintf(psz, SZ_INF);
+	snprintf(buf, buflen, SZ_INF);
 	return;
     }
     if (VpIsNegInf(a)) {
-	sprintf(psz, SZ_NINF);
+	snprintf(buf, buflen, SZ_NINF);
 	return;
     }
 
     ZeroSup = 1;        /* Flag not to print the leading zeros as 0.00xxxxEnn */
     if (!VpIsZero(a)) {
-	if (BIGDECIMAL_NEGATIVE_P(a)) *psz++ = '-';
-	n = a->Prec;
-	for (i = 0; i < n; ++i) {
-	    m = BASE1;
-	    e = a->frac[i];
-	    while (m) {
-		nn = e / m;
-		if (!ZeroSup || nn) {
-		    sprintf(psz, "%lu", (unsigned long)nn); /* The leading zero(s) */
-		    psz += strlen(psz);
-		    /* as 0.00xx will be ignored. */
-		    ZeroSup = 0; /* Set to print succeeding zeros */
-		}
-		e = e - nn * m;
-		m /= 10;
-	    }
-	}
-	*psz = 0;
-	while (psz[-1] == '0') *(--psz) = 0;
+        if (BIGDECIMAL_NEGATIVE_P(a)) *buf++ = '-';
+        n = a->Prec;
+        for (i = 0; i < n; ++i) {
+            m = BASE1;
+            e = a->frac[i];
+            while (m) {
+                nn = e / m;
+                if (!ZeroSup || nn) {
+                    snprintf(buf, buflen, "%lu", (unsigned long)nn); /* The leading zero(s) */
+                    buf += strlen(buf);
+                    /* as 0.00xx will be ignored. */
+                    ZeroSup = 0; /* Set to print succeeding zeros */
+                }
+                e = e - nn * m;
+                m /= 10;
+            }
+        }
+        *buf = 0;
+        while (buf[-1] == '0') *(--buf) = 0;
     }
     else {
-	if (VpIsPosZero(a)) sprintf(psz, "0");
-	else                sprintf(psz, "-0");
+	if (VpIsPosZero(a)) snprintf(buf, buflen, "0");
+	else                snprintf(buf, buflen, "-0");
     }
 }
 
 VP_EXPORT int
-VpToSpecialString(Real *a,char *psz,int fPlus)
+VpToSpecialString(Real *a, char *buf, size_t buflen, int fPlus)
 /* fPlus = 0: default, 1: set ' ' before digits, 2: set '+' before digits. */
 {
     if (VpIsNaN(a)) {
-	sprintf(psz,SZ_NaN);
-	return 1;
+        snprintf(buf, buflen, SZ_NaN);
+        return 1;
     }
 
     if (VpIsPosInf(a)) {
-	if (fPlus == 1) {
-	    *psz++ = ' ';
-	}
-	else if (fPlus == 2) {
-	    *psz++ = '+';
-	}
-	sprintf(psz, SZ_INF);
-	return 1;
+        if (fPlus == 1) {
+            *buf++ = ' ';
+        }
+        else if (fPlus == 2) {
+            *buf++ = '+';
+        }
+        snprintf(buf, buflen, SZ_INF);
+        return 1;
     }
     if (VpIsNegInf(a)) {
-	sprintf(psz, SZ_NINF);
-	return 1;
+        snprintf(buf, buflen, SZ_NINF);
+        return 1;
     }
     if (VpIsZero(a)) {
-	if (VpIsPosZero(a)) {
-	    if (fPlus == 1)      sprintf(psz, " 0.0");
-	    else if (fPlus == 2) sprintf(psz, "+0.0");
-	    else                 sprintf(psz,  "0.0");
-	}
-	else                     sprintf(psz, "-0.0");
-	return 1;
+        if (VpIsPosZero(a)) {
+            if (fPlus == 1)      snprintf(buf, buflen, " 0.0");
+            else if (fPlus == 2) snprintf(buf, buflen, "+0.0");
+            else                 snprintf(buf, buflen,  "0.0");
+        }
+        else                     snprintf(buf, buflen, "-0.0");
+        return 1;
     }
     return 0;
 }
 
 VP_EXPORT void
-VpToString(Real *a, char *psz, size_t fFmt, int fPlus)
+VpToString(Real *a, char *buf, size_t buflen, size_t fFmt, int fPlus)
 /* fPlus = 0: default, 1: set ' ' before digits, 2: set '+' before digits. */
 {
     size_t i, n, ZeroSup;
     DECDIG shift, m, e, nn;
-    char *pszSav = psz;
+    char *p = buf;
+    size_t plen = buflen;
     ssize_t ex;
 
-    if (VpToSpecialString(a, psz, fPlus)) return;
+    if (VpToSpecialString(a, buf, buflen, fPlus)) return;
 
     ZeroSup = 1;    /* Flag not to print the leading zeros as 0.00xxxxEnn */
 
-    if (BIGDECIMAL_NEGATIVE_P(a)) *psz++ = '-';
-    else if (fPlus == 1)  *psz++ = ' ';
-    else if (fPlus == 2)  *psz++ = '+';
+#define ADVANCE(n) do { \
+    if (plen < n) goto overflow; \
+    p += n; \
+    plen -= n; \
+} while (0)
+
+    if (BIGDECIMAL_NEGATIVE_P(a)) {
+        *p = '-';
+        ADVANCE(1);
+    }
+    else if (fPlus == 1) {
+        *p = ' ';
+        ADVANCE(1);
+    }
+    else if (fPlus == 2) {
+        *p = '+';
+        ADVANCE(1);
+    }
+
+    *p = '0'; ADVANCE(1);
+    *p = '.'; ADVANCE(1);
 
-    *psz++ = '0';
-    *psz++ = '.';
     n = a->Prec;
     for (i = 0; i < n; ++i) {
-	m = BASE1;
-	e = a->frac[i];
-	while (m) {
-	    nn = e / m;
-	    if (!ZeroSup || nn) {
-		sprintf(psz, "%lu", (unsigned long)nn);    /* The reading zero(s) */
-		psz += strlen(psz);
-		/* as 0.00xx will be ignored. */
-		ZeroSup = 0;    /* Set to print succeeding zeros */
-	    }
-	    e = e - nn * m;
-	    m /= 10;
-	}
+        m = BASE1;
+        e = a->frac[i];
+        while (m) {
+            nn = e / m;
+            if (!ZeroSup || nn) {
+                /* The reading zero(s) */
+                size_t n = (size_t)snprintf(p, plen, "%lu", (unsigned long)nn);
+                if (n > plen) goto overflow;
+                ADVANCE(n);
+                /* as 0.00xx will be ignored. */
+                ZeroSup = 0;    /* Set to print succeeding zeros */
+            }
+            e = e - nn * m;
+            m /= 10;
+        }
     }
+
     ex = a->exponent * (ssize_t)BASE_FIG;
     shift = BASE1;
     while (a->frac[0] / shift == 0) {
-	--ex;
-	shift /= 10;
+        --ex;
+        shift /= 10;
     }
-    while (psz[-1] == '0') {
-	*(--psz) = 0;
+    while (p - 1 > buf && p[-1] == '0') {
+        *(--p) = '\0';
+        ++plen;
     }
-    sprintf(psz, "e%"PRIdSIZE, ex);
-    if (fFmt) VpFormatSt(pszSav, fFmt);
+    snprintf(p, plen, "e%"PRIdSIZE, ex);
+    if (fFmt) VpFormatSt(buf, fFmt);
+
+  overflow:
+    return;
+#undef ADVANCE
 }
 
 VP_EXPORT void
-VpToFString(Real *a, char *psz, size_t fFmt, int fPlus)
+VpToFString(Real *a, char *buf, size_t buflen, size_t fFmt, int fPlus)
 /* fPlus = 0: default, 1: set ' ' before digits, 2: set '+' before digits. */
 {
     size_t i, n;
     DECDIG m, e, nn;
-    char *pszSav = psz;
+    char *p = buf;
+    size_t plen = buflen;
     ssize_t ex;
 
-    if (VpToSpecialString(a, psz, fPlus)) return;
+    if (VpToSpecialString(a, buf, buflen, fPlus)) return;
+
+#define ADVANCE(n) do { \
+    if (plen < n) goto overflow; \
+    p += n; \
+    plen -= n; \
+} while (0)
 
-    if (BIGDECIMAL_NEGATIVE_P(a)) *psz++ = '-';
-    els (... truncated)

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

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