Skip to content

Commit 98ae940

Browse files
committed
fixes #186 - out-of-range RemoveColumn to throw exception instead of segfaulting
1 parent 083851d commit 98ae940

4 files changed

Lines changed: 66 additions & 8 deletions

File tree

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ if(RAPIDCSV_BUILD_TESTS)
182182
add_unit_test(test096)
183183
add_unit_test(test097)
184184
add_unit_test(test098)
185+
add_unit_test(test099)
185186

186187
# perf tests
187188
add_perf_test(ptest001)

src/rapidcsv.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* rapidcsv.h
33
*
44
* URL: https://github.com/d99kris/rapidcsv
5-
* Version: 8.85
5+
* Version: 8.86
66
*
77
* Copyright (C) 2017-2025 Kristofer Berggren
88
* All rights reserved.
@@ -774,7 +774,18 @@ namespace rapidcsv
774774
{
775775
if (std::distance(mData.begin(), itRow) >= mLabelParams.mColumnNameIdx)
776776
{
777-
itRow->erase(itRow->begin() + static_cast<int>(dataColumnIdx));
777+
if (dataColumnIdx < itRow->size())
778+
{
779+
itRow->erase(itRow->begin() + static_cast<int>(dataColumnIdx));
780+
}
781+
else
782+
{
783+
const std::string errStr = "column out of range: " +
784+
std::to_string(pColumnIdx) + " (on row " +
785+
std::to_string(std::distance(mData.begin(), itRow)) +
786+
")";
787+
throw std::out_of_range(errStr);
788+
}
778789
}
779790
}
780791

tests/test018.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ int main()
88
int rv = 0;
99

1010
std::string csvref =
11-
"B,D\n"
12-
"4,256\n"
13-
"9,6561\n"
14-
"16,65536\n"
15-
"25,390625\n"
11+
"B,C\n"
12+
"4,16\n"
13+
"9,81\n"
14+
"16,256\n"
15+
"25,625\n"
1616
;
1717

1818
std::string csv =
@@ -30,7 +30,7 @@ int main()
3030
{
3131
rapidcsv::Document doc(path);
3232

33-
doc.RemoveColumn("C");
33+
doc.RemoveColumn("D");
3434
doc.RemoveColumn(0);
3535

3636
doc.Save();

tests/test099.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// test099.cpp - exception message removing out-of-range column
2+
3+
#include <rapidcsv.h>
4+
#include "unittest.h"
5+
6+
int main()
7+
{
8+
int rv = 0;
9+
10+
std::string csv =
11+
"-,A,B,C,D\n"
12+
"1,3,9,81,6561\n"
13+
"2,4,16,256\n"
14+
;
15+
16+
std::string path = unittest::TempPath();
17+
unittest::WriteFile(path, csv);
18+
19+
try
20+
{
21+
rapidcsv::Document doc(path, rapidcsv::LabelParams(0, 0));
22+
23+
doc.RemoveColumn("A");
24+
unittest::ExpectEqual(std::string, doc.GetColumnName(0), "B");
25+
26+
doc.RemoveColumn(0);
27+
unittest::ExpectEqual(std::string, doc.GetColumnName(0), "C");
28+
29+
// doc has columns C (0) and D (1) now, thus 2 is out of range.
30+
ExpectExceptionMsg(doc.RemoveColumn(2), std::out_of_range,
31+
"column out of range: 2 (on row 0)");
32+
33+
// column D, while existing, has not data on all rows, thus out of range.
34+
ExpectExceptionMsg(doc.RemoveColumn("D"), std::out_of_range,
35+
"column out of range: 1 (on row 2)");
36+
}
37+
catch (const std::exception& ex)
38+
{
39+
std::cout << ex.what() << std::endl;
40+
rv = 1;
41+
}
42+
43+
unittest::DeleteFile(path);
44+
45+
return rv;
46+
}

0 commit comments

Comments
 (0)