From 9c7003ff693f56a2f0a68917a78a735025fa488c Mon Sep 17 00:00:00 2001 From: Nelson Ferreira Date: Fri, 24 Feb 2012 12:51:35 -0500 Subject: [PATCH] Coverity: TOCTOU: CID 387 * lib-src/etags.c (process_file_name): use open/popen then handle failure, instead of stat. Also, after successful open check it is regular file, and reject it is not. Signed-off-by: Nelson Ferreira --- lib-src/etags.c | 91 ++++++++++++++++++++++++------------------------- 1 file changed, 45 insertions(+), 46 deletions(-) diff --git a/lib-src/etags.c b/lib-src/etags.c index b58ff0a..62e8959 100644 --- a/lib-src/etags.c +++ b/lib-src/etags.c @@ -1516,11 +1516,13 @@ char *file; language *lang; { struct stat stat_buf; - FILE *inf; - fdesc *fdp; - compressor *compr; - char *compressed_name, *uncompressed_name; - char *ext, *real_name; + FILE *inf = NULL; + fdesc *fdp = NULL; + compressor *compr = NULL; + char *compressed_name = NULL, + *uncompressed_name = NULL; + char *ext = NULL, + *real_name = NULL; int retval; canonicalize_filename (file); @@ -1531,7 +1533,6 @@ language *lang; } if ((compr = get_compressor_from_suffix (file, &ext)) == NULL) { - compressed_name = NULL; real_name = uncompressed_name = savestr (file); } else @@ -1549,52 +1550,50 @@ language *lang; goto cleanup; } - if (stat (real_name, &stat_buf) != 0) - { - /* Reset real_name and try with a different name. */ - real_name = NULL; - if (compressed_name != NULL) /* try with the given suffix */ + compr = compressors; + do { + /* First try to open ... */ + if (real_name == compressed_name) { - if (stat (uncompressed_name, &stat_buf) == 0) - real_name = uncompressed_name; + char *cmd = concat (compr->command, " ", real_name); + inf = (FILE *) popen (cmd, "r"); + free (cmd); } - else /* try all possible suffixes */ - { - for (compr = compressors; compr->suffix != NULL; compr++) + else + inf = fopen (real_name, "r"); + if ( inf != NULL ) { + /* Open was successfull, check it is a regular file */ + if (stat (real_name, &stat_buf) == 0 && + !S_ISREG (stat_buf.st_mode)) + { + error ("skipping %s: it is not a regular file.", + real_name); + fclose(inf); + inf = NULL; + } + } + /* Not else from previous if because inner check may reset inf + to NULL, at which case we will want to try the next? + compressed filename... */ + if ( inf == NULL ) { + /* Reset real_name and try with a different name. */ + free(compressed_name); + compressed_name = NULL; + real_name = NULL; + if (compressed_name != NULL) + /* try with the given suffix */ + { + real_name = uncompressed_name; + } + else if ( compr->suffix != NULL ) + /* try all possible suffixes */ { compressed_name = concat (file, ".", compr->suffix); - if (stat (compressed_name, &stat_buf) != 0) - { - free (compressed_name); - compressed_name = NULL; - } - else - { - real_name = compressed_name; - break; - } + real_name = compressed_name; + compr++; } } - if (real_name == NULL) - { - perror (file); - goto cleanup; - } - } /* try with a different name */ - - if (!S_ISREG (stat_buf.st_mode)) - { - error ("skipping %s: it is not a regular file.", real_name); - goto cleanup; - } - if (real_name == compressed_name) - { - char *cmd = concat (compr->command, " ", real_name); - inf = (FILE *) popen (cmd, "r"); - free (cmd); - } - else - inf = fopen (real_name, "r"); + } while( inf == NULL && real_name != NULL); if (inf == NULL) { perror (real_name); -- 2.25.1