Close package fs review findings: readRange bounds, picker ext, non-ASCII tests

Cap readRange's allocation and reject size_t overflow instead of truncating;
re-append .rsbank when the export picker omits it; add cafe coverage for
writeFileExclusive and writeLandedFile; loop write() on EINTR.
This commit is contained in:
2026-08-02 08:44:29 -04:00
parent edfd7ead4d
commit 655159ceac
10 changed files with 97 additions and 17 deletions
+14 -1
View File
@@ -22,7 +22,7 @@ static int g_fail = 0;
// The journal records absolute paths, so every expectation is built the same way.
static std::string scratch(const std::string& name) {
return (fs::current_path() / utf8Path(name)).u8string();
return pathToUtf8(fs::current_path() / utf8Path(name));
}
static std::vector<std::uint8_t> patternBytes(std::size_t n, std::uint8_t seed) {
@@ -64,6 +64,18 @@ static void testLandRecordsOnSuccessOnly() {
CHECK(!exists(path)); // the recorded path denoted the file we asked for
}
static void testLandNonAsciiPathRoundTripsAsUtf8() {
// The fs::absolute -> u8string round trip at writeLandedFile is otherwise
// untested with a non-ASCII path.
LandedFileJournal journal;
const std::string path = scratch("rb_caf\xC3\xA9.bin");
const std::vector<std::uint8_t> bytes = patternBytes(16, 2);
CHECK(journal.writeLandedFile(path, PayloadBuffer(bytes)));
CHECK(readAll(path) == bytes);
journal.rollback();
CHECK(!exists(path));
}
static void testRelativeInputIsRecordedAbsolute() {
// The hazard: a bare name recorded verbatim, then a CWD change, and rollback
// unlinks whatever now sits at that name in the new directory.
@@ -169,6 +181,7 @@ static void testIndexCommitDisarmsRollback() {
int main() {
testLandRecordsOnSuccessOnly();
testLandNonAsciiPathRoundTripsAsUtf8();
testRelativeInputIsRecordedAbsolute();
testExistingDestinationRefusedUntouched();
testEmptyPayloadRefused();