b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame] | 1 | From 424da221cec76ea200cff1fa9b08a6f3d94c28a7 Mon Sep 17 00:00:00 2001 |
| 2 | From: Lubomir Rintel <lkundrak@v3.sk> |
| 3 | Date: Wed, 31 Oct 2018 16:39:13 -0700 |
| 4 | Subject: [PATCH] Fix error handling with git-style patches |
| 5 | |
| 6 | When an error is encountered in output_files(), the subsequent call to |
| 7 | cleanup() calls back into output_files() resulting in an infinte recursion. |
| 8 | This is trivially reproduced with a git-style patch (which utilizes |
| 9 | output_file_later()) that tries to patch a nonexistent or unreadable |
| 10 | file (see attached test case). |
| 11 | |
| 12 | * src/patch.c: (output_files) clear the files_to_output list before |
| 13 | iterating it, so that recursive calls won't iterate the same files. |
| 14 | --- |
| 15 | src/patch.c | 12 ++++++++---- |
| 16 | 1 file changed, 8 insertions(+), 4 deletions(-) |
| 17 | |
| 18 | --- a/src/patch.c |
| 19 | +++ b/src/patch.c |
| 20 | @@ -1938,8 +1938,12 @@ output_files (struct stat const *st) |
| 21 | { |
| 22 | gl_list_iterator_t iter; |
| 23 | const void *elt; |
| 24 | + gl_list_t files; |
| 25 | |
| 26 | - iter = gl_list_iterator (files_to_output); |
| 27 | + files = files_to_output; |
| 28 | + init_files_to_output (); |
| 29 | + |
| 30 | + iter = gl_list_iterator (files); |
| 31 | while (gl_list_iterator_next (&iter, &elt, NULL)) |
| 32 | { |
| 33 | const struct file_to_output *file_to_output = elt; |
| 34 | @@ -1957,8 +1961,8 @@ output_files (struct stat const *st) |
| 35 | /* Free the list up to here. */ |
| 36 | for (;;) |
| 37 | { |
| 38 | - const void *elt2 = gl_list_get_at (files_to_output, 0); |
| 39 | - gl_list_remove_at (files_to_output, 0); |
| 40 | + const void *elt2 = gl_list_get_at (files, 0); |
| 41 | + gl_list_remove_at (files, 0); |
| 42 | if (elt == elt2) |
| 43 | break; |
| 44 | } |
| 45 | @@ -1967,7 +1971,7 @@ output_files (struct stat const *st) |
| 46 | } |
| 47 | } |
| 48 | gl_list_iterator_free (&iter); |
| 49 | - gl_list_clear (files_to_output); |
| 50 | + gl_list_clear (files); |
| 51 | } |
| 52 | |
| 53 | /* Fatal exit with cleanup. */ |