From: Jarkko Hietaniemi Date: Sat, 15 Jul 2006 13:14:32 +0000 (+0300) Subject: various safety/portability tweaks X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=d130778686fc2c04eb7d731512df9e71304d5573;p=p5sagit%2Fp5-mst-13.2.git various safety/portability tweaks Message-ID: <44B8C008.4030300@iki.fi> p4raw-id: //depot/perl@28578 --- diff --git a/pod/perlhack.pod b/pod/perlhack.pod index a2c989e..e0a9807 100644 --- a/pod/perlhack.pod +++ b/pod/perlhack.pod @@ -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 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 * diff --git a/pod/perltodo.pod b/pod/perltodo.pod index a675b7a..6bf9d1f 100644 --- a/pod/perltodo.pod +++ b/pod/perltodo.pod @@ -163,11 +163,6 @@ when is duplicated in F. Writing things twice is bad, m'kay. It would be good to teach C 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 for TARGET machine, so this C is assumed then to be copied to TARGET machine and used as a replacement of full C executable. -This should be done litle differently. Namely C should be built for +This could be done little differently. Namely C should be built for HOST and then full C 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 platform +is using those naughty interfaces. =head1 Tasks that need a knowledge of the interpreter diff --git a/pp_sys.c b/pp_sys.c index a5028ba..d0b3b10 100644 --- 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 --- 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 --- 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); }