Following up on #580, which @pelesh closed asking for an issue with a reproducer and a suggested solution.
readMatPowerGenCostRow in GridKit/Model/PowerFlow/MatpowerParser.hpp checks the last character after trimming:
rtrim(row);
if (row[row.size() - 1] != ';')
A blank line inside mpc.gencost leaves row empty, so row.size() - 1 wraps around and the read goes out of bounds.
Reproducer, driving GridKit::readMatPower with a small case file whose mpc.gencost block starts with an empty line:
mpc.gencost = [
2 0 0 3 0.01 40 0;
];
Built with clang++ -std=c++17 -fsanitize=address -g:
==36380==ERROR: AddressSanitizer: stack-buffer-underflow
#0 readMatPowerGenCostRow<double, int> MatpowerParser.hpp:156
#0 readMatPower<int, double, 1028ul> MatpowerParser.hpp:211
The bus, gen and branch row readers take the same line without trouble, since they only read through operator>>, so this is specific to the gencost reader.
Suggested solution: treat an empty row the way a row with the wrong terminator is treated, so the reader raises the parser's own syntax error rather than indexing the string. Something as small as checking for an empty string before looking at the last character is enough; I have that change and the reproducer ready if you would like a PR against it.
Following up on #580, which @pelesh closed asking for an issue with a reproducer and a suggested solution.
readMatPowerGenCostRowinGridKit/Model/PowerFlow/MatpowerParser.hppchecks the last character after trimming:A blank line inside
mpc.gencostleavesrowempty, sorow.size() - 1wraps around and the read goes out of bounds.Reproducer, driving
GridKit::readMatPowerwith a small case file whosempc.gencostblock starts with an empty line:Built with
clang++ -std=c++17 -fsanitize=address -g:The bus, gen and branch row readers take the same line without trouble, since they only read through
operator>>, so this is specific to the gencost reader.Suggested solution: treat an empty row the way a row with the wrong terminator is treated, so the reader raises the parser's own syntax error rather than indexing the string. Something as small as checking for an empty string before looking at the last character is enough; I have that change and the reproducer ready if you would like a PR against it.