From: Robert Varga Date: Wed, 24 Feb 2021 08:47:30 +0000 (+0100) Subject: Fix StringStringCodec length check X-Git-Tag: v6.0.5~2 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=yangtools.git;a=commitdiff_plain;h=232f92df65f4c5dbc87102bf5300cfbcaf01ead7 Fix StringStringCodec length check RFC7950 specifies that string length is counted in unicode characters. String.length() returns the length in code units of UTF-16, which are not the same thing. Use String.codePointCount() to get correct results for strings containing characters from outside of Unicode BMP. JIRA: YANGTOOLS-1224 Change-Id: I6ff9557d61449625be975eaca00ad235bf429155 Signed-off-by: Robert Varga (cherry picked from commit cbadacd601e11552b749edfaaa19b64b9804e55f) --- diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/StringStringCodec.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/StringStringCodec.java index 15a5b9c6d4..cb34f1cc4a 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/StringStringCodec.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/StringStringCodec.java @@ -49,7 +49,7 @@ public class StringStringCodec extends TypeDefinitionAwareCodec ranges = lengthConstraint.getAllowedRanges(); - if (!ranges.contains(str.length())) { + if (!ranges.contains(str.codePointCount(0, str.length()))) { throw new YangInvalidValueException(ErrorType.PROTOCOL, lengthConstraint, "String " + str + " does not match allowed lengths " + ranges); } diff --git a/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/codec/StringCodecStringTest.java b/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/codec/StringCodecStringTest.java index 564d3437cc..7554be63de 100644 --- a/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/codec/StringCodecStringTest.java +++ b/yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/codec/StringCodecStringTest.java @@ -9,10 +9,20 @@ package org.opendaylight.yangtools.yang.data.impl.codec; import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import java.util.List; import org.junit.Test; +import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.codec.StringCodec; +import org.opendaylight.yangtools.yang.model.api.ConstraintMetaDefinition; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.model.api.stmt.ValueRange; +import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition; import org.opendaylight.yangtools.yang.model.util.type.BaseTypes; +import org.opendaylight.yangtools.yang.model.util.type.InvalidLengthConstraintException; +import org.opendaylight.yangtools.yang.model.util.type.RestrictedTypes; +import org.opendaylight.yangtools.yang.model.util.type.StringTypeBuilder; /** * Unit tests for StringCodecString. @@ -20,8 +30,6 @@ import org.opendaylight.yangtools.yang.model.util.type.BaseTypes; * @author Thomas Pantelis */ public class StringCodecStringTest { - - @SuppressWarnings("unchecked") @Test public void testSerialize() { StringCodec codec = TypeDefinitionAwareCodecTestHelper.getCodec(BaseTypes.stringType(), @@ -31,7 +39,6 @@ public class StringCodecStringTest { assertEquals("serialize", "", codec.serialize("")); } - @SuppressWarnings("unchecked") @Test public void testDeserialize() { StringCodec codec = TypeDefinitionAwareCodecTestHelper.getCodec(BaseTypes.stringType(), @@ -40,4 +47,16 @@ public class StringCodecStringTest { assertEquals("deserialize", "bar", codec.deserialize("bar")); assertEquals("deserialize", "", codec.deserialize("")); } + + @Test + public void testDeserializeUnicode() throws InvalidLengthConstraintException { + final StringTypeBuilder builder = RestrictedTypes.newStringBuilder(BaseTypes.stringType(), + SchemaPath.create(true, QName.create("foo", "foo"))); + builder.setLengthConstraint(mock(ConstraintMetaDefinition.class), List.of(ValueRange.of(1))); + final StringTypeDefinition type = builder.build(); + + StringCodec codec = TypeDefinitionAwareCodecTestHelper.getCodec(type, StringCodec.class); + + assertEquals("🌞", codec.deserialize("🌞")); + } }