proddy
2026-06-22 22:54:25 +02:00
parent 17f76e594d
commit 745d87c6d2
2 changed files with 37 additions and 5 deletions

View File

@@ -334,9 +334,12 @@ std::deque<Token> shuntingYard(const std::deque<Token> & tokens) {
return queue;
}
// check if string is a number
// check if string is a number. Must contain at least one digit
bool isnum(const std::string & s) {
if (!s.empty() && (s.find_first_not_of("0123456789.") == std::string::npos || (s[0] == '-' && s.find_first_not_of("0123456789.", 1) == std::string::npos))) {
if (s.empty() || s.find_first_of("0123456789") == std::string::npos) {
return false;
}
if (s.find_first_not_of("0123456789.") == std::string::npos || (s[0] == '-' && s.find_first_not_of("0123456789.", 1) == std::string::npos)) {
return true;
}
return false;
@@ -499,6 +502,18 @@ std::string calculate(const std::string & expr) {
}
break;
}
if (token.str[0] == 'h') {
// hex string to number
if (rhs.empty() || rhs.find_first_not_of("0123456789abcdefABCDEF") != std::string::npos) {
return "";
}
stack.push_back(to_string(std::stoi(rhs, 0, 16)));
break;
}
// bail out on non-numeric operand
if (!isnum(rhs)) {
return "";
}
auto rhd = std::stod(rhs);
switch (token.str[0]) {
default:
@@ -531,9 +546,6 @@ std::string calculate(const std::string & expr) {
case 'p':
stack.push_back(to_string(std::pow(rhd, 2)));
break;
case 'h':
stack.push_back(to_string(std::stoi(rhs, 0, 16)));
break;
case 'x':
stack.push_back(to_hex(static_cast<int>(rhd)));
break;
@@ -641,6 +653,10 @@ std::string calculate(const std::string & expr) {
stack.push_back(lhs + rhs);
break;
}
// bail out on non-numeric operands
if (!isnum(lhs) || !isnum(rhs)) {
return "";
}
auto lhd = std::stod(lhs);
auto rhd = std::stod(rhs);
switch (token.str[0]) {

View File

@@ -107,6 +107,19 @@ void shuntingYard_test25() {
run_shuntingYard_test("hello world!", "'hello world!'");
}
// non-numeric operands must not crash. should return empty string
void shuntingYard_test26() {
run_shuntingYard_test("", "info/x");
}
void shuntingYard_test27() {
run_shuntingYard_test("", "info-x");
}
void shuntingYard_test28() {
run_shuntingYard_test("", "-x");
}
void run_shuntingYard_tests() {
RUN_TEST(shuntingYard_test1);
RUN_TEST(shuntingYard_test2);
@@ -133,4 +146,7 @@ void run_shuntingYard_tests() {
RUN_TEST(shuntingYard_test23);
RUN_TEST(shuntingYard_test24);
RUN_TEST(shuntingYard_test25);
RUN_TEST(shuntingYard_test26);
RUN_TEST(shuntingYard_test27);
RUN_TEST(shuntingYard_test28);
}