Bug category
Describe the bug
Hello, while studying matplot/util/common.cpp, I noticed that the implementation for transform derives the number of columns based on the number of columns in the first row of a 2D vector. This results in access violations when calling the function with a vector in which any subsequent row has less than x[0].size() elements (see example below).
Similarly, I think this issue also presents itself in flatten because if x[0].size() happens to be smaller than any other row, the output vector's reserved size will be too small, requiring reallocation during the insert operation. This reallocation would render the iterators invalid (if I understood std::vector::insert correctly).
Steps to Reproduce
Compile and run these tests:
Test 1: Non-empty Rows
Details
// matplot_seg_fault.cpp
#include <iostream>
#include <vector>
#include <matplot/matplot.h>
void print_vec(std::vector<std::vector<double>> v)
{
for(int i {0}; i < v.size(); ++i)
{
std::cout << "\n";
for (int j {0}; j < v[i].size(); ++j)
std::cout << v[i][j] << " ";
}
std::cout << "\n";
}
int main()
{
namespace mpl = matplot;
std::vector<std::vector<double>> bad_input {
std::vector<double(10, 0.),
{0.},
{0.},
};
auto bad_transformed = mpl::transform(bad_input, [](double x){ return x; });
print_vec(bad_transformed);
}
Output
0 0 0 0 0 0 0 0 0 0
0 0 0 1.63042e-322 2 0 0 4.00193e-322 2.74672e-315 2.74672e-315
0 0 0 4.00193e-322 2.74672e-315 2.74672e-315 2.74672e-315 2.74672e-315 2.74672e-315 2.74672e-315
Test 2: Empty Rows
Details
// matplot_seg_fault.cpp
#include <iostream>
#include <vector>
#include <matplot/matplot.h>
void print_vec(std::vector<std::vector<double>> v)
{
for(int i {0}; i < v.size(); ++i)
{
std::cout << "\n";
for (int j {0}; j < v[i].size(); ++j)
std::cout << v[i][j] << " ";
}
std::cout << "\n";
}
int main()
{
namespace mpl = matplot;
std::vector<std::vector<double>> bad_input {
{0., 1., 2., 3.},
{},
{},
{},
};
auto bad_transformed = mpl::transform(bad_input, [](double x){ return x; }); // seg faults here
print_vec(bad_transformed);
}
Output
Segmentation fault (core dumped)
Platform
Environment Details:
- OS: Fedora Linux
- OS Version: 6.11.7-300.fc41.x86_64
- Compiler: gcc
- Compiler version: 14.2.1 20240912
Additional context
I am aware that most users would pass in homogeneously-dimensioned vectors to the API, but I wanted to test to see if the potential violation was there. I don't know whether the library's perspective is to assume users wouldn't do that or to ensure they won't, so I decided to report it just in case.
P.S.
Not really the subject of the report, but I also noticed an inconsistency of capitalization on _TEMP_MACRO_ on line 248 of common.cpp when compared to lines 227, 250, and 252. I don't know if macros are case-sensitive or not, so I'm just noting it here.
Bug category
Describe the bug
Hello, while studying
matplot/util/common.cpp, I noticed that the implementation fortransformderives the number of columns based on the number of columns in the first row of a 2D vector. This results in access violations when calling the function with a vector in which any subsequent row has less thanx[0].size()elements (see example below).Similarly, I think this issue also presents itself in
flattenbecause ifx[0].size()happens to be smaller than any other row, the output vector's reserved size will be too small, requiring reallocation during the insert operation. This reallocation would render the iterators invalid (if I understood std::vector::insert correctly).Steps to Reproduce
Compile and run these tests:
Test 1: Non-empty Rows
Details
Output
Test 2: Empty Rows
Details
Output
Segmentation fault (core dumped)Platform
Environment Details:
Additional context
I am aware that most users would pass in homogeneously-dimensioned vectors to the API, but I wanted to test to see if the potential violation was there. I don't know whether the library's perspective is to assume users wouldn't do that or to ensure they won't, so I decided to report it just in case.
P.S.
Not really the subject of the report, but I also noticed an inconsistency of capitalization on
_TEMP_MACRO_on line 248 ofcommon.cppwhen compared to lines 227, 250, and 252. I don't know if macros are case-sensitive or not, so I'm just noting it here.