You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by us...@apache.org on 2023/05/19 14:34:59 UTC

[lucene] branch branch_9x updated: Wrap Query rewrite backwards layer with AccessController (#12308)

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

uschindler 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 4d1ed9ef9f6 Wrap Query rewrite backwards layer with AccessController (#12308)
4d1ed9ef9f6 is described below

commit 4d1ed9ef9f69ebd032538ff4324fe8f6c8356f9a
Author: Uwe Schindler <us...@apache.org>
AuthorDate: Fri May 19 16:34:54 2023 +0200

    Wrap Query rewrite backwards layer with AccessController (#12308)
---
 lucene/CHANGES.txt                                          |  8 ++++++--
 lucene/core/src/java/org/apache/lucene/search/Query.java    |  8 +++++++-
 .../core/src/java/org/apache/lucene/util/VirtualMethod.java | 13 +++++++++++--
 .../org/apache/lucene/search/TestKnnFloatVectorQuery.java   |  4 ++--
 4 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index 4d86f3e7f1c..4bd42ace6d0 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -8,8 +8,12 @@ http://s.apache.org/luceneversions
 API Changes
 ---------------------
 
-* GITHUB#11840: Query rewrite now takes an IndexSearcher instead of IndexReader to enable concurrent
-  rewriting. (Patrick Zhai, Ben Trent)
+* GITHUB#11840, GITHUB#12304: Query rewrite now takes an IndexSearcher instead of
+  IndexReader to enable concurrent rewriting. Please note: This is implemented in
+  a backwards compatible way. A query overriding any of both rewrite methods is
+  supported. To implement this backwards layer in Lucene 9.x the
+  RuntimePermission "accessDeclaredMembers" is needed in applications using
+  SecurityManager.  (Patrick Zhai, Ben Trent, Uwe Schindler)
 
 New Features
 ---------------------
diff --git a/lucene/core/src/java/org/apache/lucene/search/Query.java b/lucene/core/src/java/org/apache/lucene/search/Query.java
index 3f36b8729cc..560df421e6e 100644
--- a/lucene/core/src/java/org/apache/lucene/search/Query.java
+++ b/lucene/core/src/java/org/apache/lucene/search/Query.java
@@ -17,6 +17,8 @@
 package org.apache.lucene.search;
 
 import java.io.IOException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.util.VirtualMethod;
 
@@ -51,7 +53,11 @@ public abstract class Query {
   private static final VirtualMethod<Query> newMethod =
       new VirtualMethod<>(Query.class, "rewrite", IndexSearcher.class);
   private final boolean isDeprecatedRewriteMethodOverridden =
-      VirtualMethod.compareImplementationDistance(this.getClass(), oldMethod, newMethod) > 0;
+      AccessController.doPrivileged(
+          (PrivilegedAction<Boolean>)
+              () ->
+                  VirtualMethod.compareImplementationDistance(this.getClass(), oldMethod, newMethod)
+                      > 0);
 
   /**
    * Prints a query to a string, with <code>field</code> assumed to be the default field and
diff --git a/lucene/core/src/java/org/apache/lucene/util/VirtualMethod.java b/lucene/core/src/java/org/apache/lucene/util/VirtualMethod.java
index 05eef2a8661..a7c2a71cc1c 100644
--- a/lucene/core/src/java/org/apache/lucene/util/VirtualMethod.java
+++ b/lucene/core/src/java/org/apache/lucene/util/VirtualMethod.java
@@ -17,6 +17,8 @@
 package org.apache.lucene.util;
 
 import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
@@ -49,13 +51,20 @@ import java.util.Set;
  *
  * <pre class="prettyprint">
  *  final boolean isDeprecatedMethodOverridden =
- *   oldMethod.getImplementationDistance(this.getClass()) &gt; newMethod.getImplementationDistance(this.getClass());
+ *   AccessController.doPrivileged((PrivilegedAction&lt;Boolean&gt;) () -&gt;
+ *    (oldMethod.getImplementationDistance(this.getClass()) &gt; newMethod.getImplementationDistance(this.getClass())));
  *
  *  <em>// alternatively (more readable):</em>
  *  final boolean isDeprecatedMethodOverridden =
- *   VirtualMethod.compareImplementationDistance(this.getClass(), oldMethod, newMethod) &gt; 0
+ *   AccessController.doPrivileged((PrivilegedAction&lt;Boolean&gt;) () -&gt;
+ *    VirtualMethod.compareImplementationDistance(this.getClass(), oldMethod, newMethod) &gt; 0);
  * </pre>
  *
+ * <p>It is important to use {@link AccessController#doPrivileged(PrivilegedAction)} for the actual
+ * call to get the implementation distance because the subclass may be in a different package. The
+ * static constructors do not need to use {@code AccessController} because it just initializes our
+ * own method reference. The caller should have access to all declared members in its own class.
+ *
  * <p>{@link #getImplementationDistance} returns the distance of the subclass that overrides this
  * method. The one with the larger distance should be used preferable. This way also more
  * complicated method rename scenarios can be handled (think of 2.9 {@code TokenStream}
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestKnnFloatVectorQuery.java b/lucene/core/src/test/org/apache/lucene/search/TestKnnFloatVectorQuery.java
index 684e260f12b..8467ac506ae 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestKnnFloatVectorQuery.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestKnnFloatVectorQuery.java
@@ -95,7 +95,7 @@ public class TestKnnFloatVectorQuery extends BaseKnnVectorQueryTestCase {
         assertEquals(1, reader.leaves().size());
         IndexSearcher searcher = new IndexSearcher(reader);
         AbstractKnnVectorQuery query = getKnnVectorQuery("field", new float[] {1, 0}, 2);
-        Query rewritten = query.rewrite(reader);
+        Query rewritten = query.rewrite(searcher);
         Weight weight = searcher.createWeight(rewritten, ScoreMode.COMPLETE, 1);
         Scorer scorer = weight.scorer(reader.leaves().get(0));
 
@@ -126,7 +126,7 @@ public class TestKnnFloatVectorQuery extends BaseKnnVectorQueryTestCase {
         IndexSearcher searcher = new IndexSearcher(reader);
         AbstractKnnVectorQuery query =
             getKnnVectorQuery("field", VectorUtil.l2normalize(new float[] {2, 3}), 3);
-        Query rewritten = query.rewrite(reader);
+        Query rewritten = query.rewrite(searcher);
         Weight weight = searcher.createWeight(rewritten, ScoreMode.COMPLETE, 1);
         Scorer scorer = weight.scorer(reader.leaves().get(0));