GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/sanitizer.cc
Date: 2025-04-20 02:34:28
Exec Total Coverage
Lines: 69 71 97.2%
Branches: 40 49 81.6%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 *
4 * Provides input data sanitizer in the form of whitelist of character ranges.
5 */
6
7
8 #include "sanitizer.h"
9
10 #include <cassert>
11
12 using namespace std; // NOLINT
13
14 #ifdef CVMFS_NAMESPACE_GUARD
15 namespace CVMFS_NAMESPACE_GUARD {
16 #endif
17
18 namespace sanitizer {
19
20 1351 CharRange::CharRange(const char range_begin, const char range_end) {
21 1351 range_begin_ = range_begin;
22 1351 range_end_ = range_end;
23 1351 }
24
25
26 1223 CharRange::CharRange(const char single_char) {
27 1223 range_begin_ = range_end_ = single_char;
28 1223 }
29
30
31 15849 bool CharRange::InRange(const char c) const {
32
4/4
✓ Branch 0 taken 12860 times.
✓ Branch 1 taken 2989 times.
✓ Branch 2 taken 9165 times.
✓ Branch 3 taken 3695 times.
15849 return (c >= range_begin_) && (c <= range_end_);
33 }
34
35
36 //------------------------------------------------------------------------------
37
38
39 1209 InputSanitizer::InputSanitizer(const string &whitelist) : max_length_(-1) {
40
1/2
✓ Branch 1 taken 1209 times.
✗ Branch 2 not taken.
1209 InitValidRanges(whitelist);
41 1209 }
42
43
44 5 InputSanitizer::InputSanitizer(const string &whitelist, int max_length)
45 5 : max_length_(max_length)
46 {
47
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 InitValidRanges(whitelist);
48 5 }
49
50
51 1214 void InputSanitizer::InitValidRanges(const std::string &whitelist) {
52 // Parse the whitelist
53 1214 const unsigned length = whitelist.length();
54 1214 unsigned pickup_pos = 0;
55
2/2
✓ Branch 0 taken 3925 times.
✓ Branch 1 taken 1214 times.
5139 for (unsigned i = 0; i < length; ++i) {
56
7/8
✓ Branch 0 taken 2712 times.
✓ Branch 1 taken 1213 times.
✓ Branch 3 taken 1351 times.
✓ Branch 4 taken 1361 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1351 times.
✓ Branch 7 taken 2574 times.
✓ Branch 8 taken 1351 times.
3925 if ((i+1 >= length) || (whitelist[i+1] == ' ') || (i == length-1)) {
57
1/2
✓ Branch 1 taken 2574 times.
✗ Branch 2 not taken.
2574 const string range = whitelist.substr(pickup_pos, i-pickup_pos+1);
58
2/3
✓ Branch 1 taken 1223 times.
✓ Branch 2 taken 1351 times.
✗ Branch 3 not taken.
2574 switch (range.length()) {
59 1223 case 1:
60
1/2
✓ Branch 3 taken 1223 times.
✗ Branch 4 not taken.
1223 valid_ranges_.push_back(CharRange(range[0]));
61 1223 break;
62 1351 case 2:
63
1/2
✓ Branch 4 taken 1351 times.
✗ Branch 5 not taken.
1351 valid_ranges_.push_back(CharRange(range[0], range[1]));
64 1351 break;
65 default:
66 assert(false);
67 }
68 2574 ++i;
69 2574 pickup_pos = i+1;
70 2574 }
71 }
72 1214 }
73
74
75 1273 bool InputSanitizer::Sanitize(
76 std::string::const_iterator begin,
77 std::string::const_iterator end,
78 std::string *filtered_output) const {
79 1273 int pos = 0;
80 1273 bool is_sane = true;
81
2/2
✓ Branch 2 taken 10926 times.
✓ Branch 3 taken 1269 times.
12195 for (; begin != end; ++begin) {
82
2/2
✓ Branch 2 taken 9165 times.
✓ Branch 3 taken 1761 times.
10926 if (CheckRanges(*begin)) {
83
4/4
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 9116 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 45 times.
9165 if ((max_length_ >= 0) && (pos >= max_length_)) {
84 4 is_sane = false;
85 4 break;
86 }
87 9161 filtered_output->push_back(*begin);
88 9161 pos++;
89 } else {
90 1761 is_sane = false;
91 }
92 }
93 1273 return is_sane;
94 }
95
96
97 10926 bool InputSanitizer::CheckRanges(const char chr) const {
98
2/2
✓ Branch 1 taken 15849 times.
✓ Branch 2 taken 1761 times.
17610 for (unsigned j = 0; j < valid_ranges_.size(); ++j) {
99
2/2
✓ Branch 2 taken 9165 times.
✓ Branch 3 taken 6684 times.
15849 if (valid_ranges_[j].InRange(chr)) {
100 9165 return true;
101 }
102 }
103 1761 return false;
104 }
105
106
107 24 string InputSanitizer::Filter(const std::string &input) const {
108 24 string filtered_output;
109
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 Sanitize(input, &filtered_output);
110 24 return filtered_output;
111 }
112
113
114 1251 bool InputSanitizer::IsValid(const std::string &input) const {
115 1251 string dummy;
116
1/2
✓ Branch 1 taken 1251 times.
✗ Branch 2 not taken.
2502 return Sanitize(input, &dummy);
117 1251 }
118
119
120 34 bool IntegerSanitizer::Sanitize(
121 std::string::const_iterator begin,
122 std::string::const_iterator end,
123 std::string *filtered_output) const {
124
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 33 times.
34 if (std::distance(begin, end) == 0) {
125 1 return false;
126 }
127
128
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 31 times.
33 if (*begin == '-') {
129 // minus is allowed as the first character!
130 2 filtered_output->push_back('-');
131 2 begin++;
132 }
133
134 33 return InputSanitizer::Sanitize(begin, end, filtered_output);
135 }
136
137
138 10 bool PositiveIntegerSanitizer::Sanitize(
139 std::string::const_iterator begin,
140 std::string::const_iterator end,
141 std::string *filtered_output) const {
142
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 9 times.
10 if (std::distance(begin, end) == 0) {
143 1 return false;
144 }
145
146 9 return InputSanitizer::Sanitize(begin, end, filtered_output);
147 }
148
149 } // namespace sanitizer
150
151 #ifdef CVMFS_NAMESPACE_GUARD
152 } // namespace CVMFS_NAMESPACE_GUARD
153 #endif
154