Repository: rapidsai/cudf (language: python)

Issue:
[BUG] cudaErrorIllegalAddress while copying values to nullable string series
**Describe the bug**
`cudaErrorIllegalAddress` while copying values to nullable string series. This is a regression from the behavior in `24.02`.

**Steps/Code to reproduce bug**
```
cudf.Series(['a', None])[1:2] = ['b'] # cudaErrorIllegalAddress
```
However, the following _does_ work:
```
cudf.Series(['a', 'b'])[1:2] = ['c'] # works
```
as does:
```
cudf.Series([0, 1])[1:2] = [2] # works
```

**Expected behavior**
expected the value to be copied to the specified range without causing `cudaErrorIllegalAddress`

**Environment overview (please complete the following information)**
 - Environment location: Docker
 - Method of cuDF install: conda

**Additional context**
Morpheus depends heavily on this behavior.



Discussion / hints:
Also this works
```
cudf.Series(['a', None])[1:2] = 'b'
```
Broken down just to make sure:
```
>>> import cudf
>>> s = cudf.Series(['a', None])
>>> s[1:2] = 'b'
>>> s
0    a
1    b
dtype: object
```

Fix patch:
diff --git a/cpp/src/strings/copying/copy_range.cu b/cpp/src/strings/copying/copy_range.cu
index 9f8c47602f8..2434de1795e 100644
--- a/cpp/src/strings/copying/copy_range.cu
+++ b/cpp/src/strings/copying/copy_range.cu
@@ -40,20 +40,14 @@ struct compute_element_size {
   size_type source_begin;
   size_type target_begin;
   size_type target_end;
-  bool source_has_nulls;
-  bool target_has_nulls;
 
   __device__ cudf::size_type operator()(cudf::size_type idx)
   {
     if (idx >= target_begin && idx < target_end) {
       auto const str_idx = source_begin + (idx - target_begin);
-      return source_has_nulls && d_source.is_null_nocheck(str_idx)
-               ? 0
-               : d_source.element<string_view>(str_idx).size_bytes();
+      return d_source.is_null(str_idx) ? 0 : d_source.element<string_view>(str_idx).size_bytes();
     } else {
-      return target_has_nulls && d_target.is_null_nocheck(idx)
-               ? 0
-               : d_target.element<string_view>(idx).size_bytes();
+      return d_target.is_null(idx) ? 0 : d_target.element<string_view>(idx).size_bytes();
     }
   }
 };
@@ -97,20 +91,9 @@ std::unique_ptr<column> copy_range(strings_column_view const& source,
       mr);
   }();
 
-  auto [check_source, check_target] = [target, null_count = null_count] {
-    // check validities for both source & target
-    if (target.has_nulls()) { return std::make_pair(true, true); }
-    // check validities for source only
-    if (null_count > 0) { return std::make_pair(true, false); }
-    // no need to check validities
-    return std::make_pair(false, false);
-  }();
-
   // create offsets
   auto sizes_begin = cudf::detail::make_counting_transform_iterator(
-    0,
-    compute_element_size{
-      d_source, d_target, source_begin, target_begin, target_end, check_source, check_target});
+    0, compute_element_size{d_source, d_target, source_begin, target_begin, target_end});
   auto [offsets_column, chars_bytes] = cudf::strings::detail::make_offsets_child_column(
     sizes_begin, sizes_begin + target.size(), stream, mr);
   auto d_offsets = cudf::detail::offsetalator_factory::make_input_iterator(offsets_column->view());


Test patch:
diff --git a/cpp/tests/copying/copy_range_tests.cpp b/cpp/tests/copying/copy_range_tests.cpp
index 223946ddcee..25d93da277b 100644
--- a/cpp/tests/copying/copy_range_tests.cpp
+++ b/cpp/tests/copying/copy_range_tests.cpp
@@ -232,6 +232,16 @@ TEST_F(CopyRangeTestFixture, CopyWithNullsString)
   CUDF_TEST_EXPECT_COLUMNS_EQUAL(*p_ret, expected);
 }
 
+TEST_F(CopyRangeTestFixture, CopyWithTargetNullsString)
+{
+  auto target =
+    cudf::test::strings_column_wrapper({"a", "b", "", "d", "", "é"}, {1, 1, 0, 1, 1, 1});
+  auto source   = cudf::test::strings_column_wrapper({"A", "B", "C", "D", "E", "F"});
+  auto result   = cudf::copy_range(source, target, 1, 5, 1);
+  auto expected = cudf::test::strings_column_wrapper({"a", "B", "C", "D", "E", "é"});
+  CUDF_TEST_EXPECT_COLUMNS_EQUIVALENT(result->view(), expected);
+}
+
 TEST_F(CopyRangeTestFixture, CopyNoNullsString)
 {
   cudf::size_type size{100};