@@ -242,7 +242,7 @@ static void LinkTable_uninitialised_fill(LinkTable *linktbl)
242242 * Start all uninitialized requests once
243243 */
244244 int total_uninitialized = 0 ;
245- for (int i = 0 ; i < linktbl -> num ; i ++ ) {
245+ for (int i = 0 ; i < linktbl -> size ; i ++ ) {
246246 Link * this_link = linktbl -> links [i ];
247247 if (this_link -> type == LINK_UNINITIALISED_FILE
248248 || this_link -> type == LINK_UNINITIALISED_DIR ) {
@@ -260,7 +260,7 @@ static void LinkTable_uninitialised_fill(LinkTable *linktbl)
260260 int j = 0 ;
261261 do {
262262 u = 0 ;
263- for (int i = 0 ; i < linktbl -> num ; i ++ ) {
263+ for (int i = 0 ; i < linktbl -> size ; i ++ ) {
264264 Link * this_link = linktbl -> links [i ];
265265 if (this_link -> type == LINK_UNINITIALISED_FILE
266266 || this_link -> type == LINK_UNINITIALISED_DIR ) {
@@ -284,7 +284,7 @@ static void LinkTable_uninitialised_fill(LinkTable *linktbl)
284284 int n_running = curl_multi_perform_once ();
285285
286286 if (n_running == 0 ) {
287- for (int i = 0 ; i < linktbl -> num ; i ++ ) {
287+ for (int i = 0 ; i < linktbl -> size ; i ++ ) {
288288 Link * this_link = linktbl -> links [i ];
289289 if (this_link -> type == LINK_UNINITIALISED_FILE
290290 || this_link -> type == LINK_UNINITIALISED_DIR ) {
@@ -367,14 +367,10 @@ LinkTable *LinkSystem_init(const char *url)
367367
368368void LinkTable_add (LinkTable * linktbl , Link * link )
369369{
370- linktbl -> num ++ ;
371- Link * * tmp = (Link * * )realloc ((void * )linktbl -> links ,
372- linktbl -> num * sizeof (Link * ));
373- if (!tmp ) {
374- lprintf (fatal , "realloc() failure!\n" );
375- }
376- linktbl -> links = tmp ;
377- linktbl -> links [linktbl -> num - 1 ] = link ;
370+ linktbl -> links = (Link * * )REALLOC (
371+ (void * )linktbl -> links , ((size_t )linktbl -> size + 1 ) * sizeof (Link * ));
372+ linktbl -> links [linktbl -> size ] = link ;
373+ linktbl -> size ++ ;
378374}
379375
380376static LinkType linkname_to_LinkType (const char * linkname )
@@ -479,7 +475,7 @@ static void HTML_to_LinkTable(const char *url, GumboNode *node,
479475 if ((type == LINK_UNINITIALISED_DIR )
480476 || (type == LINK_UNINITIALISED_FILE )) {
481477 int identical_link_found = 0 ;
482- for (int i = 0 ; i < linktbl -> num ; i ++ ) {
478+ for (int i = 0 ; i < linktbl -> size ; i ++ ) {
483479 if (linknames_equal (relative_url ,
484480 linktbl -> links [i ]-> linkname )) {
485481 identical_link_found = 1 ;
@@ -544,7 +540,7 @@ static void LinkTable_fill(LinkTable *linktbl)
544540{
545541 Link * head_link = linktbl -> links [0 ];
546542 lprintf (debug , "Filling %s\n" , head_link -> f_url );
547- for (int i = 1 ; i < linktbl -> num ; i ++ ) {
543+ for (int i = 1 ; i < linktbl -> size ; i ++ ) {
548544 Link * this_link = linktbl -> links [i ];
549545 /* Some web sites use characters in their href attributes that really
550546 shouldn't be in their href attributes, most commonly spaces. And
@@ -582,9 +578,13 @@ static void LinkTable_fill(LinkTable *linktbl)
582578void LinkTable_free (LinkTable * linktbl )
583579{
584580 if (linktbl ) {
585- for (int i = 0 ; i < linktbl -> num ; i ++ ) {
586- LinkTable_free (linktbl -> links [i ]-> next_table );
587- FREE (linktbl -> links [i ]);
581+ for (int i = 0 ; i < linktbl -> size ; i ++ ) {
582+ Link * entry = linktbl -> links ? linktbl -> links [i ] : NULL ;
583+ if (!entry ) {
584+ continue ;
585+ }
586+ LinkTable_free (entry -> next_table );
587+ FREE (entry );
588588 }
589589 FREE (linktbl -> links );
590590 FREE (linktbl );
@@ -599,7 +599,7 @@ void LinkTable_print(LinkTable *linktbl)
599599 lprintf (info , " LinkTable %p for %s\n" , (void * )linktbl ,
600600 linktbl -> links [0 ]-> f_url );
601601 lprintf (info , "--------------------------------------------\n" );
602- for (int i = 0 ; i < linktbl -> num ; i ++ ) {
602+ for (int i = 0 ; i < linktbl -> size ; i ++ ) {
603603 Link * this_link = linktbl -> links [i ];
604604 lprintf (info , "%d %c %lu %s %s\n" , i , this_link -> type ,
605605 this_link -> content_length , this_link -> linkname ,
@@ -618,7 +618,7 @@ void LinkTable_print(LinkTable *linktbl)
618618LinkTable * LinkTable_alloc (const char * url )
619619{
620620 LinkTable * linktbl = CALLOC (1 , sizeof (LinkTable ));
621- linktbl -> num = 0 ;
621+ linktbl -> size = 0 ;
622622 linktbl -> index_time = 0 ;
623623 linktbl -> links = NULL ;
624624
@@ -629,7 +629,7 @@ LinkTable *LinkTable_alloc(const char *url)
629629 Link * head_link = Link_new ("/" , LINK_HEAD );
630630 LinkTable_add (linktbl , head_link );
631631 strncpy (head_link -> f_url , url , PATH_MAX );
632- assert (linktbl -> num == 1 );
632+ assert (linktbl -> size == 1 );
633633 return linktbl ;
634634}
635635
@@ -743,12 +743,12 @@ int LinkTable_disk_save(LinkTable *linktbl, const char *dirn)
743743 }
744744
745745 lprintf (debug , "linktbl->index_time: %ld\n" , (long )linktbl -> index_time );
746- if (fwrite (& linktbl -> num , sizeof (int ), 1 , fp ) != 1
746+ if (fwrite (& linktbl -> size , sizeof (int ), 1 , fp ) != 1
747747 || fwrite (& linktbl -> index_time , sizeof (time_t ), 1 , fp ) != 1 ) {
748748 lprintf (error , "Failed to save the header of %s!\n" , path );
749749 }
750750 FREE (path );
751- for (int i = 0 ; i < linktbl -> num ; i ++ ) {
751+ for (int i = 0 ; i < linktbl -> size ; i ++ ) {
752752 ignore_value (
753753 fwrite (linktbl -> links [i ]-> linkname , sizeof (char ), NAME_MAX , fp ));
754754 ignore_value (
@@ -788,7 +788,8 @@ LinkTable *LinkTable_disk_open(const char *dirn)
788788 }
789789
790790 LinkTable * linktbl = CALLOC (1 , sizeof (LinkTable ));
791- if (fread (& linktbl -> num , sizeof (int ), 1 , fp ) != 1
791+ int sz = 0 ;
792+ if (fread (& sz , sizeof (int ), 1 , fp ) != 1
792793 || fread (& linktbl -> index_time , sizeof (time_t ), 1 , fp ) != 1 ) {
793794 lprintf (error , "Failed to read the header of %s!\n" , path );
794795 fclose (fp );
@@ -797,10 +798,48 @@ LinkTable *LinkTable_disk_open(const char *dirn)
797798 FREE (path );
798799 return NULL ;
799800 }
801+
802+ long entry_size = (long )(NAME_MAX + PATH_MAX + sizeof (LinkType )
803+ + sizeof (size_t ) + sizeof (long ));
804+ if (fseek (fp , 0 , SEEK_END ) != 0 ) {
805+ lprintf (error , "Failed to seek %s!\n" , path );
806+ fclose (fp );
807+ LinkTable_free (linktbl );
808+ LinkTable_disk_delete (dirn );
809+ FREE (path );
810+ return NULL ;
811+ }
812+ long file_size = ftell (fp );
813+ if (file_size < 0
814+ || fseek (fp , (long )(sizeof (int ) + sizeof (time_t )), SEEK_SET ) != 0 ) {
815+ lprintf (error , "Failed to inspect %s!\n" , path );
816+ fclose (fp );
817+ LinkTable_free (linktbl );
818+ LinkTable_disk_delete (dirn );
819+ FREE (path );
820+ return NULL ;
821+ }
822+
823+ long max_entries
824+ = (file_size - (long )(sizeof (int ) + sizeof (time_t ))) / entry_size ;
825+
826+ if (sz < 1 || max_entries < sz ) {
827+ lprintf (error , "Invalid link table size: %d in %s!\n" , sz , path );
828+ fclose (fp );
829+ LinkTable_free (linktbl );
830+ LinkTable_disk_delete (dirn );
831+ FREE (path );
832+ return NULL ;
833+ }
834+
835+ linktbl -> size = sz ;
800836 lprintf (debug , "linktbl->index_time: %ld\n" , (long )linktbl -> index_time );
801837
802- linktbl -> links = (Link * * )CALLOC (linktbl -> num , sizeof (Link * ));
803- for (int i = 0 ; i < linktbl -> num ; i ++ ) {
838+ linktbl -> links
839+ = (Link * * )CALLOC ( // NOLINT(clang-analyzer-optin.taint.TaintedAlloc)
840+ sz , sizeof (Link * ));
841+
842+ for (int i = 0 ; i < sz ; i ++ ) {
804843 linktbl -> links [i ] = CALLOC (1 , sizeof (Link ));
805844 if (fread (linktbl -> links [i ]-> linkname , sizeof (char ), NAME_MAX , fp )
806845 != NAME_MAX
@@ -905,7 +944,7 @@ static Link *path_to_Link_recursive(char *path, LinkTable *linktbl)
905944 /*
906945 * We cannot find another '/', we have reached the last level
907946 */
908- for (int i = 1 ; i < linktbl -> num ; i ++ ) {
947+ for (int i = 1 ; i < linktbl -> size ; i ++ ) {
909948 if (!strncmp (path , linktbl -> links [i ]-> linkname , NAME_MAX )) {
910949 /*
911950 * We found our link
@@ -928,7 +967,7 @@ static Link *path_to_Link_recursive(char *path, LinkTable *linktbl)
928967 * move the pointer past the '/'
929968 */
930969 char * next_path = slash + 1 ;
931- for (int i = 1 ; i < linktbl -> num ; i ++ ) {
970+ for (int i = 1 ; i < linktbl -> size ; i ++ ) {
932971 if (!strncmp (path , linktbl -> links [i ]-> linkname , NAME_MAX )) {
933972 /*
934973 * The next sub-directory exists
@@ -964,7 +1003,7 @@ Link *path_to_Link(const char *path)
9641003 (unsigned long )pthread_self ());
9651004
9661005 PTHREAD_MUTEX_LOCK (& link_lock );
967- char * new_path = strndup (path , PATH_MAX );
1006+ char * new_path = STRNDUP (path , PATH_MAX );
9681007 if (!new_path ) {
9691008 lprintf (fatal , "cannot allocate memory\n" );
9701009 }
0 commit comments