Skip to content

Commit 4e2dc81

Browse files
ferdymercuryvepadulano
authored andcommitted
[hist] check for balanced parentheses, brackets, braces or quotes
set IsValid to false otherwise while constructing TFormula
1 parent 5ef9da8 commit 4e2dc81

1 file changed

Lines changed: 44 additions & 1 deletion

File tree

hist/hist/src/TFormula.cxx

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@
2222

2323
#include "ROOT/StringUtils.hxx"
2424

25-
#include <array>
2625
#include <functional>
2726
#include <iomanip>
2827
#include <iostream>
2928
#include <limits>
3029
#include <memory>
3130
#include <set>
31+
#include <stack>
3232
#include <sstream>
3333
#include <unordered_map>
3434

@@ -49,6 +49,43 @@ std::string doubleToString(double val)
4949
return ss.str();
5050
}
5151

52+
bool areMatching(char opening, char closing)
53+
{
54+
return (opening == '(' && closing == ')') || (opening == '{' && closing == '}') ||
55+
(opening == '[' && closing == ']') || (opening == '\"' && closing == '\"');
56+
}
57+
58+
bool isBalanced(const TString &s)
59+
{
60+
std::stack<char> i;
61+
auto sLength = s.Length();
62+
for (Ssiz_t c = 0; c < sLength; ++c) {
63+
if (s[c] == '[' || s[c] == '{' || s[c] == '(') {
64+
i.push(s[c]);
65+
} else if (s[c] == ']' || s[c] == '}' || s[c] == ')') {
66+
if (i.empty() || !areMatching(i.top(), s[c])) {
67+
Error("TFormula", "Found unbalanced char %c (expected closing of %c) at index %d of %s", s[c], i.top(), c,
68+
s.Data());
69+
return false;
70+
} else
71+
i.pop();
72+
} else if (s[c] == '\"') {
73+
if (i.empty())
74+
i.push(s[c]);
75+
else if (areMatching(i.top(), s[c]))
76+
i.pop();
77+
else {
78+
i.push(s[c]);
79+
}
80+
}
81+
}
82+
if (!i.empty()) {
83+
Error("TFormula", "String %s with %zu unbalanced chars.", s.Data(), i.size());
84+
return false;
85+
}
86+
return true;
87+
}
88+
5289
// In the interpreter, we must match the SIMD width used by compiled ROOT.
5390
// ROOT::Double_v aliases the best available native SIMD type, which may differ
5491
// between compiled and interpreted contexts (e.g. with -march=native).
@@ -1860,6 +1897,12 @@ Bool_t TFormula::PrepareFormula(TString &formula)
18601897
{
18611898
fFuncs.clear();
18621899
fReadyToExecute = false;
1900+
1901+
// Check for balanced parentheses
1902+
if (!isBalanced(formula)) {
1903+
return false;
1904+
}
1905+
18631906
ExtractFunctors(formula);
18641907

18651908
// update the expression with the new formula

0 commit comments

Comments
 (0)