GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/sanitizer.cc
Date: 2024-04-21 02:33:16
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 #include "cvmfs_config.h"
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 1135 CharRange::CharRange(const char range_begin, const char range_end) {
21 1135 range_begin_ = range_begin;
22 1135 range_end_ = range_end;
23 1135 }
24
25
26 1007 CharRange::CharRange(const char single_char) {
27 1007 range_begin_ = range_end_ = single_char;
28 1007 }
29
30
31 12681 bool CharRange::InRange(const char c) const {
32
4/4
✓ Branch 0 taken 10988 times.
✓ Branch 1 taken 1693 times.
✓ Branch 2 taken 5277 times.
✓ Branch 3 taken 5711 times.
12681 return (c >= range_begin_) && (c <= range_end_);
33 }
34
35
36 //------------------------------------------------------------------------------
37
38
39 993 InputSanitizer::InputSanitizer(const string &whitelist) : max_length_(-1) {
40
1/2
✓ Branch 1 taken 993 times.
✗ Branch 2 not taken.
993 InitValidRanges(whitelist);
41 993 }
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 998 void InputSanitizer::InitValidRanges(const std::string &whitelist) {
52 // Parse the whitelist
53 998 const unsigned length = whitelist.length();
54 998 unsigned pickup_pos = 0;
55
2/2
✓ Branch 0 taken 3277 times.
✓ Branch 1 taken 998 times.
4275 for (unsigned i = 0; i < length; ++i) {
56
7/8
✓ Branch 0 taken 2280 times.
✓ Branch 1 taken 997 times.
✓ Branch 3 taken 1135 times.
✓ Branch 4 taken 1145 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1135 times.
✓ Branch 7 taken 2142 times.
✓ Branch 8 taken 1135 times.
3277 if ((i+1 >= length) || (whitelist[i+1] == ' ') || (i == length-1)) {
57
1/2
✓ Branch 1 taken 2142 times.
✗ Branch 2 not taken.
2142 const string range = whitelist.substr(pickup_pos, i-pickup_pos+1);
58
2/3
✓ Branch 1 taken 1007 times.
✓ Branch 2 taken 1135 times.
✗ Branch 3 not taken.
2142 switch (range.length()) {
59 1007 case 1:
60
1/2
✓ Branch 3 taken 1007 times.
✗ Branch 4 not taken.
1007 valid_ranges_.push_back(CharRange(range[0]));
61 1007 break;
62 1135 case 2:
63
1/2
✓ Branch 4 taken 1135 times.
✗ Branch 5 not taken.
1135 valid_ranges_.push_back(CharRange(range[0], range[1]));
64 1135 break;
65 default:
66 assert(false);
67 }
68 2142 ++i;
69 2142 pickup_pos = i+1;
70 2142 }
71 }
72 998 }
73
74
75 1057 bool InputSanitizer::Sanitize(
76 std::string::const_iterator begin,
77 std::string::const_iterator end,
78 std::string *filtered_output) const {
79 1057 int pos = 0;
80 1057 bool is_sane = true;
81
2/2
✓ Branch 2 taken 8046 times.
✓ Branch 3 taken 1053 times.
9099 for (; begin != end; ++begin) {
82
2/2
✓ Branch 2 taken 5277 times.
✓ Branch 3 taken 2769 times.
8046 if (CheckRanges(*begin)) {
83
4/4
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 5228 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 45 times.
5277 if ((max_length_ >= 0) && (pos >= max_length_)) {
84 4 is_sane = false;
85 4 break;
86 }
87 5273 filtered_output->push_back(*begin);
88 5273 pos++;
89 } else {
90 2769 is_sane = false;
91 }
92 }
93 1057 return is_sane;
94 }
95
96
97 8046 bool InputSanitizer::CheckRanges(const char chr) const {
98
2/2
✓ Branch 1 taken 12681 times.
✓ Branch 2 taken 2769 times.
15450 for (unsigned j = 0; j < valid_ranges_.size(); ++j) {
99
2/2
✓ Branch 2 taken 5277 times.
✓ Branch 3 taken 7404 times.
12681 if (valid_ranges_[j].InRange(chr)) {
100 5277 return true;
101 }
102 }
103 2769 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 1035 bool InputSanitizer::IsValid(const std::string &input) const {
115 1035 string dummy;
116
1/2
✓ Branch 1 taken 1035 times.
✗ Branch 2 not taken.
2070 return Sanitize(input, &dummy);
117 1035 }
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