@@ -990,14 +990,19 @@ static int ArrowArrayViewValidateDefault(struct ArrowArrayView* array_view,
990
990
case NANOARROW_TYPE_STRING :
991
991
case NANOARROW_TYPE_BINARY :
992
992
if (array_view -> buffer_views [1 ].size_bytes != 0 ) {
993
- first_offset = array_view -> buffer_views [1 ].data .as_int32 [0 ];
993
+ first_offset = array_view -> buffer_views [1 ].data .as_int32 [array_view -> offset ];
994
994
if (first_offset < 0 ) {
995
995
ArrowErrorSet (error , "Expected first offset >= 0 but found %" PRId64 ,
996
996
first_offset );
997
997
return EINVAL ;
998
998
}
999
999
1000
1000
last_offset = array_view -> buffer_views [1 ].data .as_int32 [offset_plus_length ];
1001
+ if (last_offset < 0 ) {
1002
+ ArrowErrorSet (error , "Expected last offset >= 0 but found %" PRId64 ,
1003
+ last_offset );
1004
+ return EINVAL ;
1005
+ }
1001
1006
1002
1007
// If the data buffer size is unknown, assign it; otherwise, check it
1003
1008
if (array_view -> buffer_views [2 ].size_bytes == -1 ) {
@@ -1021,14 +1026,19 @@ static int ArrowArrayViewValidateDefault(struct ArrowArrayView* array_view,
1021
1026
case NANOARROW_TYPE_LARGE_STRING :
1022
1027
case NANOARROW_TYPE_LARGE_BINARY :
1023
1028
if (array_view -> buffer_views [1 ].size_bytes != 0 ) {
1024
- first_offset = array_view -> buffer_views [1 ].data .as_int64 [0 ];
1029
+ first_offset = array_view -> buffer_views [1 ].data .as_int64 [array_view -> offset ];
1025
1030
if (first_offset < 0 ) {
1026
1031
ArrowErrorSet (error , "Expected first offset >= 0 but found %" PRId64 ,
1027
1032
first_offset );
1028
1033
return EINVAL ;
1029
1034
}
1030
1035
1031
1036
last_offset = array_view -> buffer_views [1 ].data .as_int64 [offset_plus_length ];
1037
+ if (last_offset < 0 ) {
1038
+ ArrowErrorSet (error , "Expected last offset >= 0 but found %" PRId64 ,
1039
+ last_offset );
1040
+ return EINVAL ;
1041
+ }
1032
1042
1033
1043
// If the data buffer size is unknown, assign it; otherwise, check it
1034
1044
if (array_view -> buffer_views [2 ].size_bytes == -1 ) {
@@ -1065,14 +1075,20 @@ static int ArrowArrayViewValidateDefault(struct ArrowArrayView* array_view,
1065
1075
case NANOARROW_TYPE_LIST :
1066
1076
case NANOARROW_TYPE_MAP :
1067
1077
if (array_view -> buffer_views [1 ].size_bytes != 0 ) {
1068
- first_offset = array_view -> buffer_views [1 ].data .as_int32 [0 ];
1078
+ first_offset = array_view -> buffer_views [1 ].data .as_int32 [array_view -> offset ];
1069
1079
if (first_offset < 0 ) {
1070
1080
ArrowErrorSet (error , "Expected first offset >= 0 but found %" PRId64 ,
1071
1081
first_offset );
1072
1082
return EINVAL ;
1073
1083
}
1074
1084
1075
1085
last_offset = array_view -> buffer_views [1 ].data .as_int32 [offset_plus_length ];
1086
+ if (last_offset < 0 ) {
1087
+ ArrowErrorSet (error , "Expected last offset >= 0 but found %" PRId64 ,
1088
+ last_offset );
1089
+ return EINVAL ;
1090
+ }
1091
+
1076
1092
if (array_view -> children [0 ]-> length < last_offset ) {
1077
1093
ArrowErrorSet (error ,
1078
1094
"Expected child of %s array to have length >= %" PRId64
@@ -1087,14 +1103,20 @@ static int ArrowArrayViewValidateDefault(struct ArrowArrayView* array_view,
1087
1103
1088
1104
case NANOARROW_TYPE_LARGE_LIST :
1089
1105
if (array_view -> buffer_views [1 ].size_bytes != 0 ) {
1090
- first_offset = array_view -> buffer_views [1 ].data .as_int64 [0 ];
1106
+ first_offset = array_view -> buffer_views [1 ].data .as_int64 [array_view -> offset ];
1091
1107
if (first_offset < 0 ) {
1092
1108
ArrowErrorSet (error , "Expected first offset >= 0 but found %" PRId64 ,
1093
1109
first_offset );
1094
1110
return EINVAL ;
1095
1111
}
1096
1112
1097
1113
last_offset = array_view -> buffer_views [1 ].data .as_int64 [offset_plus_length ];
1114
+ if (last_offset < 0 ) {
1115
+ ArrowErrorSet (error , "Expected last offset >= 0 but found %" PRId64 ,
1116
+ last_offset );
1117
+ return EINVAL ;
1118
+ }
1119
+
1098
1120
if (array_view -> children [0 ]-> length < last_offset ) {
1099
1121
ArrowErrorSet (error ,
1100
1122
"Expected child of large list array to have length >= %" PRId64
@@ -1249,13 +1271,24 @@ static int ArrowArrayViewValidateFull(struct ArrowArrayView* array_view,
1249
1271
struct ArrowError * error ) {
1250
1272
for (int i = 0 ; i < NANOARROW_MAX_FIXED_BUFFERS ; i ++ ) {
1251
1273
switch (array_view -> layout .buffer_type [i ]) {
1274
+ // Only validate the portion of the buffer that is strictly required,
1275
+ // which includes not validating the offset buffer of a zero-length array.
1252
1276
case NANOARROW_BUFFER_TYPE_DATA_OFFSET :
1277
+ if (array_view -> length == 0 ) {
1278
+ continue ;
1279
+ }
1253
1280
if (array_view -> layout .element_size_bits [i ] == 32 ) {
1254
- NANOARROW_RETURN_NOT_OK (
1255
- ArrowAssertIncreasingInt32 (array_view -> buffer_views [i ], error ));
1281
+ struct ArrowBufferView offset_minimal ;
1282
+ offset_minimal .data .as_int32 =
1283
+ array_view -> buffer_views [i ].data .as_int32 + array_view -> offset ;
1284
+ offset_minimal .size_bytes = (array_view -> length + 1 ) * sizeof (int32_t );
1285
+ NANOARROW_RETURN_NOT_OK (ArrowAssertIncreasingInt32 (offset_minimal , error ));
1256
1286
} else {
1257
- NANOARROW_RETURN_NOT_OK (
1258
- ArrowAssertIncreasingInt64 (array_view -> buffer_views [i ], error ));
1287
+ struct ArrowBufferView offset_minimal ;
1288
+ offset_minimal .data .as_int64 =
1289
+ array_view -> buffer_views [i ].data .as_int64 + array_view -> offset ;
1290
+ offset_minimal .size_bytes = (array_view -> length + 1 ) * sizeof (int64_t );
1291
+ NANOARROW_RETURN_NOT_OK (ArrowAssertIncreasingInt64 (offset_minimal , error ));
1259
1292
}
1260
1293
break ;
1261
1294
default :
0 commit comments