Skip to content

Commit ec1a692

Browse files
authored
fix: check run_ends_view->length before accessing its values (#518)
This PR should fix the issue where `run_ends_view->length` is not checked if equals to 0 before attempting to access `run_ends_view`'s values. Many thanks to @WillAyd.
1 parent 8680f6d commit ec1a692

File tree

1 file changed

+21
-17
lines changed

1 file changed

+21
-17
lines changed

src/nanoarrow/array.c

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,6 +1067,7 @@ static int ArrowArrayViewValidateDefault(struct ArrowArrayView* array_view,
10671067

10681068
case NANOARROW_TYPE_RUN_END_ENCODED: {
10691069
struct ArrowArrayView* run_ends_view = array_view->children[0];
1070+
if (run_ends_view->length == 0) break;
10701071
int64_t last_run_end = ArrowArrayViewGetIntUnsafe(run_ends_view, 0);
10711072
if (last_run_end < 1) {
10721073
ArrowErrorSet(error,
@@ -1246,25 +1247,28 @@ static int ArrowArrayViewValidateFull(struct ArrowArrayView* array_view,
12461247

12471248
if (array_view->storage_type == NANOARROW_TYPE_RUN_END_ENCODED) {
12481249
struct ArrowArrayView* run_ends_view = array_view->children[0];
1249-
int64_t last_run_end = ArrowArrayViewGetIntUnsafe(run_ends_view, 0);
1250-
for (int64_t i = 1; i < run_ends_view->length; i++) {
1251-
const int64_t run_end = ArrowArrayViewGetIntUnsafe(run_ends_view, i);
1252-
if (run_end <= last_run_end) {
1253-
ArrowErrorSet(error,
1254-
"Every run end must be strictly greater than the previous run end, "
1255-
"but run_ends[%ld] is %ld and run_ends[%ld] is %ld",
1256-
(long)i, (long)run_end, (long)i - 1, (long)last_run_end);
1250+
if (run_ends_view->length > 0) {
1251+
int64_t last_run_end = ArrowArrayViewGetIntUnsafe(run_ends_view, 0);
1252+
for (int64_t i = 1; i < run_ends_view->length; i++) {
1253+
const int64_t run_end = ArrowArrayViewGetIntUnsafe(run_ends_view, i);
1254+
if (run_end <= last_run_end) {
1255+
ArrowErrorSet(
1256+
error,
1257+
"Every run end must be strictly greater than the previous run end, "
1258+
"but run_ends[%ld] is %ld and run_ends[%ld] is %ld",
1259+
(long)i, (long)run_end, (long)i - 1, (long)last_run_end);
1260+
return EINVAL;
1261+
}
1262+
last_run_end = run_end;
1263+
}
1264+
last_run_end = ArrowArrayViewGetIntUnsafe(run_ends_view, run_ends_view->length - 1);
1265+
if (last_run_end < (array_view->offset + array_view->length)) {
1266+
ArrowErrorSet(
1267+
error, "Last run end is %ld but it should >= %ld (offset: %ld, length: %ld)",
1268+
(long)last_run_end, (long)(array_view->offset + array_view->length),
1269+
(long)array_view->offset, (long)array_view->length);
12571270
return EINVAL;
12581271
}
1259-
last_run_end = run_end;
1260-
}
1261-
last_run_end = ArrowArrayViewGetIntUnsafe(run_ends_view, run_ends_view->length - 1);
1262-
if (last_run_end < (array_view->offset + array_view->length)) {
1263-
ArrowErrorSet(error,
1264-
"Last run end is %ld but it should >= %ld (offset: %ld, length: %ld)",
1265-
(long)last_run_end, (long)(array_view->offset + array_view->length),
1266-
(long)array_view->offset, (long)array_view->length);
1267-
return EINVAL;
12681272
}
12691273
}
12701274

0 commit comments

Comments
 (0)