2525#include <stdlib.h>
2626#include <stdio.h>
2727#include <string.h> /* strcpy(), strlen() */
28+
29+ #ifdef HAVE_STDINT_H
30+ #include <stdint.h> /*PTRDIFF_MAX */
31+ #endif
32+ #ifndef PTRDIFF_MAX
33+ #define PTRDIFF_MAX SIZE_MAX
34+ #endif
35+
2836#include <errno.h> /* EINVAL */
2937#include <assert.h>
3038
@@ -189,11 +197,28 @@ void *NCI_Malloc_fn(size_t size,
189197 const char * func ,
190198 const char * filename )
191199{
192- void * buf = malloc (size );
200+ void * buf ;
201+
202+ /* Many C library implementations, particularly those designed to work with
203+ * GCC and Clang, limit single malloc allocations to PTRDIFF_MAX - 1 bytes.
204+ * ptrdiff_t is a signed integer type used for the difference between two
205+ * pointers, and PTRDIFF_MAX is its maximum value. This limitation exists
206+ * because some compiler optimizations and internal library operations may
207+ * rely on pointer differences being representable within ptrdiff_t.
208+ */
209+ if (size > PTRDIFF_MAX - 1 ) {
210+ fprintf (stderr , "NCI_Malloc(%zd) failed in file %s func %s line %d\n" ,
211+ size , filename , func , lineno );
212+ return NULL ;
213+ }
193214
194- if (size > 0 && buf == NULL )
195- fprintf (stderr , "malloc(%zd) failed in file %s func %s line %d\n" ,
215+ buf = malloc (size );
216+
217+ if (size > 0 && buf == NULL ) {
218+ fprintf (stderr , "NCI_Malloc(%zd) failed in file %s func %s line %d\n" ,
196219 size , filename , func , lineno );
220+ return NULL ;
221+ }
197222
198223#ifdef PNC_MALLOC_TRACE
199224 ncmpii_add_mem_entry (buf , size , lineno , func , filename );
@@ -216,16 +241,25 @@ void *NCI_Strdup_fn(const char *src,
216241
217242 if (src == NULL ) return NULL ;
218243
219- len = strlen (src );
220- buf = malloc (len + 1 );
244+ len = strlen (src ) + 1 ;
245+
246+ if (len > PTRDIFF_MAX - 1 ) {
247+ fprintf (stderr , "NCI_Strdup(%zd) failed in file %s func %s line %d\n" ,
248+ len , filename , func , lineno );
249+ return NULL ;
250+ }
251+
252+ buf = malloc (len );
221253
222- if (len >= 0 && buf == NULL )
223- fprintf (stderr , "malloc (%zd) failed in file %s func %s line %d\n" ,
254+ if (buf == NULL ) {
255+ fprintf (stderr , "NCI_Strdup (%zd) failed in file %s func %s line %d\n" ,
224256 len , filename , func , lineno );
257+ return NULL ;
258+ }
225259
226- if ( len > 0 ) memcpy (buf , src , len );
260+ memcpy (buf , src , len - 1 );
227261
228- ((char * )buf )[len ] = '\0' ;
262+ ((char * )buf )[len - 1 ] = '\0' ;
229263
230264#ifdef PNC_MALLOC_TRACE
231265 ncmpii_add_mem_entry (buf , len , lineno , func , filename );
@@ -246,11 +280,22 @@ void *NCI_Calloc_fn(size_t nelem,
246280 const char * func ,
247281 const char * filename )
248282{
249- void * buf = calloc ( nelem , elsize ) ;
283+ void * buf ;
250284
251- if (nelem > 0 && buf == NULL )
252- fprintf (stderr , "calloc (%zd, %zd) failed in file %s func %s line %d\n" ,
285+ if (nelem * elsize > PTRDIFF_MAX - 1 ) {
286+ fprintf (stderr , "NCI_Calloc (%zd, %zd) failed in file %s func %s line %d\n" ,
253287 nelem , elsize , filename , func , lineno );
288+ return NULL ;
289+ }
290+
291+ /* calloc() accepts zero size, to allow free() to be called later */
292+ buf = calloc (nelem , elsize );
293+
294+ if (nelem > 0 && buf == NULL ) {
295+ fprintf (stderr , "NCI_Calloc(%zd, %zd) failed in file %s func %s line %d\n" ,
296+ nelem , elsize , filename , func , lineno );
297+ return NULL ;
298+ }
254299
255300#ifdef PNC_MALLOC_TRACE
256301 ncmpii_add_mem_entry (buf , nelem * elsize , lineno , func , filename );
@@ -277,6 +322,12 @@ void *NCI_Realloc_fn(void *ptr,
277322{
278323 void * buf ;
279324
325+ if (size > PTRDIFF_MAX - 1 ) {
326+ fprintf (stderr , "NCI_Realloc(_, %zd) failed in file %s func %s line %d\n" ,
327+ size , filename , func , lineno );
328+ return NULL ;
329+ }
330+
280331 if (ptr == NULL ) return NCI_Malloc_fn (size , lineno , func , filename );
281332
282333 if (size == 0 ) {
@@ -285,15 +336,19 @@ void *NCI_Realloc_fn(void *ptr,
285336 }
286337
287338#ifdef PNC_MALLOC_TRACE
288- if (ncmpii_del_mem_entry (ptr ) != 0 )
289- fprintf (stderr , "realloc failed in file %s func %s line %d\n" ,
290- filename , func , lineno );
339+ if (ncmpii_del_mem_entry (ptr ) != 0 ) {
340+ fprintf (stderr , "NCI_Realloc(_, %zd) failed in file %s func %s line %d\n" ,
341+ size , filename , func , lineno );
342+ return NULL ;
343+ }
291344#endif
292345
293346 buf = (void * ) realloc (ptr , size );
294- if (buf == NULL )
295- fprintf (stderr , "realloc failed in file %s func %s line %d\n" ,
296- filename , func , lineno );
347+ if (buf == NULL ) {
348+ fprintf (stderr , "NCI_Realloc(_, %zd) failed in file %s func %s line %d\n" ,
349+ size , filename , func , lineno );
350+ return NULL ;
351+ }
297352
298353#ifdef PNC_MALLOC_TRACE
299354 ncmpii_add_mem_entry (buf , size , lineno , func , filename );
@@ -319,7 +374,7 @@ void NCI_Free_fn(void *ptr,
319374
320375#ifdef PNC_MALLOC_TRACE
321376 if (ncmpii_del_mem_entry (ptr ) != 0 )
322- fprintf (stderr , "free failed in file %s func %s line %d\n" ,
377+ fprintf (stderr , "NCI_Free failed in file %s func %s line %d\n" ,
323378 filename , func , lineno );
324379#endif
325380
0 commit comments