GCC Code Coverage Report


Directory: ./
File: Os/SandboxedFile.cpp
Date: 2026-11-03 21:15:54
Exec Total Coverage
Lines: 48 54 88.9%
Functions: 15 18 83.3%
Branches: 16 18 88.9%

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 7 taken 86 times.
86 SandboxedFile::SandboxedFile() : m_file(), m_allowedDirectory(""), m_configured(false) {}
13
14 172 SandboxedFile::~SandboxedFile() {
15
2/2
✓ Branch 5 taken 45 times.
✓ Branch 6 taken 41 times.
86 if (m_file.isOpen()) {
16 45 m_file.close();
17 }
18 172 }
19
20 80 void SandboxedFile::configure(const char* allowedDirectory) {
21 80 FW_ASSERT(allowedDirectory != nullptr);
22 80 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 80 char resolved[FilePathUtils::MAX_PATH_LENGTH];
27 const FilePathUtils::Status resolveStatus =
28
1/1
✓ Branch 1 taken 80 times.
80 FilePathUtils::resolveDirectoryFromCwd(allowedDirectory, resolved, sizeof(resolved));
29 80 FW_ASSERT(resolveStatus == FilePathUtils::VALID, static_cast<FwAssertArgType>(resolveStatus));
30
31
1/1
✓ Branch 6 taken 80 times.
80 m_allowedDirectory = resolved;
32 80 m_configured = true;
33 80 }
34
35 2 bool SandboxedFile::isConfigured() const {
36
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 return m_configured;
37 }
38
39 83 Os::FileInterface::Status SandboxedFile::open(const char* path,
40 Os::FileInterface::Mode mode,
41 Os::FileInterface::OverwriteType overwrite) {
42 83 FW_ASSERT(path != nullptr);
43
44
3/4
✗ Branch 1 not taken.
✓ Branch 2 taken 83 times.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 78 times.
83 if (!m_configured) {
45 5 return Os::FileInterface::Status::OUTSIDE_SANDBOX;
46 }
47
48 // Resolve path against CWD then check containment
49 78 char resolvedPath[FilePathUtils::MAX_PATH_LENGTH];
50
1/1
✓ Branch 1 taken 78 times.
78 const FilePathUtils::Status resolveStatus = FilePathUtils::resolveFromCwd(path, resolvedPath, sizeof(resolvedPath));
51
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 76 times.
78 if (resolveStatus != FilePathUtils::VALID) {
52 2 return Os::FileInterface::Status::OUTSIDE_SANDBOX;
53 }
54
55
3/3
✓ Branch 7 taken 76 times.
✓ Branch 9 taken 5 times.
✓ Branch 10 taken 71 times.
76 if (FilePathUtils::checkContainment(resolvedPath, m_allowedDirectory.toChar()) != FilePathUtils::VALID) {
56 5 return Os::FileInterface::Status::OUTSIDE_SANDBOX;
57 }
58
59
1/1
✓ Branch 5 taken 71 times.
71 return m_file.open(resolvedPath, mode, overwrite);
60 }
61
62 29 void SandboxedFile::close() {
63 29 m_file.close();
64 29 }
65
66 8 bool SandboxedFile::isOpen() const {
67 8 return m_file.isOpen();
68 }
69
70 6 Os::FileInterface::Status SandboxedFile::size(FwSizeType& size_result) {
71 6 return m_file.size(size_result);
72 }
73
74 7 Os::FileInterface::Status SandboxedFile::position(FwSizeType& position_result) {
75 7 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 44 Os::FileInterface::Status SandboxedFile::seek(FwSignedSizeType offset, Os::FileInterface::SeekType seekType) {
83 44 return m_file.seek(offset, seekType);
84 }
85
86 ✗ Os::FileInterface::Status SandboxedFile::flush() {
87 ✗ return m_file.flush();
88 }
89
90 56 Os::FileInterface::Status SandboxedFile::read(U8* buffer, FwSizeType& size, Os::FileInterface::WaitType wait) {
91 56 return m_file.read(buffer, size, wait);
92 }
93
94 38 Os::FileInterface::Status SandboxedFile::read(U8* buffer, FwSizeType& size) {
95 38 return m_file.read(buffer, size);
96 }
97
98 122 Os::FileInterface::Status SandboxedFile::write(const U8* buffer, FwSizeType& size, Os::FileInterface::WaitType wait) {
99 122 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 21 Os::FileInterface::Status SandboxedFile::calculateCrc(U32& crc) {
107 21 return m_file.calculateCrc(crc);
108 }
109
110 2 const char* SandboxedFile::getSandboxDirectory() const {
111 2 return m_allowedDirectory.toChar();
112 }
113
114 } // namespace Os
115