Re: [PATCH] use snprintf/strlcpy/strlcat when useful
Jarkko Hietaniemi [Tue, 25 Apr 2006 18:23:39 +0000 (21:23 +0300)]
Message-ID: <444E3EFB.8020503@gmail.com>

p4raw-id: //depot/perl@27987

op.c
perl.h
perlio.c
pp_ctl.c
regcomp.c
sv.c
toke.c
universal.c
util.c

diff --git a/op.c b/op.c
index 3c44f96..0b92b65 100644 (file)
--- a/op.c
+++ b/op.c
@@ -250,9 +250,13 @@ Perl_allocmy(pTHX_ char *name)
            p = strchr(name, '\0');
            /* The next block assumes the buffer is at least 205 chars
               long.  At present, it's always at least 256 chars. */
-           if (p-name > 200) {
-               strcpy(name+200, "...");
-               p = name+199;
+           if (p - name > 200) {
+#ifdef HAS_STRLCPY
+               strlcpy(name + 200, "...", 4);
+#else
+               strcpy(name + 200, "...");
+#endif
+               p = name + 199;
            }
            else {
                p[1] = '\0';
diff --git a/perl.h b/perl.h
index a383591..7c2ec66 100644 (file)
--- a/perl.h
+++ b/perl.h
@@ -1435,6 +1435,12 @@ int sockatmark(int);
 */
 #ifdef SPRINTF_RETURNS_STRLEN
 #  define my_sprintf sprintf
+#  ifdef HAS_SNPRINTF
+#    define USE_SNPRINTF
+#  endif
+#  ifdef HAS_VSNPRINTF
+#    define USE_VSNPRINTF
+#  endif
 #else
 #  define my_sprintf Perl_my_sprintf
 #endif
index 299d830..cc82ffd 100644 (file)
--- a/perlio.c
+++ b/perlio.c
@@ -475,7 +475,11 @@ PerlIO_debug(const char *fmt, ...)
        /* Use fixed buffer as sv_catpvf etc. needs SVs */
        char buffer[1024];
        const STRLEN len = my_sprintf(buffer, "%.40s:%" IVdf " ", s ? s : "(none)", (IV) CopLINE(PL_curcop));
+# ifdef USE_VSNPRINTF
+       const STRLEN len2 = vnsprintf(buffer+len, sizeof(buffer) - len, fmt, ap);
+# else
        const STRLEN len2 = vsprintf(buffer+len, fmt, ap);
+# endif /* USE_VSNPRINTF */
        PerlLIO_write(PL_perlio_debug_fd, buffer, len + len2);
 #else
        const char *s = CopFILE(PL_curcop);
@@ -5135,7 +5139,11 @@ int
 PerlIO_vsprintf(char *s, int n, const char *fmt, va_list ap)
 {
     dVAR;
+#ifdef USE_VSNPRINTF
+    const int val = vsnprintf(s, n, fmt, ap);
+#else
     const int val = vsprintf(s, fmt, ap);
+#endif /* #ifdef USE_VSNPRINTF */
     if (n >= 0) {
        if (strlen(s) >= (STRLEN) n) {
            dTHX;
index dd7d122..485a004 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -831,7 +831,11 @@ PP(pp_formline)
            /* Formats aren't yet marked for locales, so assume "yes". */
            {
                STORE_NUMERIC_STANDARD_SET_LOCAL();
+#ifdef USE_SNPRINTF
+               snprintf(t, SvLEN(PL_formtarget) - (t - SvPVX(PL_formtarget)), fmt, (int) fieldsize, (int) arg & 255, value);
+#else
                sprintf(t, fmt, (int) fieldsize, (int) arg & 255, value);
+#endif /* ifdef USE_SNPRINTF */
                RESTORE_NUMERIC_STANDARD();
            }
            t += fieldsize;
@@ -2769,8 +2773,13 @@ Perl_sv_compile_2op(pTHX_ SV *sv, OP** startop, const char *code, PAD** padp)
        len = SvCUR(sv);
     }
     else
+#ifdef USE_SNPRINTF
+       len = snprintf(tmpbuf, sizeof(tbuf), "_<(%.10s_eval %lu)", code,
+                      (unsigned long)++PL_evalseq);
+#else
        len = my_sprintf(tmpbuf, "_<(%.10s_eval %lu)", code,
                         (unsigned long)++PL_evalseq);
+#endif /* ifdef USE_SNPRINTF */
     SAVECOPFILE_FREE(&PL_compiling);
     CopFILE_set(&PL_compiling, tmpbuf+2);
     SAVECOPLINE(&PL_compiling);
@@ -3422,6 +3431,10 @@ PP(pp_entereval)
     CV* runcv;
     U32 seq;
     HV *saved_hh = NULL;
+    const char * const fakestr = "_<(eval )";
+#ifdef HAS_STRLCPY
+    const int fakelen = 9 + 1;
+#endif
     
     if (PL_op->op_private & OPpEVAL_HAS_HH) {
        saved_hh = (HV*) SvREFCNT_inc(POPs);
@@ -3447,7 +3460,11 @@ PP(pp_entereval)
        len = SvCUR(temp_sv);
     }
     else
+#ifdef USE_SNPRINTF
+       len = snprintf(tmpbuf, sizeof(tbuf), "_<(eval %lu)", (unsigned long)++PL_evalseq);
+#else
        len = my_sprintf(tmpbuf, "_<(eval %lu)", (unsigned long)++PL_evalseq);
+#endif /* ifdef USE_SNPRINTF */
     SAVECOPFILE_FREE(&PL_compiling);
     CopFILE_set(&PL_compiling, tmpbuf+2);
     SAVECOPLINE(&PL_compiling);
@@ -3500,7 +3517,12 @@ PP(pp_entereval)
     ret = doeval(gimme, NULL, runcv, seq);
     if (PERLDB_INTER && was != (I32)PL_sub_generation /* Some subs defined here. */
        && ret != PL_op->op_next) {     /* Successive compilation. */
-       strcpy(safestr, "_<(eval )");   /* Anything fake and short. */
+       /* Copy in anything fake and short. */
+#ifdef HAS_STRLCPY
+       strlcpy(safestr, fakestr, fakelen);
+#else
+       strcpy(safestr, fakestr);
+#endif /* #ifdef HAS_STRLCPY */
     }
     return DOCATCH(ret);
 }
index 8a2ad3a..da245b1 100644 (file)
--- a/regcomp.c
+++ b/regcomp.c
@@ -6184,7 +6184,11 @@ Perl_save_re_context(pTHX)
            U32 i;
            for (i = 1; i <= rx->nparens; i++) {
                char digits[TYPE_CHARS(long)];
+#ifdef USE_SNPRINTF
+               const STRLEN len = snprintf(digits, sizeof(digits), "%lu", (long)i);
+#else
                const STRLEN len = my_sprintf(digits, "%lu", (long)i);
+#endif /* #ifdef USE_SNPRINTF */
                GV *const *const gvp
                    = (GV**)hv_fetch(PL_defstash, digits, len, 0);
 
diff --git a/sv.c b/sv.c
index 30b118b..58bbad6 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -2656,8 +2656,14 @@ Perl_sv_2pv_flags(pTHX_ register SV *sv, STRLEN *lp, I32 flags)
            STRLEN len;
 
            if (SvIOKp(sv)) {
-               len = SvIsUV(sv) ? my_sprintf(tbuf,"%"UVuf, (UV)SvUVX(sv))
-                   : my_sprintf(tbuf,"%"IVdf, (IV)SvIVX(sv));
+               len = SvIsUV(sv)
+#ifdef USE_SNPRINTF
+                   ? snprintf(tbuf, sizeof(tbuf), "%"UVuf, (UV)SvUVX(sv))
+                   : snprintf(tbuf, sizeof(tbuf), "%"IVdf, (IV)SvIVX(sv));
+#else
+                   ? my_sprintf(tbuf, "%"UVuf, (UV)SvUVX(sv))
+                   : my_sprintf(tbuf, "%"IVdf, (IV)SvIVX(sv));
+#endif /* #ifdef USE_SNPRINTF */
            } else {
                Gconvert(SvNVX(sv), NV_DIG, 0, tbuf);
                len = strlen(tbuf);
@@ -9260,8 +9266,13 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV
                 * --jhi */
 #if defined(HAS_LONG_DOUBLE)
                elen = ((intsize == 'q')
+# ifdef USE_SNPRINTF
+                       ? snprintf(PL_efloatbuf, PL_efloatsize, ptr, nv)
+                       : snprintf(PL_efloatbuf, PL_efloatsize, ptr, (double)nv));
+# else
                        ? my_sprintf(PL_efloatbuf, ptr, nv)
                        : my_sprintf(PL_efloatbuf, ptr, (double)nv));
+# endif /* #ifdef USE_SNPRINTF */
 #else
                elen = my_sprintf(PL_efloatbuf, ptr, nv);
 #endif
diff --git a/toke.c b/toke.c
index fc997ad..562a36c 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -5975,7 +5975,11 @@ Perl_yylex(pTHX)
                if (!PL_in_my_stash) {
                    char tmpbuf[1024];
                    PL_bufptr = s;
+#ifdef USE_SNPRINTF
+                   snprintf(tmpbuf, sizeof(tmpbuf), "No such class %.1000s", PL_tokenbuf);
+#else
                    sprintf(tmpbuf, "No such class %.1000s", PL_tokenbuf);
+#endif /* #ifdef USE_SNPRINTF */
                    yyerror(tmpbuf);
                }
 #ifdef PERL_MAD
index 8802cb2..e94c602 100644 (file)
@@ -619,7 +619,11 @@ XS(XS_version_qv)
            if ( SvNOK(ver) ) /* may get too much accuracy */
            {
                char tbuf[64];
-               const STRLEN len = my_sprintf(tbuf,"%.9"NVgf, SvNVX(ver));
+#ifdef USE_SNPRINTF
+               const STRLEN len = snprintf(tbuf, sizeof(tbuf), "%.9"NVgf, SvNVX(ver));
+#else
+               const STRLEN len = my_sprintf(tbuf, "%.9"NVgf, SvNVX(ver));
+#endif /* #ifdef USE_SNPRINTF  */
                version = savepvn(tbuf, len);
            }
            else
diff --git a/util.c b/util.c
index c003291..873d3cb 100644 (file)
--- a/util.c
+++ b/util.c
@@ -3115,9 +3115,13 @@ Perl_find_script(pTHX_ const char *scriptname, bool dosearch,
            if (len == 2 && tmpbuf[0] == '.')
                seen_dot = 1;
 #endif
+#ifdef HAS_STRLCAT
+           (void)strlcpy(tmpbuf + len, scriptname, sizeof(tmpbuf) - len);
+#else
            /* FIXME? Convert to memcpy by storing previous strlen(scriptname)
             */
            (void)strcpy(tmpbuf + len, scriptname);
+#endif /* #ifdef HAS_STRLCAT */
 #endif  /* !VMS */
 
 #ifdef SEARCH_EXTS
@@ -4290,7 +4294,11 @@ Perl_upg_version(pTHX_ SV *ver)
     if ( SvNOK(ver) ) /* may get too much accuracy */ 
     {
        char tbuf[64];
-       const STRLEN len = my_sprintf(tbuf,"%.9"NVgf, SvNVX(ver));
+#ifdef USE_SNPRINTF
+       const STRLEN len = snprintf(tbuf, sizeof(tbuf), "%.9"NVgf, SvNVX(ver));
+#else
+       const STRLEN len = my_sprintf(tbuf, "%.9"NVgf, SvNVX(ver));
+#endif /* #ifdef USE_SNPRINTF */
        version = savepvn(tbuf, len);
     }
 #ifdef SvVOK