GCC Code Coverage Report


Directory: ./
File: SandboxedFile.cpp
Date: 2026-11-03 22:11:01
Exec Total Coverage
Lines: 38 52 73.1%
Functions: 12 18 66.7%
Branches: 12 14 85.7%

Line Branch Exec Source
1 // ======================================================================
2 // \title Os/SandboxedFile.cpp
3 // \brief Implementation of directory-sandboxed file wrapper
4 // ======================================================================
5 #include <Fw/Types/Assert.hpp>
6 #include <Os/SandboxedFile.hpp>
7 #include <cstring>
8
9 namespace Os {
10
11 // Fail-closed: open() returns OUTSIDE_SANDBOX until configure() is called
12
1/1
✓ Branch 2 taken 6 times.
6 SandboxedFile::SandboxedFile() : m_file(), m_allowedDirectory(""), m_configured(false) {}
13
14 6 SandboxedFile::~SandboxedFile() {
15
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 4 times.
6 if (m_file.isOpen()) {
16 2 m_file.close();
17 }
18 6 }
19
20 8 void SandboxedFile::configure(const char* allowedDirectory) {
21 8 FW_ASSERT(allowedDirectory != nullptr);
22 8 FW_ASSERT(!m_file.isOpen());
23
24 // Resolve the allowed directory (relative paths resolve against CWD) into the
25 // canonical trailing-'/' form that checkContainment requires
26 char resolved[FilePathUtils::MAX_PATH_LENGTH];
27 const FilePathUtils::Status resolveStatus =
28
1/1
✓ Branch 1 taken 8 times.
8 FilePathUtils::resolveDirectoryFromCwd(allowedDirectory, resolved, sizeof(resolved));
29 8 FW_ASSERT(resolveStatus == FilePathUtils::VALID, static_cast<FwAssertArgType>(resolveStatus));
30
31
1/1
✓ Branch 1 taken 8 times.
8 m_allowedDirectory = resolved;
32 8 m_configured = true;
33 8 }
34
35 ✗ bool SandboxedFile::isConfigured() const {
36 ✗ return m_configured;
37 }
38
39 11 Os::FileInterface::Status SandboxedFile::open(const char* path,
40 Os::FileInterface::Mode mode,
41 Os::FileInterface::OverwriteType overwrite) {
42 11 FW_ASSERT(path != nullptr);
43
44
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if (!m_configured) {
45 ✗ return Os::FileInterface::Status::OUTSIDE_SANDBOX;
46 }
47
48 // Resolve path against CWD then check containment
49 char resolvedPath[FilePathUtils::MAX_PATH_LENGTH];
50
1/1
✓ Branch 1 taken 11 times.
11 const FilePathUtils::Status resolveStatus = FilePathUtils::resolveFromCwd(path, resolvedPath, sizeof(resolvedPath));
51
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if (resolveStatus != FilePathUtils::VALID) {
52 ✗ return Os::FileInterface::Status::OUTSIDE_SANDBOX;
53 }
54
55
3/3
✓ Branch 2 taken 11 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 9 times.
11 if (FilePathUtils::checkContainment(resolvedPath, m_allowedDirectory.toChar()) != FilePathUtils::VALID) {
56 2 return Os::FileInterface::Status::OUTSIDE_SANDBOX;
57 }
58
59
1/1
✓ Branch 1 taken 9 times.
9 return m_file.open(resolvedPath, mode, overwrite);
60 }
61
62 8 void SandboxedFile::close() {
63 8 m_file.close();
64 8 }
65
66 ✗ bool SandboxedFile::isOpen() const {
67 ✗ return m_file.isOpen();
68 }
69
70 5 Os::FileInterface::Status SandboxedFile::size(FwSizeType& size_result) {
71 5 return m_file.size(size_result);
72 }
73
74 1 Os::FileInterface::Status SandboxedFile::position(FwSizeType& position_result) {
75 1 return m_file.position(position_result);
76 }
77
78 ✗ Os::FileInterface::Status SandboxedFile::preallocate(FwSizeType offset, FwSizeType length) {
79 ✗ return m_file.preallocate(offset, length);
80 }
81
82 24 Os::FileInterface::Status SandboxedFile::seek(FwSignedSizeType offset, Os::FileInterface::SeekType seekType) {
83 24 return m_file.seek(offset, seekType);
84 }
85
86 ✗ Os::FileInterface::Status SandboxedFile::flush() {
87 ✗ return m_file.flush();
88 }
89
90 1 Os::FileInterface::Status SandboxedFile::read(U8* buffer, FwSizeType& size, Os::FileInterface::WaitType wait) {
91 1 return m_file.read(buffer, size, wait);
92 }
93
94 21 Os::FileInterface::Status SandboxedFile::read(U8* buffer, FwSizeType& size) {
95 21 return m_file.read(buffer, size);
96 }
97
98 3 Os::FileInterface::Status SandboxedFile::write(const U8* buffer, FwSizeType& size, Os::FileInterface::WaitType wait) {
99 3 return m_file.write(buffer, size, wait);
100 }
101
102 ✗ Os::FileInterface::Status SandboxedFile::write(const U8* buffer, FwSizeType& size) {
103 ✗ return m_file.write(buffer, size);
104 }
105
106 1 Os::FileInterface::Status SandboxedFile::calculateCrc(U32& crc) {
107 1 return m_file.calculateCrc(crc);
108 }
109
110 ✗ const char* SandboxedFile::getSandboxDirectory() const {
111 ✗ return m_allowedDirectory.toChar();
112 }
113
114 } // namespace Os
115