GCC Code Coverage Report


Directory: ./
File: Os/SandboxedFile.cpp
Date: 2026-09-03 21:13:48
Exec Total Coverage
Lines: 48 60 80.0%
Functions: 13 18 72.2%
Branches: 16 21 76.2%

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