Copilot commented on code in PR #51000:
URL: https://github.com/apache/arrow/pull/51000#discussion_r3857330502


##########
cpp/src/arrow/compute/kernels/scalar_validity.cc:
##########
@@ -101,6 +103,60 @@ static void SetNanBits(const ArraySpan& arr, uint8_t* 
out_bitmap, int64_t out_of
   }
 }
 
+template <typename IndexType, typename ValueType>
+static void SetNanBitsDictionary(const ArraySpan& arr, const ArraySpan& 
dict_span,
+                                 uint8_t* out_bitmap, int64_t out_offset) {
+  const IndexType* indices = arr.GetValues<IndexType>(1);
+  const ValueType* dict_values = dict_span.GetValues<ValueType>(1);
+  for (int64_t i = 0; i < arr.length; ++i) {
+    auto dict_index = indices[i];
+    bool is_nan;
+    if constexpr (std::is_same_v<ValueType, uint16_t>) {
+      is_nan = Float16::FromBits(dict_values[dict_index]).is_nan();
+    } else {
+      is_nan = std::isnan(dict_values[dict_index]);
+    }
+    if (is_nan) {
+      bit_util::SetBit(out_bitmap, i + out_offset);
+    }
+  }
+}
+
+template <typename ValueType>
+static void DispatchIndexType(const ArraySpan& arr, const ArraySpan& dict_span,
+                              uint8_t* out_bitmap, int64_t out_offset) {
+  const auto& dict_type = checked_cast<const DictionaryType&>(*arr.type);
+  switch (dict_type.index_type()->id()) {
+    case Type::INT8:
+      SetNanBitsDictionary<int8_t, ValueType>(arr, dict_span, out_bitmap, 
out_offset);
+      break;
+    case Type::INT16:
+      SetNanBitsDictionary<int16_t, ValueType>(arr, dict_span, out_bitmap, 
out_offset);
+      break;
+    case Type::INT32:
+      SetNanBitsDictionary<int32_t, ValueType>(arr, dict_span, out_bitmap, 
out_offset);
+      break;
+    case Type::INT64:
+      SetNanBitsDictionary<int64_t, ValueType>(arr, dict_span, out_bitmap, 
out_offset);
+      break;
+    case Type::UINT8:
+      SetNanBitsDictionary<uint8_t, ValueType>(arr, dict_span, out_bitmap, 
out_offset);
+      break;
+    case Type::UINT16:
+      SetNanBitsDictionary<uint16_t, ValueType>(arr, dict_span, out_bitmap, 
out_offset);
+      break;
+    case Type::UINT32:
+      SetNanBitsDictionary<uint32_t, ValueType>(arr, dict_span, out_bitmap, 
out_offset);
+      break;
+    case Type::UINT64:
+      SetNanBitsDictionary<uint64_t, ValueType>(arr, dict_span, out_bitmap, 
out_offset);
+      break;
+    default:
+      SetNanBitsDictionary<int32_t, ValueType>(arr, dict_span, out_bitmap, 
out_offset);
+      break;

Review Comment:
   The default branch in DispatchIndexType falls back to treating the indices 
buffer as int32, which would misinterpret memory (and potentially read 
out-of-bounds) if an unexpected index type id ever reaches this code path. 
Since all supported dictionary index types are explicitly handled, the default 
should be unreachable and fail fast instead of silently choosing a width.



##########
cpp/src/arrow/compute/kernels/scalar_validity.cc:
##########
@@ -101,6 +103,60 @@ static void SetNanBits(const ArraySpan& arr, uint8_t* 
out_bitmap, int64_t out_of
   }
 }
 
+template <typename IndexType, typename ValueType>
+static void SetNanBitsDictionary(const ArraySpan& arr, const ArraySpan& 
dict_span,
+                                 uint8_t* out_bitmap, int64_t out_offset) {
+  const IndexType* indices = arr.GetValues<IndexType>(1);
+  const ValueType* dict_values = dict_span.GetValues<ValueType>(1);
+  for (int64_t i = 0; i < arr.length; ++i) {
+    auto dict_index = indices[i];
+    bool is_nan;
+    if constexpr (std::is_same_v<ValueType, uint16_t>) {
+      is_nan = Float16::FromBits(dict_values[dict_index]).is_nan();
+    } else {
+      is_nan = std::isnan(dict_values[dict_index]);
+    }

Review Comment:
   SetNanBitsDictionary dereferences `dict_values[dict_index]` even when the 
corresponding index slot is null (and the indices buffer can contain 
uninitialized / arbitrary values for nulls). This can lead to out-of-bounds 
reads or crashes when `arr` has nulls. Skip NaN checks for null index slots 
(and ideally guard against negative / out-of-range indices) before indexing 
into the dictionary.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to