From: Jarkko Hietaniemi Date: Mon, 26 Mar 2007 19:50:11 +0000 (-0400) Subject: util.c [PATCH] perlhack.pod (Was: Re: threads crashes in Tru64) X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=ad7244db27635ed088fc05a8a69e99bbb19c36d6;p=p5sagit%2Fp5-mst-13.2.git util.c [PATCH] perlhack.pod (Was: Re: threads crashes in Tru64) Message-ID: <46085C33.1030601@iki.fi> p4raw-id: //depot/perl@30771 --- diff --git a/pod/perlhack.pod b/pod/perlhack.pod index 05e8751..b176b83 100644 --- a/pod/perlhack.pod +++ b/pod/perlhack.pod @@ -2844,6 +2844,22 @@ But in any case, try to keep the features and operating systems separate. =back +=head2 Problematic System Interfaces + +=over 4 + +=item * + +malloc(0), realloc(0), calloc(0, 0) are nonportable. To be portable +allocate at least one byte. (In general you should rarely need to +work at this low level, but instead use the various malloc wrappers.) + +=item * + +snprintf() - the return type is unportable. Use my_snprintf() instead. + +=back + =head2 Security problems Last but not least, here are various tips for safer coding. diff --git a/util.c b/util.c index 7478c39..8205aa8 100644 --- a/util.c +++ b/util.c @@ -258,14 +258,19 @@ Perl_safesyscalloc(MEM_SIZE count, MEM_SIZE size) { dTHX; Malloc_t ptr; -#if defined(DEBUGGING) || defined(HAS_64K_LIMIT) || defined(PERL_TRACK_MEMPOOL) - const MEM_SIZE total_size = size * count -#ifdef PERL_TRACK_MEMPOOL - + sTHX -#endif - ; -#endif + MEM_SIZE total_size = 0; + /* Even though calloc() for zero bytes is strange, be robust. */ + if (size && (count <= (MEM_SIZE)~0 / size)) + total_size = size * count; + else + Perl_croak_nocontext(PL_memory_wrap); +#ifdef PERL_TRACK_MEMPOOL + if (sTHX <= (MEM_SIZE)~0 - (MEM_SIZE)total_size) + total_size += sTHX; + else + Perl_croak_nocontext(PL_memory_wrap); +#endif #ifdef HAS_64K_LIMIT if (total_size > 0xffff) { PerlIO_printf(Perl_error_log, @@ -280,11 +285,15 @@ Perl_safesyscalloc(MEM_SIZE count, MEM_SIZE size) #ifdef PERL_TRACK_MEMPOOL /* Have to use malloc() because we've added some space for our tracking header. */ - ptr = (Malloc_t)PerlMem_malloc(total_size); + /* malloc(0) is non-portable. */ + ptr = (Malloc_t)PerlMem_malloc(total_size ? total_size : 1); #else /* Use calloc() because it might save a memset() if the memory is fresh and clean from the OS. */ - ptr = (Malloc_t)PerlMem_calloc(count, size); + if (count && size) + ptr = (Malloc_t)PerlMem_calloc(count, size); + else /* calloc(0) is non-portable. */ + ptr = (Malloc_t)PerlMem_calloc(count ? count : 1, size ? size : 1); #endif PERL_ALLOC_CHECK(ptr); DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%"UVxf": (%05ld) calloc %ld x %ld bytes\n",PTR2UV(ptr),(long)PL_an++,(long)count,(long)total_size));