@@ -234,33 +234,70 @@ static void LinkTable_uninitialised_fill(LinkTable *linktbl)
234234 int u ;
235235 char s [STATUS_LEN ];
236236 lprintf (debug , " ... " );
237+
238+ /*
239+ * Start all uninitialized requests once
240+ */
241+ int total_uninitialized = 0 ;
242+ for (int i = 0 ; i < linktbl -> num ; i ++ ) {
243+ Link * this_link = linktbl -> links [i ];
244+ if (this_link -> type == LINK_UNINITIALISED_FILE
245+ || this_link -> type == LINK_UNINITIALISED_DIR ) {
246+ Link_req_file_stat (linktbl -> links [i ]);
247+ total_uninitialized ++ ;
248+ }
249+ }
250+
251+ if (total_uninitialized == 0 ) {
252+ lprintf (debug , "Done!\n" );
253+ return ;
254+ }
255+
256+ int n = total_uninitialized ;
257+ int j = 0 ;
237258 do {
238259 u = 0 ;
239260 for (int i = 0 ; i < linktbl -> num ; i ++ ) {
240261 Link * this_link = linktbl -> links [i ];
241262 if (this_link -> type == LINK_UNINITIALISED_FILE
242263 || this_link -> type == LINK_UNINITIALISED_DIR ) {
243- Link_req_file_stat (linktbl -> links [i ]);
244264 u ++ ;
245265 }
246266 }
247- /*
248- * Block until the gaps are filled
249- */
250- int n = curl_multi_perform_once ();
251- int i = 0 ;
252- int j = 0 ;
253- while ((i = curl_multi_perform_once ())) {
267+
268+ if (u > 0 ) {
254269 if (CONFIG .log_type & debug ) {
255270 if (j ) {
256271 erase_string (stderr , STATUS_LEN , s );
257272 }
258- snprintf (s , STATUS_LEN , "%d / %d" , n - i , n );
273+ snprintf (s , STATUS_LEN , "%d / %d" , n - u , n );
259274 fprintf (stderr , "%s" , s );
260275 j ++ ;
261276 }
277+
278+ /*
279+ * Block until some handles are processed
280+ */
281+ int n_running = curl_multi_perform_once ();
282+
283+ /*
284+ * If no handles are running but u > 0, we have an error
285+ * and we must break to avoid infinite loop.
286+ */
287+ if (n_running == 0 && u > 0 ) {
288+ lprintf (error , "Some links failed to initialize.\n" );
289+ for (int i = 0 ; i < linktbl -> num ; i ++ ) {
290+ Link * this_link = linktbl -> links [i ];
291+ if (this_link -> type == LINK_UNINITIALISED_FILE
292+ || this_link -> type == LINK_UNINITIALISED_DIR ) {
293+ this_link -> type = LINK_INVALID ;
294+ }
295+ }
296+ break ;
297+ }
262298 }
263- } while (u );
299+ } while (u > 0 );
300+
264301 if (CONFIG .log_type & debug ) {
265302 erase_string (stderr , STATUS_LEN , s );
266303 fprintf (stderr , "... Done!\n" );
@@ -802,6 +839,9 @@ LinkTable *path_to_LinkTable(const char *path)
802839 tmp_link = & link_cpy ;
803840 } else {
804841 link = path_to_Link (path );
842+ if (!link ) {
843+ return NULL ;
844+ }
805845 tmp_link = link ;
806846 }
807847
@@ -837,6 +877,10 @@ LinkTable *path_to_LinkTable(const char *path)
837877
838878static Link * path_to_Link_recursive (char * path , LinkTable * linktbl )
839879{
880+ if (!linktbl || !path || path [0 ] == '\0' ) {
881+ return NULL ;
882+ }
883+
840884 /*
841885 * skip the leading '/' if it exists
842886 */
@@ -847,12 +891,15 @@ static Link *path_to_Link_recursive(char *path, LinkTable *linktbl)
847891 /*
848892 * remove the last '/' if it exists
849893 */
850- char * slash = & (path [strnlen (path , MAX_PATH_LEN ) - 1 ]);
851- if (* slash == '/' ) {
852- * slash = '\0' ;
894+ size_t path_len = strnlen (path , MAX_PATH_LEN );
895+ if (path_len > 0 ) {
896+ char * slash = & (path [path_len - 1 ]);
897+ if (* slash == '/' ) {
898+ * slash = '\0' ;
899+ }
853900 }
854901
855- slash = strchr (path , '/' );
902+ char * slash = strchr (path , '/' );
856903 if (slash == NULL ) {
857904 /*
858905 * We cannot find another '/', we have reached the last level
0 commit comments