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 bb05e0d6ad  fix: fix path-variable off-by-one and guard placeholder 
substitution in rewrite plugin (#6882) (#6951)
bb05e0d6ad is described below

commit bb05e0d6ad94f599f523421ed1bce4067aa4d518
Author: Southern <[email protected]>
AuthorDate: Wed Sep 30 09:56:13 2026 +0800

     fix: fix path-variable off-by-one and guard placeholder substitution in 
rewrite plugin (#6882) (#6951)
    
    1. Remove the "+1" when extracting the path-variable value from the URI, so 
the
         first character of the value is no longer truncated
         (e.g. /http/findById/123 was rewritten to .../23, now .../123).
     2. Only enter the placeholder-substitution branch when the regex also 
contains
         '{', so a replace template with '{' combined with a plain regex no 
longer
         throws StringIndexOutOfBoundsException (regex.substring(-1)) that 
returned 500.
    
    Co-authored-by: aias00 <[email protected]>
    Co-authored-by: xiaoyu <[email protected]>
---
 .../shenyu/plugin/rewrite/RewritePlugin.java       |  2 +-
 .../shenyu/plugin/rewrite/RewritePluginTest.java   | 26 ++++++++++++++++++++++
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git 
a/shenyu-plugin/shenyu-plugin-rewrite/src/main/java/org/apache/shenyu/plugin/rewrite/RewritePlugin.java
 
b/shenyu-plugin/shenyu-plugin-rewrite/src/main/java/org/apache/shenyu/plugin/rewrite/RewritePlugin.java
index 486764f1e7..398443bd0e 100644
--- 
a/shenyu-plugin/shenyu-plugin-rewrite/src/main/java/org/apache/shenyu/plugin/rewrite/RewritePlugin.java
+++ 
b/shenyu-plugin/shenyu-plugin-rewrite/src/main/java/org/apache/shenyu/plugin/rewrite/RewritePlugin.java
@@ -76,7 +76,7 @@ public class RewritePlugin extends AbstractShenyuPlugin {
                 && ThreadLocalRandom.current().nextInt(100) < percentage) {
             rewriteUri = rewriteHandle.getReplace().contains("{") && 
rewriteHandle.getRegex().contains("{")
                     ? PathMatchUtils.replaceAll(rewriteHandle.getReplace(), 
rewriteHandle.getRegex().substring(rewriteHandle.getRegex().indexOf("{")),
-                            
rewriteUri.substring(rewriteHandle.getRegex().indexOf("{")))
+                    
rewriteUri.substring(rewriteHandle.getRegex().indexOf("{")))
                     : rewriteUri.replaceAll(rewriteHandle.getRegex(), 
rewriteHandle.getReplace());
             Map<String, Object> attributes = exchange.getAttributes();
             if 
(Optional.ofNullable(rewriteHandle.getRewriteMetaData()).orElse(false)) {
diff --git 
a/shenyu-plugin/shenyu-plugin-rewrite/src/test/java/org/apache/shenyu/plugin/rewrite/RewritePluginTest.java
 
b/shenyu-plugin/shenyu-plugin-rewrite/src/test/java/org/apache/shenyu/plugin/rewrite/RewritePluginTest.java
index 3d9f75a3dc..5b5ec80bfc 100644
--- 
a/shenyu-plugin/shenyu-plugin-rewrite/src/test/java/org/apache/shenyu/plugin/rewrite/RewritePluginTest.java
+++ 
b/shenyu-plugin/shenyu-plugin-rewrite/src/test/java/org/apache/shenyu/plugin/rewrite/RewritePluginTest.java
@@ -88,6 +88,32 @@ public final class RewritePluginTest {
         assertEquals("/shenyu/rewrite", 
exchange.getAttributes().get(Constants.REWRITE_URI));
     }
 
+    @Test
+    public void shouldRewritePathVariableWithCompleteValue() {
+        RuleData data = new RuleData();
+        
data.setHandle("{\"regex\":\"/shenyu/{id}\",\"replace\":\"/shenyu/{id}\"}");
+        RewriteHandle rewriteHandle = 
GsonUtils.getGson().fromJson(data.getHandle(), RewriteHandle.class);
+        
RewritePluginDataHandler.CACHED_HANDLE.get().cachedHandle(CacheKeyUtils.INST.getKey(data),
 rewriteHandle);
+        ServerWebExchange rewriteExchange = 
MockServerWebExchange.from(MockServerHttpRequest.get("/shenyu/123").build());
+        rewriteExchange.getAttributes().put(Constants.CONTEXT, new 
ShenyuContext());
+        when(chain.execute(rewriteExchange)).thenReturn(Mono.empty());
+        SelectorData selectorData = mock(SelectorData.class);
+        StepVerifier.create(rewritePlugin.doExecute(rewriteExchange, chain, 
selectorData, data)).expectSubscription().verifyComplete();
+        assertEquals("/shenyu/123", 
rewriteExchange.getAttributes().get(Constants.REWRITE_URI));
+    }
+
+    @Test
+    public void shouldNotThrowWhenOnlyReplaceContainsPlaceholder() {
+        RuleData data = new RuleData();
+        data.setHandle("{\"regex\":\"/shenyu/.*\",\"replace\":\"/new/{id}\"}");
+        RewriteHandle rewriteHandle = 
GsonUtils.getGson().fromJson(data.getHandle(), RewriteHandle.class);
+        
RewritePluginDataHandler.CACHED_HANDLE.get().cachedHandle(CacheKeyUtils.INST.getKey(data),
 rewriteHandle);
+        when(chain.execute(exchange)).thenReturn(Mono.empty());
+        SelectorData selectorData = mock(SelectorData.class);
+        StepVerifier.create(rewritePlugin.doExecute(exchange, chain, 
selectorData, data)).expectSubscription().verifyComplete();
+        assertEquals("/new/{id}", 
exchange.getAttributes().get(Constants.REWRITE_URI));
+    }
+
     @Test
     public void testSkip() {
         final boolean result = rewritePlugin.skip(exchange);

Reply via email to