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

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


The following commit(s) were added to refs/heads/master by this push:
     new ee5b558  Fix NPE caused by null value of SchemaInfo's properties 
(#9985)
ee5b558 is described below

commit ee5b558f9a1147c1dbaa042ee986297885e5fe66
Author: Yunze Xu <[email protected]>
AuthorDate: Mon Mar 22 11:29:42 2021 +0800

    Fix NPE caused by null value of SchemaInfo's properties (#9985)
    
    Fixes #9964
    
    ### Motivation
    
    If there exists a null value of `SchemaInfo`'s properties, NPE will be 
thrown in `SchemaInfo#toString` or `Commands#newSubscribe`.
    
    ### Modifications
    
    - Add null checks before `JsonPrimitive`'s constructor, `KeyValue#setKey` 
and `KeyValue#setValue`.
    - Add related tests.
---
 .../java/org/apache/pulsar/schema/SchemaTest.java  | 32 ++++++++++++++++++++++
 .../pulsar/client/impl/schema/SchemaUtils.java     |  2 +-
 .../pulsar/client/impl/schema/SchemaInfoTest.java  | 10 +++++++
 .../apache/pulsar/common/protocol/Commands.java    |  8 ++++--
 4 files changed, 48 insertions(+), 4 deletions(-)

diff --git 
a/pulsar-broker/src/test/java/org/apache/pulsar/schema/SchemaTest.java 
b/pulsar-broker/src/test/java/org/apache/pulsar/schema/SchemaTest.java
index f6b2947..087223c 100644
--- a/pulsar-broker/src/test/java/org/apache/pulsar/schema/SchemaTest.java
+++ b/pulsar-broker/src/test/java/org/apache/pulsar/schema/SchemaTest.java
@@ -27,12 +27,17 @@ import static org.testng.Assert.assertTrue;
 import com.google.common.collect.Sets;
 
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
 import lombok.extern.slf4j.Slf4j;
 import org.apache.pulsar.broker.auth.MockedPulsarServiceBaseTest;
 import org.apache.pulsar.broker.service.schema.SchemaRegistryServiceImpl;
+import org.apache.pulsar.client.admin.PulsarAdminException;
 import org.apache.pulsar.client.api.Consumer;
 import org.apache.pulsar.client.api.Message;
 import org.apache.pulsar.client.api.Producer;
+import org.apache.pulsar.client.api.PulsarClientException;
 import org.apache.pulsar.client.api.Schema;
 import org.apache.pulsar.client.api.schema.GenericRecord;
 import org.apache.pulsar.client.api.schema.SchemaDefinition;
@@ -40,6 +45,7 @@ import org.apache.pulsar.common.naming.TopicDomain;
 import org.apache.pulsar.common.naming.TopicName;
 import org.apache.pulsar.common.policies.data.ClusterData;
 import org.apache.pulsar.common.policies.data.TenantInfo;
+import org.apache.pulsar.common.schema.SchemaInfo;
 import org.apache.pulsar.common.schema.SchemaType;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
@@ -205,4 +211,30 @@ public class SchemaTest extends 
MockedPulsarServiceBaseTest {
             }
         }
     }
+
+    @Test
+    public void testNullKeyValueProperty() throws PulsarAdminException, 
PulsarClientException {
+        final String tenant = PUBLIC_TENANT;
+        final String namespace = "test-namespace-" + randomName(16);
+        final String topicName = "test";
+
+        final String topic = TopicName.get(
+                TopicDomain.persistent.value(),
+                tenant,
+                namespace,
+                topicName).toString();
+        admin.namespaces().createNamespace(
+                tenant + "/" + namespace,
+                Sets.newHashSet(CLUSTER_NAME));
+
+        final Map<String, String> map = new HashMap<>();
+        map.put("key", null);
+        map.put(null, "value"); // null key is not allowed for JSON, it's only 
for test here
+        Schema.INT32.getSchemaInfo().setProperties(map);
+
+        final Consumer<Integer> consumer = 
pulsarClient.newConsumer(Schema.INT32).topic(topic)
+                .subscriptionName("sub")
+                .subscribe();
+        consumer.close();
+    }
 }
diff --git 
a/pulsar-client/src/main/java/org/apache/pulsar/client/impl/schema/SchemaUtils.java
 
b/pulsar-client/src/main/java/org/apache/pulsar/client/impl/schema/SchemaUtils.java
index 7d9ae25f..23ecb4e 100644
--- 
a/pulsar-client/src/main/java/org/apache/pulsar/client/impl/schema/SchemaUtils.java
+++ 
b/pulsar-client/src/main/java/org/apache/pulsar/client/impl/schema/SchemaUtils.java
@@ -238,7 +238,7 @@ public final class SchemaUtils {
             sortedProperties.putAll(properties);
             JsonObject object = new JsonObject();
             sortedProperties.forEach((key, value) -> {
-                object.add(key, new JsonPrimitive(value));
+                object.add(key, (value != null) ? new JsonPrimitive(value) : 
null);
             });
             return object;
         }
diff --git 
a/pulsar-client/src/test/java/org/apache/pulsar/client/impl/schema/SchemaInfoTest.java
 
b/pulsar-client/src/test/java/org/apache/pulsar/client/impl/schema/SchemaInfoTest.java
index d187446..7e34a64 100644
--- 
a/pulsar-client/src/test/java/org/apache/pulsar/client/impl/schema/SchemaInfoTest.java
+++ 
b/pulsar-client/src/test/java/org/apache/pulsar/client/impl/schema/SchemaInfoTest.java
@@ -26,6 +26,7 @@ import org.apache.pulsar.common.schema.SchemaType;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
+import java.util.HashMap;
 import java.util.Map;
 
 import static org.testng.Assert.assertEquals;
@@ -317,5 +318,14 @@ public class SchemaInfoTest {
             assertEquals(schemaInfo.getProperties(), Maps.newHashMap(map));
         }
 
+        @Test
+        public void testNullPropertyValue() {
+            final Map<String, String> map = new HashMap<>();
+            map.put("key", null);
+            final IntSchema schema = new IntSchema();
+            schema.getSchemaInfo().setProperties(map);
+            // null key will be skipped by Gson when serializing JSON to String
+            assertEquals(schema.getSchemaInfo().toString(), INT32_SCHEMA_INFO);
+        }
     }
 }
diff --git 
a/pulsar-common/src/main/java/org/apache/pulsar/common/protocol/Commands.java 
b/pulsar-common/src/main/java/org/apache/pulsar/common/protocol/Commands.java
index ba619fc..0c80395 100644
--- 
a/pulsar-common/src/main/java/org/apache/pulsar/common/protocol/Commands.java
+++ 
b/pulsar-common/src/main/java/org/apache/pulsar/common/protocol/Commands.java
@@ -694,9 +694,11 @@ public class Commands {
                 .setType(getSchemaType(schemaInfo.getType()));
 
         schemaInfo.getProperties().entrySet().stream().forEach(entry -> {
-            schema.addProperty()
-                .setKey(entry.getKey())
-                .setValue(entry.getValue());
+            if (entry.getKey() != null && entry.getValue() != null) {
+                schema.addProperty()
+                        .setKey(entry.getKey())
+                        .setValue(entry.getValue());
+            }
         });
     }
 

Reply via email to