You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by je...@apache.org on 2018/09/06 01:57:47 UTC

[incubator-dubbo] branch 2.6.x updated: fix telnet invoke NPE #2218 (#2273) (#2453)

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

jerrick pushed a commit to branch 2.6.x
in repository https://gitbox.apache.org/repos/asf/incubator-dubbo.git


The following commit(s) were added to refs/heads/2.6.x by this push:
     new 52e9290  fix telnet invoke NPE #2218 (#2273) (#2453)
52e9290 is described below

commit 52e9290d12162d1d483b21070729e7f2c6a04733
Author: Jerrick Zhu <di...@gmail.com>
AuthorDate: Thu Sep 6 09:57:44 2018 +0800

    fix telnet invoke NPE #2218 (#2273) (#2453)
---
 .../protocol/dubbo/telnet/InvokeTelnetHandler.java | 13 ++++++++
 .../rpc/protocol/dubbo/support/DemoService.java    |  2 ++
 .../protocol/dubbo/support/DemoServiceImpl.java    |  5 +++
 .../dubbo/telnet/InvokerTelnetHandlerTest.java     | 36 ++++++++++++++++++++++
 4 files changed, 56 insertions(+)

diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/com/alibaba/dubbo/rpc/protocol/dubbo/telnet/InvokeTelnetHandler.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/com/alibaba/dubbo/rpc/protocol/dubbo/telnet/InvokeTelnetHandler.java
index 47f11f5..59733dc 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/com/alibaba/dubbo/rpc/protocol/dubbo/telnet/InvokeTelnetHandler.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/com/alibaba/dubbo/rpc/protocol/dubbo/telnet/InvokeTelnetHandler.java
@@ -60,6 +60,19 @@ public class InvokeTelnetHandler implements TelnetHandler {
         for (int i = 0; i < types.length; i++) {
             Class<?> type = types[i];
             Object arg = args.get(i);
+
+            if (arg == null) {
+                // if the type is primitive, the method to invoke will cause NullPointerException definitely
+                // so we can offer a specified error message to the invoker in advance and avoid unnecessary invoking
+                if (type.isPrimitive()) {
+                    throw new NullPointerException(String.format(
+                            "The type of No.%d parameter is primitive(%s), but the value passed is null.", i + 1, type.getName()));
+                }
+
+                // if the type is not primitive, we choose to believe what the invoker want is a null value
+                continue;
+            }
+
             if (ReflectUtils.isPrimitive(arg.getClass())) {
                 if (!ReflectUtils.isPrimitive(type)) {
                     return false;
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/com/alibaba/dubbo/rpc/protocol/dubbo/support/DemoService.java b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/com/alibaba/dubbo/rpc/protocol/dubbo/support/DemoService.java
index 182a1e8..93c48f5 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/com/alibaba/dubbo/rpc/protocol/dubbo/support/DemoService.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/com/alibaba/dubbo/rpc/protocol/dubbo/support/DemoService.java
@@ -57,4 +57,6 @@ public interface DemoService {
 
     NonSerialized returnNonSerialized();
 
+    long add(int a, long b);
+
 }
\ No newline at end of file
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/com/alibaba/dubbo/rpc/protocol/dubbo/support/DemoServiceImpl.java b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/com/alibaba/dubbo/rpc/protocol/dubbo/support/DemoServiceImpl.java
index 93c9764..50d98e6 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/com/alibaba/dubbo/rpc/protocol/dubbo/support/DemoServiceImpl.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/com/alibaba/dubbo/rpc/protocol/dubbo/support/DemoServiceImpl.java
@@ -103,4 +103,9 @@ public class DemoServiceImpl implements DemoService {
     public NonSerialized returnNonSerialized() {
         return new NonSerialized();
     }
+
+    public long add(int a, long b) {
+        return a + b;
+    }
+
 }
\ No newline at end of file
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/com/alibaba/dubbo/rpc/protocol/dubbo/telnet/InvokerTelnetHandlerTest.java b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/com/alibaba/dubbo/rpc/protocol/dubbo/telnet/InvokerTelnetHandlerTest.java
index 04092d0..9dfc20f 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/com/alibaba/dubbo/rpc/protocol/dubbo/telnet/InvokerTelnetHandlerTest.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/com/alibaba/dubbo/rpc/protocol/dubbo/telnet/InvokerTelnetHandlerTest.java
@@ -33,6 +33,7 @@ import org.junit.Test;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.BDDMockito.given;
 import static org.mockito.Mockito.mock;
@@ -70,6 +71,41 @@ public class InvokerTelnetHandlerTest {
 
     @SuppressWarnings("unchecked")
     @Test
+    public void testInvokeByPassingNullValue() throws RemotingException {
+        mockInvoker = mock(Invoker.class);
+        given(mockInvoker.getInterface()).willReturn(DemoService.class);
+        given(mockInvoker.getUrl()).willReturn(URL.valueOf("dubbo://127.0.0.1:20883/demo"));
+        given(mockInvoker.invoke(any(Invocation.class))).willReturn(new RpcResult("ok"));
+        mockChannel = mock(Channel.class);
+        given(mockChannel.getAttribute("telnet.service")).willReturn("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService");
+        given(mockChannel.getLocalAddress()).willReturn(NetUtils.toAddress("127.0.0.1:5555"));
+        given(mockChannel.getRemoteAddress()).willReturn(NetUtils.toAddress("127.0.0.1:20883"));
+        DubboProtocol.getDubboProtocol().export(mockInvoker);
+        // pass null value to parameter of primitive type
+        try {
+            invoke.telnet(mockChannel, "DemoService.add(null, 2)");
+            fail("It should cause a NullPointerException by the above code.");
+        } catch (NullPointerException ex) {
+            String message = ex.getMessage();
+            assertEquals("The type of No.1 parameter is primitive(int), but the value passed is null.", message);
+        }
+        try {
+            invoke.telnet(mockChannel, "DemoService.add(1, null)");
+            fail("It should cause a NullPointerException by the above code.");
+        } catch (NullPointerException ex) {
+            String message = ex.getMessage();
+            assertEquals("The type of No.2 parameter is primitive(long), but the value passed is null.", message);
+        }
+        // pass null value to parameter of object type
+        try {
+            invoke.telnet(mockChannel, "DemoService.sayHello(null)");
+        } catch (NullPointerException ex) {
+            fail("It shouldn't cause a NullPointerException by the above code.");
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
     public void testInvokeAutoFindMethod() throws RemotingException {
         mockInvoker = mock(Invoker.class);
         given(mockInvoker.getInterface()).willReturn(DemoService.class);