forked from pool/patch
60 lines
2.2 KiB
Diff
60 lines
2.2 KiB
Diff
|
From: Takashi Iwai <tiwai@suse.de>
|
||
|
Date: Wed, 6 Apr 2022 10:48:35 +0200
|
||
|
Subject: Pass the correct stat to backup files
|
||
|
Patch-mainline: Yes
|
||
|
Git-commit: c835ecc67b7e37c0d0b7dd7e032209fdaa285808
|
||
|
References: boo#1198106 savananh#62364
|
||
|
|
||
|
The last case to call output_file() in the main loop is
|
||
|
output_file (outname, NULL, &tmpoutst, NULL, NULL,
|
||
|
file_type | 0, backup);
|
||
|
and this essentially means to create a backup file (where to=NULL)
|
||
|
only if backup=true, and does nothing else.
|
||
|
|
||
|
And, in the current code, the passed file stat (&tmpoutst) is a file
|
||
|
stat of the temporary file that has been processed, not the original
|
||
|
file (outname) to be backed up. When the backup is performed
|
||
|
immediately, this is no big problem. However, output_file() may
|
||
|
schedule the deferred handling, and the given file may be backed up at
|
||
|
a later point. The problem is that create_backup() tries to avoid the
|
||
|
backup of the same file twice, and it checks the given stat i-node
|
||
|
number in the hash list. Since it's a stat of a temporary file, the
|
||
|
same i-node number may be reused once a temp file is deleted and
|
||
|
another is created. This results in a false-positive detection of the
|
||
|
already existing file, eventually missing a backup file.
|
||
|
|
||
|
This patch attempts to address the issue:
|
||
|
- Modify the condition for better understanding, clearly indicating
|
||
|
that the code there is for creating a backup file
|
||
|
- Pass the stat of the original file instead of a temporary file
|
||
|
|
||
|
BugLink: https://bugzilla.opensuse.org/show_bug.cgi?id=1198106
|
||
|
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||
|
Signed-off-by: Jean Delvare <jdelvare@suse.de>
|
||
|
---
|
||
|
src/patch.c | 13 ++++++++++---
|
||
|
1 file changed, 10 insertions(+), 3 deletions(-)
|
||
|
|
||
|
--- a/src/patch.c
|
||
|
+++ b/src/patch.c
|
||
|
@@ -611,9 +611,16 @@ main (int argc, char **argv)
|
||
|
output_file (NULL, NULL, NULL, inname, &instat,
|
||
|
mode, backup);
|
||
|
}
|
||
|
- else
|
||
|
- output_file (outname, NULL, &tmpoutst, NULL, NULL,
|
||
|
- file_type | 0, backup);
|
||
|
+ else if (backup)
|
||
|
+ {
|
||
|
+ struct stat outstat;
|
||
|
+
|
||
|
+ if (stat_file (outname, &outstat) != 0)
|
||
|
+ say ("Cannot stat file %s, skipping backup\n", outname);
|
||
|
+ else
|
||
|
+ output_file (outname, NULL, &outstat, NULL, NULL,
|
||
|
+ file_type | 0, true);
|
||
|
+ }
|
||
|
}
|
||
|
}
|
||
|
}
|