This is an automated email from the ASF dual-hosted git repository. paleolimbot pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/arrow-nanoarrow.git
The following commit(s) were added to refs/heads/main by this push: new ec1a6927 fix: check `run_ends_view->length` before accessing its values (#518) ec1a6927 is described below commit ec1a6927283a33a97232047179b6abc77c374de3 Author: Cocoa <i...@uwucocoa.moe> AuthorDate: Tue Jun 11 05:09:48 2024 -0700 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. --- src/nanoarrow/array.c | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/src/nanoarrow/array.c b/src/nanoarrow/array.c index 36df998f..ebd95df1 100644 --- a/src/nanoarrow/array.c +++ b/src/nanoarrow/array.c @@ -1067,6 +1067,7 @@ static int ArrowArrayViewValidateDefault(struct ArrowArrayView* array_view, case NANOARROW_TYPE_RUN_END_ENCODED: { struct ArrowArrayView* run_ends_view = array_view->children[0]; + if (run_ends_view->length == 0) break; int64_t last_run_end = ArrowArrayViewGetIntUnsafe(run_ends_view, 0); if (last_run_end < 1) { ArrowErrorSet(error, @@ -1246,25 +1247,28 @@ static int ArrowArrayViewValidateFull(struct ArrowArrayView* array_view, if (array_view->storage_type == NANOARROW_TYPE_RUN_END_ENCODED) { struct ArrowArrayView* run_ends_view = array_view->children[0]; - int64_t last_run_end = ArrowArrayViewGetIntUnsafe(run_ends_view, 0); - for (int64_t i = 1; i < run_ends_view->length; i++) { - const int64_t run_end = ArrowArrayViewGetIntUnsafe(run_ends_view, i); - if (run_end <= last_run_end) { - ArrowErrorSet(error, - "Every run end must be strictly greater than the previous run end, " - "but run_ends[%ld] is %ld and run_ends[%ld] is %ld", - (long)i, (long)run_end, (long)i - 1, (long)last_run_end); + if (run_ends_view->length > 0) { + int64_t last_run_end = ArrowArrayViewGetIntUnsafe(run_ends_view, 0); + for (int64_t i = 1; i < run_ends_view->length; i++) { + const int64_t run_end = ArrowArrayViewGetIntUnsafe(run_ends_view, i); + if (run_end <= last_run_end) { + ArrowErrorSet( + error, + "Every run end must be strictly greater than the previous run end, " + "but run_ends[%ld] is %ld and run_ends[%ld] is %ld", + (long)i, (long)run_end, (long)i - 1, (long)last_run_end); + return EINVAL; + } + last_run_end = run_end; + } + last_run_end = ArrowArrayViewGetIntUnsafe(run_ends_view, run_ends_view->length - 1); + if (last_run_end < (array_view->offset + array_view->length)) { + ArrowErrorSet( + error, "Last run end is %ld but it should >= %ld (offset: %ld, length: %ld)", + (long)last_run_end, (long)(array_view->offset + array_view->length), + (long)array_view->offset, (long)array_view->length); return EINVAL; } - last_run_end = run_end; - } - last_run_end = ArrowArrayViewGetIntUnsafe(run_ends_view, run_ends_view->length - 1); - if (last_run_end < (array_view->offset + array_view->length)) { - ArrowErrorSet(error, - "Last run end is %ld but it should >= %ld (offset: %ld, length: %ld)", - (long)last_run_end, (long)(array_view->offset + array_view->length), - (long)array_view->offset, (long)array_view->length); - return EINVAL; } }