Skip to content

Commit e1e40d4

Browse files
committed
Avoid crashing on out-of-range inputs for int4 columns
This approach also avoids undefined behaviour when using sscanf, and changes the mean calculation to avoid overflows. Fixes #955
1 parent 08de8ce commit e1e40d4

File tree

1 file changed

+13
-4
lines changed

1 file changed

+13
-4
lines changed

table.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -457,12 +457,21 @@ void table_t::escape_type(const string &value, ColumnType flags)
457457
switch (flags) {
458458
case COLUMN_TYPE_INT: {
459459
// For integers we take the first number, or the average if it's a-b
460-
long from, to;
461-
int items = sscanf(value.c_str(), "%ld-%ld", &from, &to);
462-
if (items == 1) {
460+
int64_t from, to;
461+
// limit number of digits parsed to avoid undefined behaviour in sscanf
462+
int items = sscanf(value.c_str(), "%18ld-%18ld", &from, &to);
463+
if (items == 1 && from <= std::numeric_limits<int32_t>::max() &&
464+
from >= std::numeric_limits<int32_t>::min()) {
463465
m_copy.add_column(from);
464466
} else if (items == 2) {
465-
m_copy.add_column((from + to) / 2);
467+
// calculate mean while avoiding overflows
468+
int64_t mean = (from / 2) + (to / 2) + ((from % 2 + to % 2) / 2);
469+
if (mean <= std::numeric_limits<int32_t>::max() &&
470+
mean >= std::numeric_limits<int32_t>::min()) {
471+
m_copy.add_column(mean);
472+
} else {
473+
m_copy.add_null_column();
474+
}
466475
} else {
467476
m_copy.add_null_column();
468477
}

0 commit comments

Comments
 (0)