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

rsivaram pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/kafka.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 43e2125  KAFKA-7388 equal sign in property value for password (#5630)
43e2125 is described below

commit 43e21252cac8eebfbb168cd47d4de18241f8b755
Author: Mutasem Aldmour <[email protected]>
AuthorDate: Tue Sep 18 11:35:59 2018 +0300

    KAFKA-7388 equal sign in property value for password (#5630)
    
    Reviewers: Manikumar Reddy <[email protected]>, Murali Mani 
<[email protected]>, Rajini Sivaram <[email protected]>
---
 .../main/scala/kafka/utils/CommandLineUtils.scala  | 13 ++++----
 .../test/scala/unit/kafka/KafkaConfigTest.scala    | 23 ++++++++++----
 .../unit/kafka/utils/CommandLineUtilsTest.scala    | 35 +++++++++++++++++-----
 3 files changed, 50 insertions(+), 21 deletions(-)

diff --git a/core/src/main/scala/kafka/utils/CommandLineUtils.scala 
b/core/src/main/scala/kafka/utils/CommandLineUtils.scala
index edf473e..700a137 100644
--- a/core/src/main/scala/kafka/utils/CommandLineUtils.scala
+++ b/core/src/main/scala/kafka/utils/CommandLineUtils.scala
@@ -5,7 +5,7 @@
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *    http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
@@ -58,21 +58,18 @@ object CommandLineUtils extends Logging {
 
   /**
    * Parse key-value pairs in the form key=value
+   * value may contain equals sign
    */
   def parseKeyValueArgs(args: Iterable[String], acceptMissingValue: Boolean = 
true): Properties = {
-    val splits = args.map(_ split "=").filterNot(_.length == 0)
+    val splits = args.map(_.split("=", 2)).filterNot(_.length == 0)
 
     val props = new Properties
     for (a <- splits) {
-      if (a.length == 1) {
+      if (a.length == 1 || (a.length == 2 && a(1).isEmpty())) {
         if (acceptMissingValue) props.put(a(0), "")
         else throw new IllegalArgumentException(s"Missing value for key 
${a(0)}")
       }
-      else if (a.length == 2) props.put(a(0), a(1))
-      else {
-        System.err.println("Invalid command line properties: " + 
args.mkString(" "))
-        Exit.exit(1)
-      }
+      else props.put(a(0), a(1))
     }
     props
   }
diff --git a/core/src/test/scala/unit/kafka/KafkaConfigTest.scala 
b/core/src/test/scala/unit/kafka/KafkaConfigTest.scala
index 469cf92..c887632 100644
--- a/core/src/test/scala/unit/kafka/KafkaConfigTest.scala
+++ b/core/src/test/scala/unit/kafka/KafkaConfigTest.scala
@@ -59,12 +59,6 @@ class KafkaTest {
   }
 
   @Test(expected = classOf[FatalExitError])
-  def testGetKafkaConfigFromArgsWrongSetValue(): Unit = {
-    val propertiesFile = prepareDefaultConfig()
-    KafkaConfig.fromProps(Kafka.getPropsFromArgs(Array(propertiesFile, 
"--override", "a=b=c")))
-  }
-
-  @Test(expected = classOf[FatalExitError])
   def testGetKafkaConfigFromArgsNonArgsAtTheEnd(): Unit = {
     val propertiesFile = prepareDefaultConfig()
     KafkaConfig.fromProps(Kafka.getPropsFromArgs(Array(propertiesFile, 
"--override", "broker.id=1", "broker.id=2")))
@@ -97,6 +91,23 @@ class KafkaTest {
     assertEquals("truststore_password", 
config.getPassword(KafkaConfig.SslTruststorePasswordProp).value)
   }
 
+  @Test
+  def testKafkaSslPasswordsWithSymbols(): Unit = {
+    val password = "=!#-+!?*/\"\'^%$=\\.,@:;="
+    val propertiesFile = prepareDefaultConfig()
+    val config = 
KafkaConfig.fromProps(Kafka.getPropsFromArgs(Array(propertiesFile,
+      "--override", "ssl.keystore.password=" + password,
+      "--override", "ssl.key.password=" + password,
+      "--override", "ssl.truststore.password=" + password)))
+    assertEquals(Password.HIDDEN, 
config.getPassword(KafkaConfig.SslKeyPasswordProp).toString)
+    assertEquals(Password.HIDDEN, 
config.getPassword(KafkaConfig.SslKeystorePasswordProp).toString)
+    assertEquals(Password.HIDDEN, 
config.getPassword(KafkaConfig.SslTruststorePasswordProp).toString)
+
+    assertEquals(password, 
config.getPassword(KafkaConfig.SslKeystorePasswordProp).value)
+    assertEquals(password, 
config.getPassword(KafkaConfig.SslKeyPasswordProp).value)
+    assertEquals(password, 
config.getPassword(KafkaConfig.SslTruststorePasswordProp).value)
+  }
+
   def prepareDefaultConfig(): String = {
     prepareConfig(Array("broker.id=1", "zookeeper.connect=somewhere"))
   }
diff --git a/core/src/test/scala/unit/kafka/utils/CommandLineUtilsTest.scala 
b/core/src/test/scala/unit/kafka/utils/CommandLineUtilsTest.scala
index 50023f8..25c6729 100644
--- a/core/src/test/scala/unit/kafka/utils/CommandLineUtilsTest.scala
+++ b/core/src/test/scala/unit/kafka/utils/CommandLineUtilsTest.scala
@@ -26,30 +26,51 @@ class CommandLineUtilsTest {
   @Test(expected = classOf[java.lang.IllegalArgumentException])
   def testParseEmptyArg() {
     val argArray = Array("my.empty.property=")
-    CommandLineUtils.parseKeyValueArgs(argArray, false)
+
+    CommandLineUtils.parseKeyValueArgs(argArray, acceptMissingValue = false)
   }
 
+  @Test(expected = classOf[java.lang.IllegalArgumentException])
+  def testParseEmptyArgWithNoDelimiter() {
+    val argArray = Array("my.empty.property")
+
+    CommandLineUtils.parseKeyValueArgs(argArray, acceptMissingValue = false)
+  }
 
   @Test
   def testParseEmptyArgAsValid() {
-    val argArray = Array("my.empty.property=")
+    val argArray = Array("my.empty.property=", "my.empty.property1")
     val props = CommandLineUtils.parseKeyValueArgs(argArray)
-    assertEquals("Value of a key with missing value should be an empty 
string",props.getProperty("my.empty.property"),"")
+
+    assertEquals("Value of a key with missing value should be an empty 
string", props.getProperty("my.empty.property"), "")
+    assertEquals("Value of a key with missing value with no delimiter should 
be an empty string", props.getProperty("my.empty.property1"), "")
   }
 
   @Test
   def testParseSingleArg() {
     val argArray = Array("my.property=value")
     val props = CommandLineUtils.parseKeyValueArgs(argArray)
-    assertEquals("Value of a single property should be 'value' 
",props.getProperty("my.property"),"value")
+
+    assertEquals("Value of a single property should be 'value' ", 
props.getProperty("my.property"), "value")
   }
 
   @Test
   def testParseArgs() {
     val argArray = Array("first.property=first","second.property=second")
-    val props = CommandLineUtils.parseKeyValueArgs(argArray, false)
-    assertEquals("Value of first property should be 
'first'",props.getProperty("first.property"),"first")
-    assertEquals("Value of second property should be 
'second'",props.getProperty("second.property"),"second")
+    val props = CommandLineUtils.parseKeyValueArgs(argArray)
+
+    assertEquals("Value of first property should be 'first'", 
props.getProperty("first.property"), "first")
+    assertEquals("Value of second property should be 'second'", 
props.getProperty("second.property"), "second")
+  }
+
+  @Test
+  def testParseArgsWithMultipleDelimiters() {
+    val argArray = Array("first.property==first", "second.property=second=", 
"third.property=thi=rd")
+    val props = CommandLineUtils.parseKeyValueArgs(argArray)
+
+    assertEquals("Value of first property should be '=first'", 
props.getProperty("first.property"), "=first")
+    assertEquals("Value of second property should be 'second='", 
props.getProperty("second.property"), "second=")
+    assertEquals("Value of second property should be 'thi=rd'", 
props.getProperty("third.property"), "thi=rd")
   }
 
 }

Reply via email to