Skip to content

Commit 53cdce4

Browse files
committed
Enhance file shredder safety
Several safety checks have been added to optimize and improve the program's safety.
1 parent e7cda0c commit 53cdce4

File tree

1 file changed

+19
-9
lines changed

1 file changed

+19
-9
lines changed

src/fileShredder/shredFiles.cpp

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ constexpr std::streamoff BUFFER_SIZE = 4096;
3434
/// \param fileSize the size of the file in bytes.
3535
/// \param nPasses the number of passes to overwrite the file.
3636
void overwriteRandom(std::ofstream &file, const std::size_t fileSize, int nPasses = 1) {
37-
37+
if (!file.is_open()) throw std::runtime_error("File not open.");
3838
// Instantiate the random number generator
3939
std::random_device rd;
4040
std::uniform_int_distribution<unsigned char> dist(0, 255);
@@ -75,6 +75,7 @@ void overwriteRandom(std::ofstream &file, const std::size_t fileSize, int nPasse
7575
/// \param fileSize the size of the file in bytes.
7676
template<typename T>
7777
void overwriteConstantByte(std::ofstream &file, T &byte, const auto &fileSize) {
78+
if (!file.is_open()) throw std::runtime_error("File not open.");
7879
// seek to the beginning of the file
7980
file.seekp(0, std::ios::beg);
8081

@@ -85,6 +86,8 @@ void overwriteConstantByte(std::ofstream &file, T &byte, const auto &fileSize) {
8586
buffer.resize(fileSize - pos);
8687
}
8788
file.write(reinterpret_cast<char *>(buffer.data()), static_cast<std::streamsize>(buffer.size()));
89+
90+
if (!file) throw std::runtime_error("file write error.");
8891
}
8992
}
9093

@@ -168,9 +171,7 @@ struct FileDescriptor {
168171
throw std::runtime_error("Failed to open file: " + filename + " (" + std::strerror(errno) + ")");
169172
}
170173

171-
~FileDescriptor() {
172-
if (fd != -1) close(fd);
173-
}
174+
~FileDescriptor() { if (fd != -1) close(fd); }
174175
};
175176

176177
/// \struct FileStatInfo
@@ -210,6 +211,7 @@ inline void wipeClusterTips(const std::string &fileName) {
210211
// Write zeros to the cluster tip
211212
std::vector<char> zeroBuffer(clusterTipSize, 0);
212213
auto bytesWritten = write(fileDescriptor.fd, zeroBuffer.data(), zeroBuffer.size());
214+
213215
if (bytesWritten == static_cast<ssize_t>(-1)) {
214216
throw std::runtime_error(std::format("Failed to write zeros: ({})", std::strerror(errno)));
215217
}
@@ -263,7 +265,7 @@ void dod5220Shred(const std::string &filename, const int &nPasses = 3, bool wipe
263265
std::streamoff fileSize = file.tellp();
264266
file.seekp(0, std::ios::beg);
265267

266-
// The DoD 5220.22-M Standard algorithm (I'm avoiding recursion, hence the lambda)
268+
// The DoD 5220.22-M Standard algorithm
267269
auto dod3Pass = [&file, &fileSize] -> void {
268270
unsigned char zeroByte = 0x00;
269271
unsigned char oneByte = 0xFF;
@@ -357,15 +359,21 @@ bool shredFiles(const std::string &filePath, const unsigned int &options, const
357359
if (fs::is_empty(filePath, ec)) {
358360
if (ec) ec.clear();
359361
else {
360-
printColor("The path is an empty directory.", 'y', true);
362+
printColor(filePath, 'c');
363+
printColor(" is an empty directory.", 'y', true);
361364
return true;
362365
}
363366
}
364367
static std::size_t numShredded{0}, numNotShredded{0};
365368

366369
// Shred all files in the directory and all subdirectories
367370
for (const auto &entry: fs::recursive_directory_iterator(filePath)) {
368-
if (fs::exists(entry.status())) {
371+
if (entry.exists(ec)) {
372+
if (ec) {
373+
printColor(ec.message(), 'r', true, std::cerr);
374+
ec.clear();
375+
continue;
376+
}
369377
if (!fs::is_directory(entry.status())) {
370378
printColor("Shredding ", 'c');
371379
printColor(fs::canonical(entry.path()).string(), 'b');
@@ -377,14 +385,16 @@ bool shredFiles(const std::string &filePath, const unsigned int &options, const
377385

378386
++(shredded ? numShredded : numNotShredded);
379387

380-
} catch (std::runtime_error &err) {
388+
} catch (const std::runtime_error &err) {
381389
printColor("Shredding failed: ", 'y', false, std::cerr);
382390
printColor(err.what(), 'r', true, std::cerr);
383391
}
384392
}
385393
}
386394
}
387-
fs::remove_all(fs::canonical(filePath));
395+
if (numNotShredded == 0) // All files in the directory and all subdirectories were shredded successfully.
396+
fs::remove_all(fs::canonical(filePath));
397+
else printColor("Failed to shred some files.", 'r', true, std::cerr);
388398

389399
std::cout << "\nProcessed " << numShredded + numNotShredded << " files." << std::endl;
390400
if (numShredded) {

0 commit comments

Comments
 (0)