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

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


The following commit(s) were added to refs/heads/branch_9x by this push:
     new cabeb77ef47 SOLR-17255: Fix bugs in SolrParams.toLocalParamsString()
cabeb77ef47 is described below

commit cabeb77ef47380fbeee60f57dd4a75e39fa2d254
Author: Chris Hostetter <[email protected]>
AuthorDate: Tue Jun 18 14:40:52 2024 -0700

    SOLR-17255: Fix bugs in SolrParams.toLocalParamsString()
    
    (cherry picked from commit 0c2b1a6dd615b4fc160ea2e715031c057ba3df5e)
---
 solr/CHANGES.txt                                   |  2 ++
 .../apache/solr/client/solrj/util/ClientUtils.java | 10 +++---
 .../org/apache/solr/common/params/SolrParams.java  | 13 ++++---
 .../apache/solr/common/params/SolrParamTest.java   | 42 ++++++++++++++++++++++
 4 files changed, 59 insertions(+), 8 deletions(-)

diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 2fe4b04a7f5..eefa86795dd 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -69,6 +69,8 @@ Bug Fixes
   to the `<updateLog>` element in `solrconfig.xml`, which has long been 
silently ignored, will now be
   respected (Michael Gibney, David Smiley)
 
+* SOLR-17255: Fix bugs in SolrParams.toLocalParamsString() (hossman)
+
 Dependency Upgrades
 ---------------------
 (No changes)
diff --git 
a/solr/solrj/src/java/org/apache/solr/client/solrj/util/ClientUtils.java 
b/solr/solrj/src/java/org/apache/solr/client/solrj/util/ClientUtils.java
index 16f27410400..d0cc138a8ad 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/util/ClientUtils.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/util/ClientUtils.java
@@ -246,14 +246,16 @@ public class ClientUtils {
   }
 
   /**
-   * Returns the value encoded properly so it can be appended after a
+   * Returns the (literal) value encoded properly so it can be appended after 
a <code>name=</code>
+   * local-param key.
    *
-   * <pre>name=</pre>
-   *
-   * local-param.
+   * <p>NOTE: This method assumes <code>$</code> is a literal character that 
must be quoted. (It
+   * does not assume strings starting <code>$</code> should be treated as 
param refrenes)
    */
   public static String encodeLocalParamVal(String val) {
     int len = val.length();
+    if (0 == len) return "''"; // quoted empty string
+
     int i = 0;
     if (len > 0 && val.charAt(0) != '$') {
       for (; i < len; i++) {
diff --git a/solr/solrj/src/java/org/apache/solr/common/params/SolrParams.java 
b/solr/solrj/src/java/org/apache/solr/common/params/SolrParams.java
index 2d2fbe9d837..a06933ed099 100644
--- a/solr/solrj/src/java/org/apache/solr/common/params/SolrParams.java
+++ b/solr/solrj/src/java/org/apache/solr/common/params/SolrParams.java
@@ -569,9 +569,9 @@ public abstract class SolrParams
   }
 
   /**
-   * Generates a local-params string of the form
-   *
-   * <pre>{! name=value name2=value2}</pre>
+   * Generates a local-params string of the form <code>{! name=value 
name2=value2}</code>,
+   * Protecting (with out any quoting or escaping) any values that start with 
<code>$</code> (param
+   * references).
    */
   public String toLocalParamsString() {
     final StringBuilder sb = new StringBuilder(128);
@@ -583,7 +583,12 @@ public abstract class SolrParams
         sb.append(' '); // do so even the first time; why not.
         sb.append(name); // no escaping for name; it must follow "Java 
Identifier" rules.
         sb.append('=');
-        sb.append(ClientUtils.encodeLocalParamVal(val));
+        if (val.startsWith("$")) {
+          // maintain literal param ref...
+          sb.append(val);
+        } else {
+          sb.append(ClientUtils.encodeLocalParamVal(val));
+        }
       }
     }
     sb.append('}');
diff --git 
a/solr/solrj/src/test/org/apache/solr/common/params/SolrParamTest.java 
b/solr/solrj/src/test/org/apache/solr/common/params/SolrParamTest.java
index 6ae0e3edd4f..84b8ea1894c 100644
--- a/solr/solrj/src/test/org/apache/solr/common/params/SolrParamTest.java
+++ b/solr/solrj/src/test/org/apache/solr/common/params/SolrParamTest.java
@@ -16,6 +16,8 @@
  */
 package org.apache.solr.common.params;
 
+import static org.apache.solr.SolrTestCaseJ4.params;
+
 import java.lang.invoke.MethodHandles;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -24,6 +26,7 @@ import java.util.List;
 import java.util.Map;
 import org.apache.solr.SolrTestCase;
 import org.apache.solr.common.SolrException;
+import org.apache.solr.search.QueryParsing;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -31,6 +34,45 @@ import org.slf4j.LoggerFactory;
 public class SolrParamTest extends SolrTestCase {
   private static final Logger log = 
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
+  public void testLocalParamRoundTripParsing() throws Exception {
+    final SolrParams in =
+        params(
+            "simple", "xxx",
+            "blank", "",
+            "space", "x y z",
+            "lead_space", " x",
+            "curly", "x}y",
+            "quote", "x'y",
+            "quoted", "'x y'",
+            "d_quote", "x\"y",
+            "d_quoted", "\"x y\"",
+            "dollar", "x$y",
+            "multi", "x",
+            "multi", "y y",
+            "v", "$ref");
+    final String toStr = in.toLocalParamsString();
+    final SolrParams out = QueryParsing.getLocalParams(toStr, params("ref", 
"ref value"));
+
+    assertEquals("xxx", out.get("simple"));
+    assertEquals("", out.get("blank"));
+    assertEquals("x y z", out.get("space"));
+    assertEquals(" x", out.get("lead_space"));
+    assertEquals("x}y", out.get("curly"));
+    assertEquals("x'y", out.get("quote"));
+    assertEquals("'x y'", out.get("quoted"));
+    assertEquals("x\"y", out.get("d_quote"));
+    assertEquals("\"x y\"", out.get("d_quoted"));
+    assertEquals("x$y", out.get("dollar"));
+
+    assertArrayEquals(new String[] {"x", "y y"}, out.getParams("multi"));
+    // first one should win...
+    assertEquals("x", out.get("multi"));
+
+    assertEquals("ref value", out.get("v"));
+
+    assertIterSize(toStr, 12, out);
+  }
+
   public void testParamIterators() {
 
     ModifiableSolrParams aaa = new ModifiableSolrParams();

Reply via email to