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

Aias00 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu.git


The following commit(s) were added to refs/heads/master by this push:
     new dc46e1087e fix(sdk): quote path-variable replacement values in the 
Spring SDK (#7712) (#7729)
dc46e1087e is described below

commit dc46e1087e06d124f0870554a4b0002a3536fc63
Author: konlue <[email protected]>
AuthorDate: Mon Oct 19 09:33:52 2026 +0800

    fix(sdk): quote path-variable replacement values in the Spring SDK (#7712) 
(#7729)
---
 .../annotation/PathVariableParameterProcessor.java |  5 ++--
 .../PathVariableParameterProcessorTest.java        | 31 ++++++++++++++++++++++
 2 files changed, 34 insertions(+), 2 deletions(-)

diff --git 
a/shenyu-sdk/shenyu-sdk-spring/src/main/java/org/apache/shenyu/sdk/spring/annotation/PathVariableParameterProcessor.java
 
b/shenyu-sdk/shenyu-sdk-spring/src/main/java/org/apache/shenyu/sdk/spring/annotation/PathVariableParameterProcessor.java
index 28e5c21479..04887ee948 100644
--- 
a/shenyu-sdk/shenyu-sdk-spring/src/main/java/org/apache/shenyu/sdk/spring/annotation/PathVariableParameterProcessor.java
+++ 
b/shenyu-sdk/shenyu-sdk-spring/src/main/java/org/apache/shenyu/sdk/spring/annotation/PathVariableParameterProcessor.java
@@ -27,6 +27,7 @@ import org.springframework.web.bind.annotation.PathVariable;
 
 import java.lang.annotation.Annotation;
 import java.util.Map;
+import java.util.regex.Matcher;
 
 /**
  * {@link PathVariable} parameter processor.
@@ -51,7 +52,7 @@ public class PathVariableParameterProcessor implements 
AnnotatedParameterProcess
             String varName = "{" + name + "}";
             String varNameRegex = "\\{" + name + "\\}";
             if (shenyuRequest.getUrl().contains(varName)) {
-                
shenyuRequest.setUrl(RegExUtils.replaceAll(shenyuRequest.getUrl(), 
varNameRegex, String.valueOf(arg)));
+                
shenyuRequest.setUrl(RegExUtils.replaceAll(shenyuRequest.getUrl(), 
varNameRegex, Matcher.quoteReplacement(String.valueOf(arg))));
             }
             return true;
         }
@@ -63,7 +64,7 @@ public class PathVariableParameterProcessor implements 
AnnotatedParameterProcess
                 String varName = "{" + key + "}";
                 String varNameRegex = "\\{" + key + "\\}";
                 if (url.contains(varName)) {
-                    url = RegExUtils.replaceAll(url, varNameRegex, (String) 
value);
+                    url = RegExUtils.replaceAll(url, varNameRegex, 
Matcher.quoteReplacement((String) value));
                 }
             }
         }
diff --git 
a/shenyu-sdk/shenyu-sdk-spring/src/test/java/org/apache/shenyu/sdk/spring/annotation/PathVariableParameterProcessorTest.java
 
b/shenyu-sdk/shenyu-sdk-spring/src/test/java/org/apache/shenyu/sdk/spring/annotation/PathVariableParameterProcessorTest.java
index 30a1846813..99adb4cf23 100644
--- 
a/shenyu-sdk/shenyu-sdk-spring/src/test/java/org/apache/shenyu/sdk/spring/annotation/PathVariableParameterProcessorTest.java
+++ 
b/shenyu-sdk/shenyu-sdk-spring/src/test/java/org/apache/shenyu/sdk/spring/annotation/PathVariableParameterProcessorTest.java
@@ -107,6 +107,37 @@ public class PathVariableParameterProcessorTest {
         assertTrue(request.getUrl().equals("/url/a/b/id/idValue") || 
request.getUrl().contains("nameValue") || 
request.getUrl().contains("typeValue"), "path value resolve error");
     }
 
+    @ParameterizedTest
+    
@MethodSource("org.apache.shenyu.sdk.spring.annotation.PathVariableParameterProcessorTest#templateStream")
+    public void processArgumentStringWithRegexReplacementSyntaxTest(final 
RequestTemplate template) {
+        this.request = ShenyuRequest.create(ShenyuRequest.HttpMethod.POST, 
template.getUrl() + template.getPath(), Maps.newHashMap(), "", "test", 
template);
+        final PathVariable path = spy(PathVariable.class);
+        when(path.value()).thenReturn("id");
+
+        // "$1" and backslashes in a replacement string are regex syntax 
unless quoted
+        processor.processArgument(request, path, "$1");
+        assertTrue(request.getUrl().contains("/$1"), "dollar sign value must 
be treated literally");
+
+        final RequestTemplate backslashTemplate = 
RequestTemplate.from(template);
+        this.request = ShenyuRequest.create(ShenyuRequest.HttpMethod.POST, 
backslashTemplate.getUrl() + backslashTemplate.getPath(), Maps.newHashMap(), 
"", "test", backslashTemplate);
+        processor.processArgument(request, path, "a\\b");
+        assertTrue(request.getUrl().contains("/a\\b"), "backslash value must 
not be swallowed");
+    }
+
+    @ParameterizedTest
+    
@MethodSource("org.apache.shenyu.sdk.spring.annotation.PathVariableParameterProcessorTest#templateStream")
+    public void processArgumentMapWithRegexReplacementSyntaxTest(final 
RequestTemplate template) {
+        this.request = ShenyuRequest.create(ShenyuRequest.HttpMethod.POST, 
template.getUrl() + template.getPath(), Maps.newHashMap(), "", "test", 
template);
+        Map<String, String> pathParam = Maps.newHashMap();
+        pathParam.put("id", "$1");
+
+        final PathVariable path = spy(PathVariable.class);
+        when(path.value()).thenReturn("");
+        processor.processArgument(request, path, pathParam);
+
+        assertTrue(request.getUrl().contains("/$1"), "dollar sign map value 
must be treated literally");
+    }
+
     /**
      * template argument source.
      * @return Stream&lt;RequestTemplate&gt;

Reply via email to