diff options
author | Denis Vlasenko | 2008-03-25 14:15:39 +0000 |
---|---|---|
committer | Denis Vlasenko | 2008-03-25 14:15:39 +0000 |
commit | cc2965fd236a85e5cac4fffa1c34057997780385 (patch) | |
tree | 39c5b7183cbc85130bd3f43ae25bd84898463c22 | |
parent | 80591b0a000e88c284bd2ec355f27e19e1da7528 (diff) | |
download | busybox-cc2965fd236a85e5cac4fffa1c34057997780385.zip busybox-cc2965fd236a85e5cac4fffa1c34057997780385.tar.gz |
patch: fix vda's thinko: we need to open new_filename.orig, always!
plug memory leak; add testsuite
patch_main 1009 988 -21
-rw-r--r-- | editors/patch.c | 30 | ||||
-rwxr-xr-x | testsuite/patch.tests | 47 |
2 files changed, 59 insertions, 18 deletions
diff --git a/editors/patch.c b/editors/patch.c index 7b39160..2a2b130 100644 --- a/editors/patch.c +++ b/editors/patch.c @@ -87,7 +87,7 @@ int patch_main(int argc ATTRIBUTE_UNUSED, char **argv) while (patch_line) { FILE *src_stream; FILE *dst_stream; - char *original_filename; + //char *old_filename; char *new_filename; char *backup_filename; unsigned src_cur_line = 1; @@ -102,10 +102,12 @@ int patch_main(int argc ATTRIBUTE_UNUSED, char **argv) */ do { /* Extract the filename used before the patch was generated */ - original_filename = extract_filename(patch_line, patch_level, "--- "); + new_filename = extract_filename(patch_line, patch_level, "--- "); + // was old_filename above patch_line = xmalloc_getline(patch_file); if (!patch_line) goto quit; - } while (!original_filename); + } while (!new_filename); + free(new_filename); // "source" filename is irrelevant new_filename = extract_filename(patch_line, patch_level, "+++ "); if (!new_filename) { @@ -122,25 +124,15 @@ int patch_main(int argc ATTRIBUTE_UNUSED, char **argv) *slash = '/'; } backup_filename = NULL; + src_stream = NULL; saved_stat.st_mode = 0644; } else { backup_filename = xasprintf("%s.orig", new_filename); xrename(new_filename, backup_filename); + src_stream = xfopen(backup_filename, "r"); } dst_stream = xfopen(new_filename, "w"); fchmod(fileno(dst_stream), saved_stat.st_mode); - src_stream = NULL; - if (backup_filename && stat(original_filename, &saved_stat) == 0) { - // strcmp() is never 0! Otherwise: - // original_filename == new_filename, - // stat(original_filename) == stat(new_filename), - // stat(new_filename) == 0, - // but we renamed new_filename if it existed! - // stat() must fail! - //src_stream = xfopen((strcmp(original_filename, new_filename)) ? - // original_filename : backup_filename, "r"); - src_stream = xfopen(original_filename, "r"); - } printf("patching file %s\n", new_filename); @@ -224,15 +216,17 @@ int patch_main(int argc ATTRIBUTE_UNUSED, char **argv) /* It worked, we can remove the backup */ if (backup_filename) { unlink(backup_filename); - free(backup_filename); } if ((dest_cur_line == 0) || (dest_beg_line == 0)) { /* The new patched file is empty, remove it */ xunlink(new_filename); - /* original_filename and new_filename may be the same file */ - unlink(original_filename); + // /* old_filename and new_filename may be the same file */ + // unlink(old_filename); } } + free(backup_filename); + //free(old_filename); + free(new_filename); } /* end of "while there are patch lines" */ quit: diff --git a/testsuite/patch.tests b/testsuite/patch.tests new file mode 100755 index 0000000..8a957d3 --- /dev/null +++ b/testsuite/patch.tests @@ -0,0 +1,47 @@ +#!/bin/sh +# Copyright 2008 by Denys Vlasenko +# Licensed under GPL v2, see file LICENSE for details. + +. testing.sh + +# testing "test name" "options" "expected result" "file input" "stdin" + +testing "patch with old_file == new_file" \ + "patch; echo $?; cat input" \ +"\ +patching file input +0 +qwe +asd +zxc +" \ + "qwe\nzxc\n" \ +"\ +--- input Jan 01 01:01:01 2000 ++++ input Jan 01 01:01:01 2000 +@@ -1,2 +1,3 @@ + qwe ++asd + zxc +" \ + +testing "patch with nonexistent old_file" \ + "strace -o zzz patch; echo $?; cat input" \ +"\ +patching file input +0 +qwe +asd +zxc +" \ + "qwe\nzxc\n" \ +"\ +--- input.doesnt_exist Jan 01 01:01:01 2000 ++++ input Jan 01 01:01:01 2000 +@@ -1,2 +1,3 @@ + qwe ++asd + zxc +" \ + +exit $FAILCOUNT |