Hi, I'd like to fix a few buffer overruns I have found in the gcov tools. First I noticed that the -x output contains most of the time "ff" bytes, and that when different source files exist in different directories, with same base name the MD5 sum always matches, which results in gcov overwriting the previous result file always, except if -l is given, which makes hashing the file names practically useless.
And secondly I wanted to fix potential buffer underflow if a file contains lines with begin with NUL ascii characters, and a out of memory due to always doubling the buffer space, even if the line buffer is not yet filled up. Bootstrapped and reg-tested on x86_64-pc-linux-gnu. Is it OK for trunk? Thanks Bernd.
2017-03-30 Bernd Edlinger <bernd.edlin...@hotmail.de> * gcov.c (md5sum_to_hex): Fix output of MD5 hex bytes. (make_gcov_file_name): Use the canonical path name for generating the MD5 value. (read_line): Fix handling of files with ascii null bytes. Index: gcc/gcov.c =================================================================== --- gcc/gcov.c (revision 246571) +++ gcc/gcov.c (working copy) @@ -2167,7 +2167,7 @@ static void md5sum_to_hex (const char *sum, char *buffer) { for (unsigned i = 0; i < 16; i++) - sprintf (buffer + (2 * i), "%02x", sum[i]); + sprintf (buffer + (2 * i), "%02x", (unsigned char)sum[i]); } /* Generate an output file name. INPUT_NAME is the canonicalized main @@ -2216,7 +2216,7 @@ make_gcov_file_name (const char *input_name, const char md5sum_hex[33]; md5_init_ctx (&ctx); - md5_process_bytes (result, strlen (result), &ctx); + md5_process_bytes (src_name, strlen (src_name), &ctx); md5_finish_ctx (&ctx, md5sum); md5sum_to_hex (md5sum, md5sum_hex); free (result); @@ -2512,14 +2512,17 @@ read_line (FILE *file) { size_t len = strlen (string + pos); - if (string[pos + len - 1] == '\n') + if (len && string[pos + len - 1] == '\n') { string[pos + len - 1] = 0; return string; } pos += len; - string = XRESIZEVEC (char, string, string_len * 2); - string_len *= 2; + if (pos > string_len / 2) + { + string_len *= 2; + string = XRESIZEVEC (char, string, string_len); + } } return pos ? string : NULL;