Skip to content

Commit 1ae46fe

Browse files
committed
stoi to from_chars, reducing unsupported try catch
Signed-off-by: Matteo Pace <[email protected]>
1 parent 1eb136c commit 1ae46fe

12 files changed

+118
-100
lines changed

src/actions/accuracy.cc

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include <iostream>
1919
#include <string>
20+
#include <charconv>
2021

2122
#include "modsecurity/actions/action.h"
2223
#include "modsecurity/transaction.h"
@@ -28,9 +29,8 @@ namespace actions {
2829

2930

3031
bool Accuracy::init(std::string *error) {
31-
try {
32-
m_accuracy = std::stoi(m_parser_payload);
33-
} catch (...) {
32+
const auto conv_res = std::from_chars(m_parser_payload.data(), m_parser_payload.data() + m_parser_payload.size(), m_accuracy);
33+
if (conv_res.ec == std::errc::invalid_argument) {
3434
error->assign("Accuracy: The input \"" + m_parser_payload + "\" is " \
3535
"not a number.");
3636
return false;

src/actions/ctl/rule_remove_by_id.cc

+20-13
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
#include <iostream>
1919
#include <string>
20+
#include <charconv>
21+
2022

2123
#include "modsecurity/transaction.h"
2224
#include "src/utils/string.h"
@@ -42,19 +44,21 @@ bool RuleRemoveById::init(std::string *error) {
4244
std::string n2s = std::string(b, dash + 1, b.size() - (dash + 1));
4345
int n1n = 0;
4446
int n2n = 0;
45-
try {
46-
n1n = std::stoi(n1s);
47-
added = true;
48-
} catch (...) {
47+
48+
const auto conv_res = std::from_chars(n1s.data(), n1s.data() + n1s.size(), n1n);
49+
if (conv_res.ec == std::errc::invalid_argument) {
4950
error->assign("Not a number: " + n1s);
5051
return false;
51-
}
52-
try {
53-
n2n = std::stoi(n2s);
52+
} else {
5453
added = true;
55-
} catch (...) {
54+
}
55+
56+
const auto conv_res2 = std::from_chars(n2s.data(), n2s.data() + n2s.size(), n2n);
57+
if (conv_res2.ec == std::errc::invalid_argument) {
5658
error->assign("Not a number: " + n2s);
5759
return false;
60+
} else {
61+
added = true;
5862
}
5963

6064
if (n1n > n2n) {
@@ -64,13 +68,16 @@ bool RuleRemoveById::init(std::string *error) {
6468
m_ranges.push_back(std::make_pair(n1n, n2n));
6569
added = true;
6670
} else {
67-
try {
68-
int num = std::stoi(b);
69-
m_ids.push_back(num);
70-
added = true;
71-
} catch (...) {
71+
int num;
72+
const auto conv_res3 = std::from_chars(b.data(), b.data() + b.size(), num);
73+
if (conv_res3.ec == std::errc::invalid_argument) {
74+
// Conversion Fail
7275
error->assign("Not a number or range: " + b);
7376
return false;
77+
} else {
78+
// Conversion Done
79+
m_ids.push_back(num);
80+
added = true;
7481
}
7582
}
7683
}

src/actions/ctl/rule_remove_target_by_id.cc

+3-3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <string>
2020
#include <vector>
2121
#include <utility>
22+
#include <charconv>
2223

2324
#include "modsecurity/transaction.h"
2425
#include "src/utils/string.h"
@@ -38,9 +39,8 @@ bool RuleRemoveTargetById::init(std::string *error) {
3839
return false;
3940
}
4041

41-
try {
42-
m_id = std::stoi(param[0]);
43-
} catch(...) {
42+
const auto conv_res = std::from_chars(param[0].data(), param[0].data() + param[0].size(), m_id);
43+
if (conv_res.ec == std::errc::invalid_argument) {
4444
error->assign("Not able to convert '" + param[0] +
4545
"' into a number");
4646
return false;

src/actions/data/status.cc

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <iostream>
1919
#include <string>
2020
#include <memory>
21+
#include <charconv>
2122

2223
#include "modsecurity/transaction.h"
2324

@@ -27,9 +28,8 @@ namespace actions {
2728
namespace data {
2829

2930
bool Status::init(std::string *error) {
30-
try {
31-
m_status = std::stoi(m_parser_payload);
32-
} catch (...) {
31+
const auto conv_res = std::from_chars(m_parser_payload.data(), m_parser_payload.data() + m_parser_payload.size(), m_status);
32+
if (conv_res.ec == std::errc::invalid_argument) {
3333
error->assign("Not a valid number: " + m_parser_payload);
3434
return false;
3535
}

src/actions/maturity.cc

+5-3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include <iostream>
1919
#include <string>
20+
#include <charconv>
2021

2122
#include "modsecurity/actions/action.h"
2223
#include "modsecurity/transaction.h"
@@ -28,9 +29,10 @@ namespace actions {
2829

2930

3031
bool Maturity::init(std::string *error) {
31-
try {
32-
m_maturity = std::stoi(m_parser_payload);
33-
} catch (...) {
32+
33+
const auto conv_res = std::from_chars(m_parser_payload.data(), m_parser_payload.data() + m_parser_payload.size(), m_maturity);
34+
if (conv_res.ec == std::errc::invalid_argument) {
35+
// Conversion error
3436
error->assign("Maturity: The input \"" + m_parser_payload + "\" is " \
3537
"not a number.");
3638
return false;

src/actions/phase.cc

+17-14
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include <iostream>
1919
#include <string>
20+
#include <charconv>
2021

2122
#include "modsecurity/transaction.h"
2223
#include "modsecurity/rule.h"
@@ -31,8 +32,22 @@ bool Phase::init(std::string *error) {
3132
std::string a = utils::string::tolower(m_parser_payload);
3233
m_phase = -1;
3334

34-
try {
35-
m_phase = std::stoi(m_parser_payload);
35+
36+
const auto conv_res = std::from_chars(m_parser_payload.data(), m_parser_payload.data() + m_parser_payload.size(), m_phase);
37+
if (conv_res.ec == std::errc::invalid_argument) {
38+
// Conversion Fail
39+
if (a == "request") {
40+
m_phase = modsecurity::Phases::RequestBodyPhase;
41+
m_secRulesPhase = 2;
42+
} else if (a == "response") {
43+
m_phase = modsecurity::Phases::ResponseBodyPhase;
44+
m_secRulesPhase = 4;
45+
} else if (a == "logging") {
46+
m_phase = modsecurity::Phases::LoggingPhase;
47+
m_secRulesPhase = 5;
48+
}
49+
} else {
50+
// Conversion Done
3651
if (m_phase == 0) {
3752
m_phase = modsecurity::Phases::ConnectionPhase;
3853
m_secRulesPhase = 0;
@@ -55,19 +70,7 @@ bool Phase::init(std::string *error) {
5570
error->assign("Unknown phase: " + m_parser_payload);
5671
return false;
5772
}
58-
} catch (...) {
59-
if (a == "request") {
60-
m_phase = modsecurity::Phases::RequestBodyPhase;
61-
m_secRulesPhase = 2;
62-
} else if (a == "response") {
63-
m_phase = modsecurity::Phases::ResponseBodyPhase;
64-
m_secRulesPhase = 4;
65-
} else if (a == "logging") {
66-
m_phase = modsecurity::Phases::LoggingPhase;
67-
m_secRulesPhase = 5;
68-
}
6973
}
70-
7174
return true;
7275
}
7376

src/actions/set_var.cc

+17-15
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <iostream>
1919
#include <string>
2020
#include <memory>
21+
#include <charconv>
2122

2223
#include "modsecurity/rules_set.h"
2324
#include "modsecurity/transaction.h"
@@ -104,28 +105,29 @@ bool SetVar::evaluate(RuleWithActions *rule, Transaction *t) {
104105
int pre = 0;
105106
int value = 0;
106107

107-
try {
108-
pre = stoi(resolvedPre);
109-
} catch (...) {
108+
109+
const auto conv_res = std::from_chars(resolvedPre.data(), resolvedPre.data() + resolvedPre.size(), pre);
110+
if (conv_res.ec == std::errc::invalid_argument) {
111+
// Conversion error
110112
pre = 0;
111113
}
112114

113-
try {
114-
std::vector<const VariableValue *> l;
115-
RuleWithOperator *rr = dynamic_cast<RuleWithOperator *>(rule);
116-
m_variable->evaluate(t, rr, &l);
117-
if (l.size() == 0) {
115+
std::vector<const VariableValue *> l;
116+
RuleWithOperator *rr = dynamic_cast<RuleWithOperator *>(rule);
117+
m_variable->evaluate(t, rr, &l);
118+
if (l.size() == 0) {
119+
value = 0;
120+
} else {
121+
const auto conv_res2 = std::from_chars(l[0]->getValue().data(), l[0]->getValue().data() + l[0]->getValue().size(), value);
122+
if (conv_res2.ec == std::errc::invalid_argument) {
118123
value = 0;
119-
} else {
120-
value = stoi(l[0]->getValue());
121-
for (auto &i : l) {
122-
delete i;
123-
}
124124
}
125-
} catch (...) {
126-
value = 0;
125+
for (auto &i : l) {
126+
delete i;
127+
}
127128
}
128129

130+
129131
if (m_operation == sumAndSetOperation) {
130132
targetValue = std::to_string(value + pre);
131133
} else if (m_operation == substractAndSetOperation) {

src/actions/severity.cc

+5-5
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <iostream>
1919
#include <string>
2020
#include <memory>
21+
#include <charconv>
2122

2223
#include "modsecurity/rules_set.h"
2324
#include "modsecurity/actions/action.h"
@@ -58,15 +59,14 @@ bool Severity::init(std::string *error) {
5859
m_severity = 7;
5960
return true;
6061
} else {
61-
try {
62-
m_severity = std::stoi(a);
63-
return true;
64-
} catch (...) {
62+
const auto conv_res = std::from_chars(a.data(), a.data() + a.size(), m_severity);
63+
if (conv_res.ec == std::errc::invalid_argument) {
6564
error->assign("Severity: The input \"" + a + "\" is " \
6665
"not a number.");
66+
} else {
67+
return true;
6768
}
6869
}
69-
7070
return false;
7171
}
7272

src/actions/skip.cc

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include <iostream>
1919
#include <string>
20+
#include <charconv>
2021

2122
#include "modsecurity/rules_set.h"
2223
#include "modsecurity/actions/action.h"
@@ -27,9 +28,8 @@ namespace actions {
2728

2829

2930
bool Skip::init(std::string *error) {
30-
try {
31-
m_skip_next = std::stoi(m_parser_payload);
32-
} catch (...) {
31+
const auto conv_res = std::from_chars(m_parser_payload.data(), m_parser_payload.data() + m_parser_payload.size(), m_skip_next);
32+
if (conv_res.ec == std::errc::invalid_argument) {
3333
error->assign("Skip: The input \"" + m_parser_payload + "\" is " \
3434
"not a number.");
3535
return false;

src/operators/eq.cc

+5-6
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "src/operators/eq.h"
1717

1818
#include <string>
19+
#include <charconv>
1920

2021
#include "src/operators/operator.h"
2122

@@ -29,14 +30,12 @@ bool Eq::evaluate(Transaction *transaction, const std::string &input) {
2930
int i = 0;
3031
std::string pt(m_string->evaluate(transaction));
3132

32-
try {
33-
p = std::stoi(pt);
34-
} catch (...) {
33+
const auto conv_res = std::from_chars(pt.data(), pt.data() + pt.size(), p);
34+
if (conv_res.ec == std::errc::invalid_argument) {
3535
p = 0;
3636
}
37-
try {
38-
i = std::stoi(input);
39-
} catch (...) {
37+
const auto conv_res2 = std::from_chars(input.data(), input.data() + input.size(), i);
38+
if (conv_res2.ec == std::errc::invalid_argument) {
4039
i = 0;
4140
}
4241

src/operators/validate_byte_range.cc

+13-17
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include <string>
1919
#include <memory>
20+
#include <charconv>
2021

2122
#include "src/operators/operator.h"
2223

@@ -29,34 +30,29 @@ bool ValidateByteRange::getRange(const std::string &rangeRepresentation,
2930
int start;
3031
int end;
3132

32-
if (pos == std::string::npos) {
33-
try {
34-
start = std::stoi(rangeRepresentation);
35-
} catch(...) {
33+
if (pos == std::string::npos) {
34+
const auto conv_res = std::from_chars(rangeRepresentation.data(), rangeRepresentation.data() + rangeRepresentation.size(), start);
35+
if (conv_res.ec == std::errc::invalid_argument) {
3636
error->assign("Not able to convert '" + rangeRepresentation +
3737
"' into a number");
3838
return false;
3939
}
40+
4041
table[start >> 3] = (table[start >> 3] | (1 << (start & 0x7)));
4142
return true;
4243
}
4344

44-
try {
45-
start = std::stoi(std::string(rangeRepresentation, 0, pos));
46-
} catch (...) {
47-
error->assign("Not able to convert '" +
48-
std::string(rangeRepresentation, 0, pos) +
49-
"' into a number");
45+
std::string to_be_converted(rangeRepresentation, 0, pos);
46+
const auto conv_res2 = std::from_chars(to_be_converted.data(), to_be_converted.data() + to_be_converted.size(), start);
47+
if (conv_res2.ec == std::errc::invalid_argument) {
48+
error->assign("Not able to convert '" + to_be_converted + "' into a number");
5049
return false;
5150
}
5251

53-
try {
54-
end = std::stoi(std::string(rangeRepresentation, pos + 1,
55-
rangeRepresentation.length() - (pos + 1)));
56-
} catch (...) {
57-
error->assign("Not able to convert '" + std::string(rangeRepresentation,
58-
pos + 1, rangeRepresentation.length() - (pos + 1)) +
59-
"' into a number");
52+
std::string to_be_converted2(rangeRepresentation, pos + 1, rangeRepresentation.length() - (pos + 1));
53+
const auto conv_res3 = std::from_chars(to_be_converted2.data(), to_be_converted2.data() + to_be_converted2.size(), end);
54+
if (conv_res3.ec == std::errc::invalid_argument) {
55+
error->assign("Not able to convert '" + to_be_converted2 + "' into a number");
6056
return false;
6157
}
6258

0 commit comments

Comments
 (0)