diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-03-25 14:15:39 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-03-25 14:15:39 +0000 |
| commit | cc2965fd236a85e5cac4fffa1c34057997780385 (patch) | |
| tree | 39c5b7183cbc85130bd3f43ae25bd84898463c22 | |
| parent | 80591b0a000e88c284bd2ec355f27e19e1da7528 (diff) | |
| download | busybox-w32-cc2965fd236a85e5cac4fffa1c34057997780385.tar.gz busybox-w32-cc2965fd236a85e5cac4fffa1c34057997780385.tar.bz2 busybox-w32-cc2965fd236a85e5cac4fffa1c34057997780385.zip | |
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 7b391603d..2a2b130b9 100644 --- a/editors/patch.c +++ b/editors/patch.c | |||
| @@ -87,7 +87,7 @@ int patch_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
| 87 | while (patch_line) { | 87 | while (patch_line) { |
| 88 | FILE *src_stream; | 88 | FILE *src_stream; |
| 89 | FILE *dst_stream; | 89 | FILE *dst_stream; |
| 90 | char *original_filename; | 90 | //char *old_filename; |
| 91 | char *new_filename; | 91 | char *new_filename; |
| 92 | char *backup_filename; | 92 | char *backup_filename; |
| 93 | unsigned src_cur_line = 1; | 93 | unsigned src_cur_line = 1; |
| @@ -102,10 +102,12 @@ int patch_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
| 102 | */ | 102 | */ |
| 103 | do { | 103 | do { |
| 104 | /* Extract the filename used before the patch was generated */ | 104 | /* Extract the filename used before the patch was generated */ |
| 105 | original_filename = extract_filename(patch_line, patch_level, "--- "); | 105 | new_filename = extract_filename(patch_line, patch_level, "--- "); |
| 106 | // was old_filename above | ||
| 106 | patch_line = xmalloc_getline(patch_file); | 107 | patch_line = xmalloc_getline(patch_file); |
| 107 | if (!patch_line) goto quit; | 108 | if (!patch_line) goto quit; |
| 108 | } while (!original_filename); | 109 | } while (!new_filename); |
| 110 | free(new_filename); // "source" filename is irrelevant | ||
| 109 | 111 | ||
| 110 | new_filename = extract_filename(patch_line, patch_level, "+++ "); | 112 | new_filename = extract_filename(patch_line, patch_level, "+++ "); |
| 111 | if (!new_filename) { | 113 | if (!new_filename) { |
| @@ -122,25 +124,15 @@ int patch_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
| 122 | *slash = '/'; | 124 | *slash = '/'; |
| 123 | } | 125 | } |
| 124 | backup_filename = NULL; | 126 | backup_filename = NULL; |
| 127 | src_stream = NULL; | ||
| 125 | saved_stat.st_mode = 0644; | 128 | saved_stat.st_mode = 0644; |
| 126 | } else { | 129 | } else { |
| 127 | backup_filename = xasprintf("%s.orig", new_filename); | 130 | backup_filename = xasprintf("%s.orig", new_filename); |
| 128 | xrename(new_filename, backup_filename); | 131 | xrename(new_filename, backup_filename); |
| 132 | src_stream = xfopen(backup_filename, "r"); | ||
| 129 | } | 133 | } |
| 130 | dst_stream = xfopen(new_filename, "w"); | 134 | dst_stream = xfopen(new_filename, "w"); |
| 131 | fchmod(fileno(dst_stream), saved_stat.st_mode); | 135 | fchmod(fileno(dst_stream), saved_stat.st_mode); |
| 132 | src_stream = NULL; | ||
| 133 | if (backup_filename && stat(original_filename, &saved_stat) == 0) { | ||
| 134 | // strcmp() is never 0! Otherwise: | ||
| 135 | // original_filename == new_filename, | ||
| 136 | // stat(original_filename) == stat(new_filename), | ||
| 137 | // stat(new_filename) == 0, | ||
| 138 | // but we renamed new_filename if it existed! | ||
| 139 | // stat() must fail! | ||
| 140 | //src_stream = xfopen((strcmp(original_filename, new_filename)) ? | ||
| 141 | // original_filename : backup_filename, "r"); | ||
| 142 | src_stream = xfopen(original_filename, "r"); | ||
| 143 | } | ||
| 144 | 136 | ||
| 145 | printf("patching file %s\n", new_filename); | 137 | printf("patching file %s\n", new_filename); |
| 146 | 138 | ||
| @@ -224,15 +216,17 @@ int patch_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
| 224 | /* It worked, we can remove the backup */ | 216 | /* It worked, we can remove the backup */ |
| 225 | if (backup_filename) { | 217 | if (backup_filename) { |
| 226 | unlink(backup_filename); | 218 | unlink(backup_filename); |
| 227 | free(backup_filename); | ||
| 228 | } | 219 | } |
| 229 | if ((dest_cur_line == 0) || (dest_beg_line == 0)) { | 220 | if ((dest_cur_line == 0) || (dest_beg_line == 0)) { |
| 230 | /* The new patched file is empty, remove it */ | 221 | /* The new patched file is empty, remove it */ |
| 231 | xunlink(new_filename); | 222 | xunlink(new_filename); |
| 232 | /* original_filename and new_filename may be the same file */ | 223 | // /* old_filename and new_filename may be the same file */ |
| 233 | unlink(original_filename); | 224 | // unlink(old_filename); |
| 234 | } | 225 | } |
| 235 | } | 226 | } |
| 227 | free(backup_filename); | ||
| 228 | //free(old_filename); | ||
| 229 | free(new_filename); | ||
| 236 | } /* end of "while there are patch lines" */ | 230 | } /* end of "while there are patch lines" */ |
| 237 | quit: | 231 | quit: |
| 238 | 232 | ||
diff --git a/testsuite/patch.tests b/testsuite/patch.tests new file mode 100755 index 000000000..8a957d3f7 --- /dev/null +++ b/testsuite/patch.tests | |||
| @@ -0,0 +1,47 @@ | |||
| 1 | #!/bin/sh | ||
| 2 | # Copyright 2008 by Denys Vlasenko | ||
| 3 | # Licensed under GPL v2, see file LICENSE for details. | ||
| 4 | |||
| 5 | . testing.sh | ||
| 6 | |||
| 7 | # testing "test name" "options" "expected result" "file input" "stdin" | ||
| 8 | |||
| 9 | testing "patch with old_file == new_file" \ | ||
| 10 | "patch; echo $?; cat input" \ | ||
| 11 | "\ | ||
| 12 | patching file input | ||
| 13 | 0 | ||
| 14 | qwe | ||
| 15 | asd | ||
| 16 | zxc | ||
| 17 | " \ | ||
| 18 | "qwe\nzxc\n" \ | ||
| 19 | "\ | ||
| 20 | --- input Jan 01 01:01:01 2000 | ||
| 21 | +++ input Jan 01 01:01:01 2000 | ||
| 22 | @@ -1,2 +1,3 @@ | ||
| 23 | qwe | ||
| 24 | +asd | ||
| 25 | zxc | ||
| 26 | " \ | ||
| 27 | |||
| 28 | testing "patch with nonexistent old_file" \ | ||
| 29 | "strace -o zzz patch; echo $?; cat input" \ | ||
| 30 | "\ | ||
| 31 | patching file input | ||
| 32 | 0 | ||
| 33 | qwe | ||
| 34 | asd | ||
| 35 | zxc | ||
| 36 | " \ | ||
| 37 | "qwe\nzxc\n" \ | ||
| 38 | "\ | ||
| 39 | --- input.doesnt_exist Jan 01 01:01:01 2000 | ||
| 40 | +++ input Jan 01 01:01:01 2000 | ||
| 41 | @@ -1,2 +1,3 @@ | ||
| 42 | qwe | ||
| 43 | +asd | ||
| 44 | zxc | ||
| 45 | " \ | ||
| 46 | |||
| 47 | exit $FAILCOUNT | ||
