You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by gs...@apache.org on 2023/03/01 02:41:42 UTC

[lucene] branch branch_9x updated: Clone the BytesRef[] values in KeywordField#newSetQuery (#12158)

This is an automated email from the ASF dual-hosted git repository.

gsmiller pushed a commit to branch branch_9x
in repository https://gitbox.apache.org/repos/asf/lucene.git


The following commit(s) were added to refs/heads/branch_9x by this push:
     new 748ced5d5ef Clone the BytesRef[] values in KeywordField#newSetQuery (#12158)
748ced5d5ef is described below

commit 748ced5d5ef19a02cbc886e3f41184ef4c698f18
Author: Greg Miller <gs...@gmail.com>
AuthorDate: Tue Feb 28 18:30:38 2023 -0800

    Clone the BytesRef[] values in KeywordField#newSetQuery (#12158)
---
 lucene/CHANGES.txt                                         |  3 ++-
 .../src/java/org/apache/lucene/document/KeywordField.java  |  2 +-
 .../apache/lucene/document/SortedSetDocValuesSetQuery.java |  6 ++++++
 .../test/org/apache/lucene/document/TestKeywordField.java  | 14 ++++++++++++++
 4 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index 85455e6aa2b..8539f0e8af5 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -47,7 +47,8 @@ Optimizations
 
 Bug Fixes
 ---------------------
-(No changes)
+
+* GITHUB#12158: KeywordField#newSetQuery should clone input BytesRef[] to avoid modifying provided array. (Greg Miller)
 
 Build
 ---------------------
diff --git a/lucene/core/src/java/org/apache/lucene/document/KeywordField.java b/lucene/core/src/java/org/apache/lucene/document/KeywordField.java
index 6ff0ecaf4dd..a8abd83ea29 100644
--- a/lucene/core/src/java/org/apache/lucene/document/KeywordField.java
+++ b/lucene/core/src/java/org/apache/lucene/document/KeywordField.java
@@ -174,7 +174,7 @@ public class KeywordField extends Field {
     Objects.requireNonNull(field, "field must not be null");
     Objects.requireNonNull(values, "values must not be null");
     return new IndexOrDocValuesQuery(
-        new TermInSetQuery(field, values), new SortedSetDocValuesSetQuery(field, values));
+        new TermInSetQuery(field, values), new SortedSetDocValuesSetQuery(field, values.clone()));
   }
 
   /**
diff --git a/lucene/core/src/java/org/apache/lucene/document/SortedSetDocValuesSetQuery.java b/lucene/core/src/java/org/apache/lucene/document/SortedSetDocValuesSetQuery.java
index a742bc663bb..3f0c37cc5ac 100644
--- a/lucene/core/src/java/org/apache/lucene/document/SortedSetDocValuesSetQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/document/SortedSetDocValuesSetQuery.java
@@ -51,6 +51,12 @@ final class SortedSetDocValuesSetQuery extends Query implements Accountable {
   private final PrefixCodedTerms termData;
   private final int termDataHashCode; // cached hashcode of termData
 
+  /**
+   * Sole constructor. Note that {@code terms} will be sorted in-place, so callers should clone the
+   * array prior to calling if they care to preserve original ordering. This decision was made since
+   * this is an internal implementation (pkg-private class) and not expected to be used directly by
+   * users.
+   */
   SortedSetDocValuesSetQuery(String field, BytesRef terms[]) {
     this.field = Objects.requireNonNull(field);
     Objects.requireNonNull(terms);
diff --git a/lucene/core/src/test/org/apache/lucene/document/TestKeywordField.java b/lucene/core/src/test/org/apache/lucene/document/TestKeywordField.java
index 41ffd13b9ea..9654a04aa24 100644
--- a/lucene/core/src/test/org/apache/lucene/document/TestKeywordField.java
+++ b/lucene/core/src/test/org/apache/lucene/document/TestKeywordField.java
@@ -26,6 +26,7 @@ import org.apache.lucene.index.SortedSetDocValues;
 import org.apache.lucene.index.TermsEnum;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.tests.util.LuceneTestCase;
+import org.apache.lucene.tests.util.TestUtil;
 import org.apache.lucene.util.BytesRef;
 
 public class TestKeywordField extends LuceneTestCase {
@@ -123,4 +124,17 @@ public class TestKeywordField extends LuceneTestCase {
     reader.close();
     dir.close();
   }
+
+  public void testValueClone() {
+    BytesRef[] values = new BytesRef[100];
+    for (int i = 0; i < 100; i++) {
+      String s = TestUtil.randomSimpleString(random(), 10, 20);
+      values[i] = new BytesRef(s);
+    }
+
+    // Make sure we don't modify the input values array.
+    BytesRef[] expected = values.clone();
+    KeywordField.newSetQuery("f", values);
+    assertArrayEquals(expected, values);
+  }
 }