Skip to content

Commit 725276f

Browse files
committed
test error corrected
1 parent 29b4362 commit 725276f

File tree

3 files changed

+104
-56
lines changed

3 files changed

+104
-56
lines changed

src/operators/validate_byte_range.cc

Lines changed: 86 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515

1616
#include "src/operators/validate_byte_range.h"
1717

18+
#include <cctype>
19+
#include <cstring>
1820
#include <string>
1921
#include <memory>
2022

@@ -23,45 +25,90 @@
2325
namespace modsecurity {
2426
namespace operators {
2527

28+
namespace {
29+
30+
std::string trimCopy(const std::string &value) {
31+
std::string::size_type start = 0;
32+
std::string::size_type end = value.size();
33+
34+
while (start < end
35+
&& std::isspace(static_cast<unsigned char>(value[start]))) {
36+
start++;
37+
}
38+
while (end > start
39+
&& std::isspace(static_cast<unsigned char>(value[end - 1]))) {
40+
end--;
41+
}
42+
43+
return value.substr(start, end - start);
44+
}
45+
46+
bool parseStrictInt(const std::string &value, int *result, std::string *error) {
47+
const std::string trimmed = trimCopy(value);
48+
49+
if (trimmed.empty()) {
50+
error->assign("Not able to convert '" + value + "' into a number");
51+
return false;
52+
}
53+
54+
size_t pos = 0;
55+
56+
try {
57+
*result = std::stoi(trimmed, &pos);
58+
} catch (...) {
59+
error->assign("Not able to convert '" + trimmed + "' into a number");
60+
return false;
61+
}
62+
63+
if (pos != trimmed.size()) {
64+
error->assign("Not able to convert '" + trimmed + "' into a number");
65+
return false;
66+
}
67+
68+
return true;
69+
}
70+
71+
inline void allowByte(std::array<unsigned char, 32> *table, int value) {
72+
(*table)[value >> 3] = ((*table)[value >> 3]
73+
| (1U << static_cast<unsigned char>(value & 0x7)));
74+
}
75+
76+
} // namespace
77+
78+
2679
bool ValidateByteRange::getRange(const std::string &rangeRepresentation,
2780
std::string *error) {
28-
size_t pos = rangeRepresentation.find_first_of("-");
29-
int start;
30-
int end;
81+
return getRange(rangeRepresentation, &table, error);
82+
}
83+
84+
85+
bool ValidateByteRange::getRange(const std::string &rangeRepresentation,
86+
std::array<unsigned char, kTableSize> *targetTable,
87+
std::string *error) const {
88+
const std::string range = trimCopy(rangeRepresentation);
89+
const size_t pos = range.find_first_of("-");
90+
int start = 0;
91+
int end = 0;
3192

3293
if (pos == std::string::npos) {
33-
try {
34-
start = std::stoi(rangeRepresentation);
35-
} catch(...) {
36-
error->assign("Not able to convert '" + rangeRepresentation +
37-
"' into a number");
94+
if (parseStrictInt(range, &start, error) == false) {
3895
return false;
3996
}
4097
if ((start < 0) || (start > 255)) {
4198
error->assign("Invalid byte value: " +
4299
std::to_string(start));
43100
return false;
44101
}
45-
table[start >> 3] = (table[start >> 3] | (1 << (start & 0x7)));
102+
allowByte(targetTable, start);
46103
return true;
47104
}
48105

49-
try {
50-
start = std::stoi(std::string(rangeRepresentation, 0, pos));
51-
} catch (...) {
52-
error->assign("Not able to convert '" +
53-
std::string(rangeRepresentation, 0, pos) +
54-
"' into a number");
106+
if (parseStrictInt(std::string(range, 0, pos), &start, error) == false) {
55107
return false;
56108
}
57109

58-
try {
59-
end = std::stoi(std::string(rangeRepresentation, pos + 1,
60-
rangeRepresentation.length() - (pos + 1)));
61-
} catch (...) {
62-
error->assign("Not able to convert '" + std::string(rangeRepresentation,
63-
pos + 1, rangeRepresentation.length() - (pos + 1)) +
64-
"' into a number");
110+
if (parseStrictInt(std::string(range, pos + 1,
111+
range.length() - (pos + 1)), &end, error) == false) {
65112
return false;
66113
}
67114

@@ -81,7 +128,7 @@ bool ValidateByteRange::getRange(const std::string &rangeRepresentation,
81128
}
82129

83130
while (start <= end) {
84-
table[start >> 3] = (table[start >> 3] | (1 << (start & 0x7)));
131+
allowByte(targetTable, start);
85132
start++;
86133
}
87134

@@ -91,34 +138,29 @@ bool ValidateByteRange::getRange(const std::string &rangeRepresentation,
91138

92139
bool ValidateByteRange::init(const std::string &file,
93140
std::string *error) {
94-
size_t pos = m_param.find_first_of(",");
95-
bool rc;
141+
std::array<unsigned char, kTableSize> parsedTable{};
142+
std::string::size_type pos = 0;
96143

97-
if (pos == std::string::npos) {
98-
rc = getRange(m_param, error);
99-
} else {
100-
rc = getRange(std::string(m_param, 0, pos), error);
101-
}
144+
table.fill('\0');
102145

103-
if (rc == false) {
104-
return false;
105-
}
146+
while (true) {
147+
const std::string::size_type nextPos = m_param.find(',', pos);
148+
const std::string token = nextPos == std::string::npos
149+
? m_param.substr(pos)
150+
: m_param.substr(pos, nextPos - pos);
106151

107-
while (pos != std::string::npos) {
108-
size_t next_pos = m_param.find_first_of(",", pos + 1);
109-
110-
if (next_pos == std::string::npos) {
111-
rc = getRange(std::string(m_param, pos + 1, m_param.length() -
112-
(pos + 1)), error);
113-
} else {
114-
rc = getRange(std::string(m_param, pos + 1, next_pos - (pos + 1)), error);
115-
}
116-
if (rc == false) {
152+
if (getRange(token, &parsedTable, error) == false) {
117153
return false;
118154
}
119-
pos = next_pos;
155+
156+
if (nextPos == std::string::npos) {
157+
break;
158+
}
159+
160+
pos = nextPos + 1;
120161
}
121162

163+
table = parsedTable;
122164
return true;
123165
}
124166

src/operators/validate_byte_range.h

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,9 @@
1616
#ifndef SRC_OPERATORS_VALIDATE_BYTE_RANGE_H_
1717
#define SRC_OPERATORS_VALIDATE_BYTE_RANGE_H_
1818

19+
#include <array>
1920
#include <string>
20-
#include <vector>
21-
#include <cstring>
2221
#include <memory>
23-
#include <utility>
2422

2523
#include "src/operators/operator.h"
2624

@@ -32,19 +30,23 @@ class ValidateByteRange : public Operator {
3230
public:
3331
/** @ingroup ModSecurity_Operator */
3432
explicit ValidateByteRange(std::unique_ptr<RunTimeString> param)
35-
: Operator("ValidateByteRange", std::move(param)) {
36-
std::memset(table, '\0', sizeof(char) * 32);
37-
}
33+
: Operator("ValidateByteRange", std::move(param)) { }
3834
~ValidateByteRange() override { }
3935

4036
bool evaluate(Transaction *transaction, RuleWithActions *rule,
4137
const std::string &input,
4238
RuleMessage &ruleMessage) override;
4339
bool getRange(const std::string &rangeRepresentation, std::string *error);
4440
bool init(const std::string& file, std::string *error) override;
41+
4542
private:
46-
std::vector<std::string> ranges;
47-
char table[32];
43+
static constexpr size_t kTableSize = 32;
44+
45+
bool getRange(const std::string &rangeRepresentation,
46+
std::array<unsigned char, kTableSize> *targetTable,
47+
std::string *error) const;
48+
49+
std::array<unsigned char, kTableSize> table{};
4850
};
4951

5052
} // namespace operators

test/Makefile.am

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,14 @@ unit_tests_SOURCES = \
3636

3737

3838
noinst_HEADERS = \
39-
common/modsecurity_test.cc \
40-
common/*.h \
41-
unit/*.h \
42-
regression/*.h
39+
$(srcdir)/common/colors.h \
40+
$(srcdir)/common/custom_debug_log.h \
41+
$(srcdir)/common/json.h \
42+
$(srcdir)/common/modsecurity_test.h \
43+
$(srcdir)/common/modsecurity_test_context.h \
44+
$(srcdir)/common/modsecurity_test_results.h \
45+
$(srcdir)/unit/unit_test.h \
46+
$(srcdir)/regression/regression_test.h
4347

4448

4549
unit_tests_LDADD = \

0 commit comments

Comments
 (0)