libdiff: Simplify truncation detection
* Adjust the comment to reflect the fact that SIGBUS can occur not only if the file is truncated, but also if an I/O error occurs while paging in any part of it. * Instead of setting a flag, just return EIO. * Adjust the unit test accordingly. MFC after: 1 week Sponsored by: Klara, Inc. Reviewed by: thj, kevans Differential Revision: https://reviews.freebsd.org/D55108
This commit is contained in:
@@ -118,7 +118,6 @@ struct diff_data {
|
||||
|
||||
/* Flags set by file atomizer. */
|
||||
#define DIFF_ATOMIZER_FOUND_BINARY_DATA 0x00000001
|
||||
#define DIFF_ATOMIZER_FILE_TRUNCATED 0x00000002
|
||||
|
||||
/* Flags set by caller of diff_main(). */
|
||||
#define DIFF_FLAG_IGNORE_WHITESPACE 0x00000001
|
||||
|
||||
@@ -141,6 +141,7 @@ diff_data_atomize_text_lines_mmap(struct diff_data *d)
|
||||
bool embedded_nul = false;
|
||||
unsigned int array_size_estimate = d->len / 50;
|
||||
unsigned int pow2 = 1;
|
||||
int ret = DIFF_RC_OK;
|
||||
while (array_size_estimate >>= 1)
|
||||
pow2++;
|
||||
|
||||
@@ -152,13 +153,14 @@ diff_data_atomize_text_lines_mmap(struct diff_data *d)
|
||||
sigaction(SIGBUS, &act, &oact);
|
||||
if (sigsetjmp(diff_data_signal_env, 0) > 0) {
|
||||
/*
|
||||
* The file was truncated while we were reading it. Set
|
||||
* the end pointer to the beginning of the line we were
|
||||
* trying to read, adjust the file length, and set a flag.
|
||||
* The file was truncated while we were reading it, or an
|
||||
* I/O error occurred. Set the end pointer to the
|
||||
* beginning of the line we were trying to read, adjust
|
||||
* the file length, and set the return value to an error.
|
||||
*/
|
||||
end = pos;
|
||||
d->len = end - d->data;
|
||||
d->atomizer_flags |= DIFF_ATOMIZER_FILE_TRUNCATED;
|
||||
ret = EIO;
|
||||
}
|
||||
while (pos < end) {
|
||||
const uint8_t *line_start = pos, *line_end = pos;
|
||||
@@ -203,7 +205,7 @@ diff_data_atomize_text_lines_mmap(struct diff_data *d)
|
||||
if (embedded_nul)
|
||||
d->atomizer_flags |= DIFF_ATOMIZER_FOUND_BINARY_DATA;
|
||||
|
||||
return DIFF_RC_OK;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
|
||||
@@ -45,10 +45,9 @@ ATF_TC_BODY(diff_atomize_truncated, tc)
|
||||
rewind(f);
|
||||
ATF_REQUIRE(truncate(fn, size / 2) == 0);
|
||||
ATF_REQUIRE((p = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fileno(f), 0)) != MAP_FAILED);
|
||||
ATF_REQUIRE(diff_atomize_file(&d, &cfg, f, p, size, 0) == 0);
|
||||
ATF_REQUIRE(diff_atomize_file(&d, &cfg, f, p, size, 0) == EIO);
|
||||
ATF_REQUIRE((size_t)d.len <= size / 2);
|
||||
ATF_REQUIRE((size_t)d.len >= size / 2 - sizeof(line));
|
||||
ATF_REQUIRE(d.atomizer_flags & DIFF_ATOMIZER_FILE_TRUNCATED);
|
||||
}
|
||||
ATF_TC_CLEANUP(diff_atomize_truncated, tc)
|
||||
{
|
||||
|
||||
@@ -223,14 +223,10 @@ diffreg_new(char *file1, char *file2, int flags, int capsicum)
|
||||
rc = D_ERROR;
|
||||
goto done;
|
||||
}
|
||||
if (left.atomizer_flags & DIFF_ATOMIZER_FILE_TRUNCATED)
|
||||
warnx("%s truncated", file1);
|
||||
if (diff_atomize_file(&right, cfg, f2, (uint8_t *)str2, st2.st_size, diff_flags)) {
|
||||
rc = D_ERROR;
|
||||
goto done;
|
||||
}
|
||||
if (right.atomizer_flags & DIFF_ATOMIZER_FILE_TRUNCATED)
|
||||
warnx("%s truncated", file2);
|
||||
|
||||
result = diff_main(cfg, &left, &right);
|
||||
if (result->rc != DIFF_RC_OK) {
|
||||
|
||||
Reference in New Issue
Block a user