OPENDJ-2776 Remove trailing spaces from AVAs and RDNs during parsing
Leading and trailing whitespace in RDN attribute values must be escaped
according to RFC 4514, otherwise the RDN is invalid. However, it is
often best practice to be tolerant of malformed data, so we should
really trim off any leading or trailing whitespaces. The AVA class was
already trimming leading whitespace, but not trailing.
| | |
| | | reader.skipWhitespaces(); |
| | | |
| | | boolean escaped = false; |
| | | int trailingSpaces = 0; |
| | | while (reader.remaining() > 0) { |
| | | final char c = reader.read(); |
| | | if (escaped) { |
| | |
| | | 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); |
| | | } |
| | | |
| | |
| | | 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"); |
| | | } |
| | | } |
| | |
| | | * 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; |
| | |
| | | .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())); |
| | | } |
| | | } |