From a3765efb5b8fda69465b9f8fb433bdf16eb21307 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Wed, 16 Mar 2016 00:46:31 +0000
Subject: [PATCH] OPENDJ-2776 Remove trailing spaces from AVAs and RDNs during parsing

---
 opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/RDNTestCase.java |   22 ++++++++++++++++++++--
 opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AVA.java         |    5 +++++
 opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/AVATestCase.java |   28 ++++++++++++++++++++++++++++
 3 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AVA.java b/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AVA.java
index 2f4d167..599f28b 100644
--- a/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AVA.java
+++ b/opendj-sdk/opendj-core/src/main/java/org/forgerock/opendj/ldap/AVA.java
@@ -182,6 +182,7 @@
         reader.skipWhitespaces();
 
         boolean escaped = false;
+        int trailingSpaces = 0;
         while (reader.remaining() > 0) {
             final char c = reader.read();
             if (escaped) {
@@ -216,21 +217,25 @@
                 escaped = false;
             } else if (c == '\\') {
                 escaped = true;
+                trailingSpaces = 0;
             } else {
                 // Check for delimited chars.
                 if (c == '+' || c == ',' || c == ';') {
                     reader.reset();
                     appendHexChars(reader, valueBuffer, hexBuffer);
+                    valueBuffer.setLength(valueBuffer.length() - trailingSpaces);
                     return ByteString.valueOfUtf8(valueBuffer);
                 }
                 // It is definitely not a delimiter at this point.
                 appendHexChars(reader, valueBuffer, hexBuffer);
                 valueBuffer.append(c);
+                trailingSpaces = c != ' ' ? 0 : trailingSpaces + 1;
             }
             reader.mark();
         }
 
         reader.reset();
+        valueBuffer.setLength(valueBuffer.length() - trailingSpaces);
         return ByteString.valueOfUtf8(valueBuffer);
     }
 
diff --git a/opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/AVATestCase.java b/opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/AVATestCase.java
index 1c3993c..b7ac087 100644
--- a/opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/AVATestCase.java
+++ b/opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/AVATestCase.java
@@ -52,4 +52,32 @@
         final String roundtrippedValue = AVA.valueOf(avaString).toString();
         assertThat(AVA.valueOf(roundtrippedValue).toString()).isEqualTo(avaString);
     }
+
+    @DataProvider
+    public Object[][] toStringShouldStripOutIllegalWhitespaceDataProvider() {
+        // @formatter:off
+        return new Object[][] {
+            { " dc = hello  world ", "dc=hello  world" },
+            { " dc =\\  hello  world\\  ", "dc=\\  hello  world\\ " },
+        };
+        // @formatter:on
+    }
+
+    @Test(dataProvider = "toStringShouldStripOutIllegalWhitespaceDataProvider")
+    public void toStringShouldStripOutIllegalWhitespace(String withWhiteSpace, String withoutWhiteSpace) {
+        assertThat(AVA.valueOf(withWhiteSpace).toString()).isEqualTo(withoutWhiteSpace);
+        assertThat(AVA.valueOf(withWhiteSpace).toNormalizedByteString(new ByteStringBuilder()))
+                .isEqualTo(AVA.valueOf(withoutWhiteSpace).toNormalizedByteString(new ByteStringBuilder()));
+    }
+
+    @Test
+    public void avaConstructedWithValueContainingLeadingAndTrailingSpacesShouldBeEscaped() {
+        AVA ava = new AVA("dc", " hello  world ");
+        assertThat(ava.toString()).isEqualTo("dc=\\ hello  world\\ ");
+    }
+
+    @Test
+    public void valueOfDecodesTrailingEscapedChars() {
+        assertThat(AVA.valueOf("dc=\\41\\42\\43").toString()).isEqualTo("dc=ABC");
+    }
 }
diff --git a/opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/RDNTestCase.java b/opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/RDNTestCase.java
index 26fdd69..3d59411 100644
--- a/opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/RDNTestCase.java
+++ b/opendj-sdk/opendj-core/src/test/java/org/forgerock/opendj/ldap/RDNTestCase.java
@@ -12,12 +12,12 @@
  * information: "Portions Copyright [year] [name of copyright owner]".
  *
  * Copyright 2010 Sun Microsystems, Inc.
- * Portions copyright 2011-2015 ForgeRock AS.
+ * Portions copyright 2011-2016 ForgeRock AS.
  */
 
 package org.forgerock.opendj.ldap;
 
-import static org.fest.assertions.Assertions.*;
+import static org.assertj.core.api.Assertions.assertThat;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertTrue;
@@ -449,4 +449,22 @@
                     .isNotEqualTo(h2);
         }
     }
+
+    @DataProvider
+    public Object[][] toStringShouldStripOutIllegalWhitespaceDataProvider() {
+        // @formatter:off
+        return new Object[][] {
+            { " dc = hello  world ", "dc=hello  world" },
+            { " dc =\\  hello  world\\  ", "dc=\\  hello  world\\ " },
+            { " uid = cpfc + dc = example ", "uid=cpfc+dc=example" },
+        };
+        // @formatter:on
+    }
+
+    @Test(dataProvider = "toStringShouldStripOutIllegalWhitespaceDataProvider")
+    public void toStringShouldStripOutIllegalWhitespace(String withWhiteSpace, String withoutWhiteSpace) {
+        assertThat(RDN.valueOf(withWhiteSpace).toString()).isEqualTo(withoutWhiteSpace);
+        assertThat(RDN.valueOf(withWhiteSpace).toNormalizedByteString(new ByteStringBuilder()))
+                .isEqualTo(RDN.valueOf(withoutWhiteSpace).toNormalizedByteString(new ByteStringBuilder()));
+    }
 }

--
Gitblit v1.10.0