GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/sanitizer.cc
Date: 2025-05-11 02:35:43
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 1207 CharRange::CharRange(const char range_begin, const char range_end) {
21 1207 range_begin_ = range_begin;
22 1207 range_end_ = range_end;
23 1207 }
24
25
26 1079 CharRange::CharRange(const char single_char) {
27 1079 range_begin_ = range_end_ = single_char;
28 1079 }
29
30
31 13977 bool CharRange::InRange(const char c) const {
32
4/4
✓ Branch 0 taken 11420 times.
✓ Branch 1 taken 2557 times.
✓ Branch 2 taken 7725 times.
✓ Branch 3 taken 3695 times.
13977 return (c >= range_begin_) && (c <= range_end_);
33 }
34
35
36 //------------------------------------------------------------------------------
37
38
39 1065 InputSanitizer::InputSanitizer(const string &whitelist) : max_length_(-1) {
40
1/2
✓ Branch 1 taken 1065 times.
✗ Branch 2 not taken.
1065 InitValidRanges(whitelist);
41 1065 }
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 1070 void InputSanitizer::InitValidRanges(const std::string &whitelist) {
52 // Parse the whitelist
53 1070 const unsigned length = whitelist.length();
54 1070 unsigned pickup_pos = 0;
55
2/2
✓ Branch 0 taken 3493 times.
✓ Branch 1 taken 1070 times.
4563 for (unsigned i = 0; i < length; ++i) {
56
7/8
✓ Branch 0 taken 2424 times.
✓ Branch 1 taken 1069 times.
✓ Branch 3 taken 1207 times.
✓ Branch 4 taken 1217 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1207 times.
✓ Branch 7 taken 2286 times.
✓ Branch 8 taken 1207 times.
3493 if ((i+1 >= length) || (whitelist[i+1] == ' ') || (i == length-1)) {
57
1/2
✓ Branch 1 taken 2286 times.
✗ Branch 2 not taken.
2286 const string range = whitelist.substr(pickup_pos, i-pickup_pos+1);
58
2/3
✓ Branch 1 taken 1079 times.
✓ Branch 2 taken 1207 times.
✗ Branch 3 not taken.
2286 switch (range.length()) {
59 1079 case 1:
60
1/2
✓ Branch 3 taken 1079 times.
✗ Branch 4 not taken.
1079 valid_ranges_.push_back(CharRange(range[0]));
61 1079 break;
62 1207 case 2:
63
1/2
✓ Branch 4 taken 1207 times.
✗ Branch 5 not taken.
1207 valid_ranges_.push_back(CharRange(range[0], range[1]));
64 1207 break;
65 default:
66 assert(false);
67 }
68 2286 ++i;
69 2286 pickup_pos = i+1;
70 2286 }
71 }
72 1070 }
73
74
75 1129 bool InputSanitizer::Sanitize(
76 std::string::const_iterator begin,
77 std::string::const_iterator end,
78 std::string *filtered_output) const {
79 1129 int pos = 0;
80 1129 bool is_sane = true;
81
2/2
✓ Branch 2 taken 9486 times.
✓ Branch 3 taken 1125 times.
10611 for (; begin != end; ++begin) {
82
2/2
✓ Branch 2 taken 7725 times.
✓ Branch 3 taken 1761 times.
9486 if (CheckRanges(*begin)) {
83
4/4
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 7676 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 45 times.
7725 if ((max_length_ >= 0) && (pos >= max_length_)) {
84 4 is_sane = false;
85 4 break;
86 }
87 7721 filtered_output->push_back(*begin);
88 7721 pos++;
89 } else {
90 1761 is_sane = false;
91 }
92 }
93 1129 return is_sane;
94 }
95
96
97 9486 bool InputSanitizer::CheckRanges(const char chr) const {
98
2/2
✓ Branch 1 taken 13977 times.
✓ Branch 2 taken 1761 times.
15738 for (unsigned j = 0; j < valid_ranges_.size(); ++j) {
99
2/2
✓ Branch 2 taken 7725 times.
✓ Branch 3 taken 6252 times.
13977 if (valid_ranges_[j].InRange(chr)) {
100 7725 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 1107 bool InputSanitizer::IsValid(const std::string &input) const {
115 1107 string dummy;
116
1/2
✓ Branch 1 taken 1107 times.
✗ Branch 2 not taken.
2214 return Sanitize(input, &dummy);
117 1107 }
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