various safety/portability tweaks
Jarkko Hietaniemi [Sat, 15 Jul 2006 13:14:32 +0000 (16:14 +0300)]
Message-ID: <44B8C008.4030300@iki.fi>

p4raw-id: //depot/perl@28578

pod/perlhack.pod
pod/perltodo.pod
pp_sys.c
sv.c
util.c

index a2c989e..e0a9807 100644 (file)
@@ -2461,6 +2461,10 @@ reading.  Please test your changes with as many C compilers and
 platforms as possible -- we will, anyway, and it's nice to save
 oneself from public embarrassment.
 
+If using gcc, starting from Perl 5.9.4 Perl core C files will be
+compiled with the C<-std=c89> option which will hopefully catch
+most of these unportabilities.
+
 Also study L<perlport> carefully to avoid any bad assumptions
 about the operating system, filesystem, and so forth.
 
@@ -2771,13 +2775,11 @@ Or we will publicly ridicule you.  Seriously.
 
 =item *
 
-Do not use strcpy() or strcat()
+Do not use strcpy() or strcat() or strncpy() or strncat()
 
-While some uses of these still linger in the Perl source code,
-we have inspected them for safety and are very, very ashamed of them,
-and plan to get rid of them.  Use my_strlcpy() and my_strlcat() instead:
-they either use the native implementation, or Perl's own implementation
-(borrowed from the public domain implementation of INN).
+Use my_strlcpy() and my_strlcat() instead: they either use the native
+implementation, or Perl's own implementation (borrowed from the public
+domain implementation of INN).
 
 =item *
 
index a675b7a..6bf9d1f 100644 (file)
@@ -163,11 +163,6 @@ when is duplicated in F<makedef.pl>. Writing things twice is bad, m'kay.
 It would be good to teach C<embed.pl> to understand the conditional
 compilation, and hence remove the duplication, and the mistakes it has caused.
 
-
-
-
-
-
 =head1 Tasks that need a little sysadmin-type knowledge
 
 Or if you prefer, tasks that you would learn from, and broaden your skills
@@ -308,10 +303,10 @@ arranges for building C<miniperl> for TARGET machine, so this C<miniperl> is
 assumed then to be copied to TARGET machine and used as a replacement of full
 C<perl> executable.
 
-This should be done litle differently. Namely C<miniperl> should be built for
+This could be done little differently. Namely C<miniperl> should be built for
 HOST and then full C<perl> with extensions should be compiled for TARGET.
-
-
+This, however, might require extra trickery for %Config: we have one config
+first for HOST and then another for TARGET.
 
 =head1 Tasks that need a little C knowledge
 
@@ -493,9 +488,16 @@ system() accepts a LIST syntax (and a PROGRAM LIST syntax) to avoid
 running a shell. readpipe() (the function behind qx//) could be similarly
 extended.
 
+=head2 strcat(), strcpy(), strncat(), strncpy(), sprintf(), vsprintf()
 
+Maybe create a utility that checks after each libperl.a creation that
+none of the above (nor sprintf(), vsprintf(), or *SHUDDER* gets())
+ever creep back to libperl.a.
 
+  nm libperl.a | ./miniperl -alne '$o = $F[0] if /:$/; print "$o $F[1]" if $F[0] eq "U" && $F[1] =~ /^(?:strn?c(?:at|py)|v?sprintf|gets)$/'
 
+Note, of course, that this will only tell whether B<your> platform
+is using those naughty interfaces.
 
 =head1 Tasks that need a knowledge of the interpreter
 
index a5028ba..d0b3b10 100644 (file)
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -3589,7 +3589,8 @@ S_dooneliner(pTHX_ const char *cmd, const char *filename)
        *s++ = '\\';
        *s++ = *filename++;
     }
-    strcpy(s, " 2>&1");
+    if (s - cmdline < size)
+       my_strlcpy(s, " 2>&1", size - (s - cmdline));
     myfp = PerlProc_popen(cmdline, "r");
     Safefree(cmdline);
 
diff --git a/sv.c b/sv.c
index f2ad6d5..065a292 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -2800,7 +2800,7 @@ Perl_sv_2pv_flags(pTHX_ register SV *sv, STRLEN *lp, I32 flags)
        /* some Xenix systems wipe out errno here */
 #ifdef apollo
        if (SvNVX(sv) == 0.0)
-           (void)strcpy(s,"0");
+           my_strlcpy(s, "0", SvLEN(sv));
        else
 #endif /*apollo*/
        {
@@ -2809,7 +2809,7 @@ Perl_sv_2pv_flags(pTHX_ register SV *sv, STRLEN *lp, I32 flags)
        errno = olderrno;
 #ifdef FIXNEGATIVEZERO
         if (*s == '-' && s[1] == '0' && !s[2])
-           strcpy(s,"0");
+           my_strlcpy(s, "0", SvLEN(s));
 #endif
        while (*s) s++;
 #ifdef hcx
diff --git a/util.c b/util.c
index be619a3..c3d5948 100644 (file)
--- a/util.c
+++ b/util.c
@@ -5225,7 +5225,7 @@ Perl_mem_log_alloc(const UV n, const UV typesize, const char *typename, Malloc_t
        {
            const STRLEN len =
                my_snprintf(buf,
-                           PERL_MEM_LOG_SPRINTF_BUF_SIZE,
+                           sizeof(buf),
 #  ifdef PERL_MEM_LOG_TIMESTAMP
                            "%10d.%06d: "
 # endif
@@ -5270,7 +5270,7 @@ Perl_mem_log_realloc(const UV n, const UV typesize, const char *typename, Malloc
        {
            const STRLEN len =
                my_snprintf(buf,
-                           PERL_MEM_LOG_SPRINTF_BUF_SIZE,
+                           sizeof(buf),
 #  ifdef PERL_MEM_LOG_TIMESTAMP
                            "%10d.%06d: "
 # endif
@@ -5316,7 +5316,7 @@ Perl_mem_log_free(Malloc_t oldalloc, const char *filename, const int linenumber,
        {
            const STRLEN len =
                my_snprintf(buf,
-                           PERL_MEM_LOG_SPRINTF_BUF_SIZE,
+                           sizeof(buf),
 #  ifdef PERL_MEM_LOG_TIMESTAMP
                            "%10d.%06d: "
 # endif
@@ -5458,16 +5458,17 @@ Perl_my_clearenv(pTHX)
     (void)clearenv();
 #        elif defined(HAS_UNSETENV)
     int bsiz = 80; /* Most envvar names will be shorter than this. */
-    char *buf = (char*)safesysmalloc(bsiz * sizeof(char));
+    int bufsiz = bsiz * sizeof(char); /* sizeof(char) paranoid? */
+    char *buf = (char*)safesysmalloc(bufsiz);
     while (*environ != NULL) {
       char *e = strchr(*environ, '=');
       int l = e ? e - *environ : strlen(*environ);
       if (bsiz < l + 1) {
         (void)safesysfree(buf);
         bsiz = l + 1;
-        buf = (char*)safesysmalloc(bsiz * sizeof(char));
+        buf = (char*)safesysmalloc(bufsiz);
       } 
-      strncpy(buf, *environ, l);
+      my_strlcpy(buf, bufsiz, *environ, l);
       *(buf + l) = '\0';
       (void)unsetenv(buf);
     }