diff options
author | Jarkko Hietaniemi <jhi@iki.fi> | 2007-03-26 15:50:11 -0400 |
---|---|---|
committer | H.Merijn Brand <h.m.brand@xs4all.nl> | 2007-03-27 06:17:25 +0000 |
commit | ad7244db27635ed088fc05a8a69e99bbb19c36d6 (patch) | |
tree | a1b5453552fe78cc237f814fff2fdbc5a1403ce1 | |
parent | c8fb9d349396af98577278122fee7357e4ce610e (diff) | |
download | perl-ad7244db27635ed088fc05a8a69e99bbb19c36d6.tar.gz |
util.c [PATCH] perlhack.pod (Was: Re: threads crashes in Tru64)
Message-ID: <46085C33.1030601@iki.fi>
p4raw-id: //depot/perl@30771
-rw-r--r-- | pod/perlhack.pod | 16 | ||||
-rw-r--r-- | util.c | 27 |
2 files changed, 34 insertions, 9 deletions
diff --git a/pod/perlhack.pod b/pod/perlhack.pod index 05e8751369..b176b83721 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. @@ -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)); |