diff options
author | Volker Lendecke <vl@samba.org> | 2019-05-01 15:34:22 +0200 |
---|---|---|
committer | Uri Simchoni <uri@samba.org> | 2019-07-17 12:45:51 +0000 |
commit | 69cca061a4e176c3d23f5f0771893011adafc940 (patch) | |
tree | 70501906c1f3aa2370ced795454698f6f1ca7826 /lib | |
parent | 79e3b1c71f59591c54e87299984e50d2ffb00b6b (diff) | |
download | samba-69cca061a4e176c3d23f5f0771893011adafc940.tar.gz |
lib: Optimize file_compare
Triggered by two coverity false positives. Loading both files into
talloc'ed memory seems inefficient to me. Rely on stdio to do proper
buffering. This removes the restriction from ae95d611: "It is meant for
small files".
This is more lines, but to me it has less implicit complexity.
Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Uri Simchoni <uri@samba.org>
Autobuild-User(master): Uri Simchoni <uri@samba.org>
Autobuild-Date(master): Wed Jul 17 12:45:51 UTC 2019 on sn-devel-184
Diffstat (limited to 'lib')
-rw-r--r-- | lib/util/util_file.c | 55 |
1 files changed, 41 insertions, 14 deletions
diff --git a/lib/util/util_file.c b/lib/util/util_file.c index 48ee03fb5f9..5260ee9d721 100644 --- a/lib/util/util_file.c +++ b/lib/util/util_file.c @@ -382,22 +382,49 @@ _PUBLIC_ int fdprintf(int fd, const char *format, ...) */ bool file_compare(const char *path1, const char *path2) { - size_t size1, size2; - char *p1, *p2; - TALLOC_CTX *mem_ctx = talloc_new(NULL); - - p1 = file_load(path1, &size1, 0, mem_ctx); - p2 = file_load(path2, &size2, 0, mem_ctx); - if (!p1 || !p2 || size1 != size2) { - talloc_free(mem_ctx); - return false; + FILE *f1 = NULL, *f2 = NULL; + uint8_t buf1[1024], buf2[1024]; + bool ret = false; + + f1 = fopen(path1, "r"); + if (f1 == NULL) { + goto done; } - if (memcmp(p1, p2, size1) != 0) { - talloc_free(mem_ctx); - return false; + f2 = fopen(path2, "r"); + if (f2 == NULL) { + goto done; } - talloc_free(mem_ctx); - return true; + + while (!feof(f1)) { + size_t n1 = fread(buf1, 1, sizeof(buf1), f1); + size_t n2 = fread(buf2, 1, sizeof(buf2), f2); + + if (n1 != n2) { + goto done; + } + if (n1 == 0) { + ret = (feof(f1) && feof(f2)); + goto done; + } + if (memcmp(buf1, buf2, n1) != 0) { + goto done; + } + if (n1 < sizeof(buf1)) { + bool has_error = (ferror(f1) || ferror(f2)); + if (has_error) { + goto done; + } + } + } + ret = true; +done: + if (f2 != NULL) { + fclose(f2); + } + if (f1 != NULL) { + fclose(f1); + } + return ret; } /** |