diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 7698d7b5..4fbe9ebb 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -3283,6 +3283,7 @@ Matthias Senzel for the "jumpingseconds" patch for reporting a bug in drawing very long menu titles in the LCARS skin for reporting and helping to debug a crash when stopping VDR + for reporting a crash when moving a recording between different volumes Marek Nazarko for translating OSD texts to the Polish language diff --git a/HISTORY b/HISTORY index 4dade437..b266a627 100644 --- a/HISTORY +++ b/HISTORY @@ -9162,7 +9162,7 @@ Video Disk Recorder Revision History a subdirectory. - SVDRP peering can now be limited to the default SVDRP host (see MANUAL for details). -2017-11-26: Version 2.3.9 +2017-11-27: Version 2.3.9 - Updated the Italian OSD texts (thanks to Diego Pierotto). - Updated the Finnish OSD texts (thanks to Rolf Ahrenberg). @@ -9208,3 +9208,5 @@ Video Disk Recorder Revision History - Now calling Hide() and cStatus::MsgReplaying(..., false) from cReplayControl::Stop(), to inform plugins about an ending replay session before the replay control gets destroyed. +- Fixed a possible crash when moving a recording between different volumes (reported by + Matthias Senzel). diff --git a/recording.c b/recording.c index ca0ec798..e2d6e7c5 100644 --- a/recording.c +++ b/recording.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: recording.c 4.10 2017/06/25 12:31:46 kls Exp $ + * $Id: recording.c 4.11 2017/11/27 13:58:34 kls Exp $ */ #include "recording.h" @@ -1725,6 +1725,7 @@ void cDirCopier::Action(void) int From = -1; int To = -1; size_t BufferSize = BUFSIZ; + uchar *Buffer = NULL; while (Running()) { // Suspend copying if we have severe throughput problems: if (Throttled()) { @@ -1734,8 +1735,11 @@ void cDirCopier::Action(void) // Copy all files in the source directory to the destination directory: if (e) { // We're currently copying a file: - uchar Buffer[BufferSize]; - size_t Read = safe_read(From, Buffer, sizeof(Buffer)); + if (!Buffer) { + esyslog("ERROR: no buffer"); + break; + } + size_t Read = safe_read(From, Buffer, BufferSize); if (Read > 0) { size_t Written = safe_write(To, Buffer, Read); if (Written != Read) { @@ -1784,7 +1788,14 @@ void cDirCopier::Action(void) break; } dsyslog("copying file '%s' to '%s'", *FileNameSrc, *FileNameDst); - BufferSize = max(size_t(st.st_blksize * 10), size_t(BUFSIZ)); + if (!Buffer) { + BufferSize = max(size_t(st.st_blksize * 10), size_t(BUFSIZ)); + Buffer = MALLOC(uchar, BufferSize); + if (!Buffer) { + esyslog("ERROR: out of memory"); + break; + } + } if (access(FileNameDst, F_OK) == 0) { esyslog("ERROR: destination file '%s' already exists", *FileNameDst); break; @@ -1801,11 +1812,13 @@ void cDirCopier::Action(void) } else { // We're done: + free(Buffer); dsyslog("done copying directory '%s' to '%s'", *dirNameSrc, *dirNameDst); error = false; return; } } + free(Buffer); close(From); // just to be absolutely sure close(To); esyslog("ERROR: copying directory '%s' to '%s' ended prematurely", *dirNameSrc, *dirNameDst);