commit ed9312f04bcebc7aee4f7e7d96d6ec467cb9bb66 from: Omar Polo date: Tue Jul 26 13:22:28 2022 UTC fix accounting for line endings in CRLF files There are two different subtles error in computing the end of line in diff_data_atomize_text_lines (one in per implementation, _fd and _mmap) that causes the '\n' of the '\r\n' case to be left out the current line. It causes strange bugs when diffing CRLF files, such as printing the "\ No newline at end of file" marker very often and showing the wrong offsets in the hunk headers. ok stsp@ commit - b72f51ffc39028023059fc994542565691b669fa commit + ed9312f04bcebc7aee4f7e7d96d6ec467cb9bb66 blob - 0531fabe30530664069034f1c3166fe9d18a6e54 blob + 79d9633bdaa73ce679a74c04294b35271c5374f7 --- lib/diff_atomize_text.c +++ lib/diff_atomize_text.c @@ -92,7 +92,7 @@ diff_data_atomize_text_lines_fd(struct diff_data *d) r = fread(buf, sizeof(char), sizeof(buf), d->root->f); if (r == 0 && ferror(d->root->f)) return errno; - if (r == 1 && buf[0] == '\n' ) + if (r > 0 && buf[0] == '\n') line_end++; } @@ -151,11 +151,9 @@ diff_data_atomize_text_lines_mmap(struct diff_data *d) /* When not at the end of data, the line ending char ('\r' or * '\n') must follow */ - if (line_end < end) + if (line_end < end && *line_end == '\r') line_end++; - /* If that was an '\r', also pull in any following '\n' */ - if (line_end < end - 1 && line_end[0] == '\r' && - line_end[1] == '\n') + if (line_end < end && *line_end == '\n') line_end++; /* Record the found line as diff atom */