From d68ba23ab87ee5f6f8af2f855f9caa29480c1cf7 Mon Sep 17 00:00:00 2001 From: Hallvard Furuseth Date: Sat, 18 Oct 2008 11:09:55 +0000 Subject: [PATCH] ITS#5750: Fix nameUIDPretty() bitstring in Name and Optional UID syntax. Also update a comment about parsing this syntax. --- servers/slapd/schema_init.c | 44 ++++++++++--------------------------- tests/data/dn.out | 27 ++++++++++++----------- tests/data/test-dn.ldif | 4 ++-- tests/scripts/test026-dn | 15 ++++++++++++- 4 files changed, 41 insertions(+), 49 deletions(-) diff --git a/servers/slapd/schema_init.c b/servers/slapd/schema_init.c index 28f2498a42..ca508cfdfe 100644 --- a/servers/slapd/schema_init.c +++ b/servers/slapd/schema_init.c @@ -1105,12 +1105,7 @@ bitStringValidate( ... * - * Note: normalization strips any leading "0"s, unless the - * bit string is exactly "'0'B", so the normalized example, - * in slapd, would result in - * - * 1.3.6.1.4.1.1466.0=#04024869,o=test,c=gb#'101'B - * + * Note: * RFC 4514 clarifies that SHARP, i.e. "#", doesn't have to * be escaped except when at the beginning of a value, the * definition of Name and Optional UID appears to be flawed, @@ -1134,11 +1129,11 @@ bitStringValidate( * * in fact "com#'1'B" is a valid IA5 string. * - * As a consequence, current slapd code assumes that the - * presence of portions of a BitString at the end of the string - * representation of a NameAndOptionalUID means a BitString - * is expected, and cause an error otherwise. This is quite - * arbitrary, and might change in the future. + * As a consequence, current slapd code takes the presence of + * # at the end of the string representation + * of a NameAndOptionalUID to mean this is indeed a BitString. + * This is quite arbitrary - it has changed the past and might + * change in the future. */ @@ -1209,7 +1204,8 @@ nameUIDPretty( if ( rc == LDAP_SUCCESS ) { ber_dupbv_x( &dnval, val, ctx ); - dnval.bv_len -= uidval.bv_len + 1; + uidval.bv_val--; + dnval.bv_len -= ++uidval.bv_len; dnval.bv_val[dnval.bv_len] = '\0'; } else { @@ -1226,36 +1222,18 @@ nameUIDPretty( } if( !BER_BVISNULL( &uidval ) ) { - int i, c, got1; char *tmp; tmp = slap_sl_realloc( out->bv_val, out->bv_len - + STRLENOF( "#" ) + uidval.bv_len + 1, + + uidval.bv_len + 1, ctx ); if( tmp == NULL ) { ber_memfree_x( out->bv_val, ctx ); return LDAP_OTHER; } out->bv_val = tmp; - out->bv_val[out->bv_len++] = '#'; - out->bv_val[out->bv_len++] = '\''; - - got1 = uidval.bv_len < sizeof("'0'B"); - for( i = 1; i < uidval.bv_len - 2; i++ ) { - c = uidval.bv_val[i]; - switch(c) { - case '0': - if( got1 ) out->bv_val[out->bv_len++] = c; - break; - case '1': - got1 = 1; - out->bv_val[out->bv_len++] = c; - break; - } - } - - out->bv_val[out->bv_len++] = '\''; - out->bv_val[out->bv_len++] = 'B'; + memcpy( out->bv_val + out->bv_len, uidval.bv_val, uidval.bv_len ); + out->bv_len += uidval.bv_len; out->bv_val[out->bv_len] = '\0'; } } diff --git a/tests/data/dn.out b/tests/data/dn.out index 5cc8214c50..24019e58c3 100644 --- a/tests/data/dn.out +++ b/tests/data/dn.out @@ -78,15 +78,15 @@ objectClass: groupOfUniqueNames cn: Name and Optional UID uniqueMember: cn=Name and Optional UID,ou=Related Syntaxes,dc=example,dc=com uniqueMember: #'1'B -uniqueMember: #'10'B +uniqueMember: #'0010'B uniqueMember: dc=example,dc=com#'1000'B -uniqueMember: dc=example,dc=com#'0'B +uniqueMember: dc=example,dc=com#''B description: cn=Name and Optional UID,ou=Related Syntaxes,dc=example,dc=com // only DN portion description: #'1'B // empty "" DN description: #'0010'B // empty "" DN with leading '0's description: dc=example,dc=com#'1000'B // with DN portion -description: dc=example,dc=com#'0'B // with DN portion and just one '0' +description: dc=example,dc=com#''B // with DN portion + bitstring with no bits dn: ou=Related Syntaxes,dc=example,dc=com objectClass: organizationalUnit @@ -183,20 +183,21 @@ description: testUUID=597ae2f6-16a6-1027-98f4-abcdefABCDEF,DC=Example # Searching database for nameAndOptionalUID="dc=example,dc=com"... # Searching database for nameAndOptionalUID="dc=example,dc=com#'001000'B"... +# Searching database for nameAndOptionalUID="dc=example,dc=com#'1000'B"... dn: cn=Name and Optional UID,ou=Related Syntaxes,dc=example,dc=com objectClass: groupOfUniqueNames cn: Name and Optional UID uniqueMember: cn=Name and Optional UID,ou=Related Syntaxes,dc=example,dc=com uniqueMember: #'1'B -uniqueMember: #'10'B +uniqueMember: #'0010'B uniqueMember: dc=example,dc=com#'1000'B -uniqueMember: dc=example,dc=com#'0'B +uniqueMember: dc=example,dc=com#''B description: cn=Name and Optional UID,ou=Related Syntaxes,dc=example,dc=com // only DN portion description: #'1'B // empty "" DN description: #'0010'B // empty "" DN with leading '0's description: dc=example,dc=com#'1000'B // with DN portion -description: dc=example,dc=com#'0'B // with DN portion and just one '0' +description: dc=example,dc=com#''B // with DN portion + bitstring with no bits # Searching database for uniqueMember~="dc=example,dc=com" (approx)... dn: cn=Name and Optional UID,ou=Related Syntaxes,dc=example,dc=com @@ -204,29 +205,29 @@ objectClass: groupOfUniqueNames cn: Name and Optional UID uniqueMember: cn=Name and Optional UID,ou=Related Syntaxes,dc=example,dc=com uniqueMember: #'1'B -uniqueMember: #'10'B +uniqueMember: #'0010'B uniqueMember: dc=example,dc=com#'1000'B -uniqueMember: dc=example,dc=com#'0'B +uniqueMember: dc=example,dc=com#''B description: cn=Name and Optional UID,ou=Related Syntaxes,dc=example,dc=com // only DN portion description: #'1'B // empty "" DN description: #'0010'B // empty "" DN with leading '0's description: dc=example,dc=com#'1000'B // with DN portion -description: dc=example,dc=com#'0'B // with DN portion and just one '0' +description: dc=example,dc=com#''B // with DN portion + bitstring with no bits -# Searching database for uniqueMember~="dc=example,dc=com#'001000'B" (approx)... +# Searching database for uniqueMember~="dc=example,dc=com#'1000'B" (approx)... dn: cn=Name and Optional UID,ou=Related Syntaxes,dc=example,dc=com objectClass: groupOfUniqueNames cn: Name and Optional UID uniqueMember: cn=Name and Optional UID,ou=Related Syntaxes,dc=example,dc=com uniqueMember: #'1'B -uniqueMember: #'10'B +uniqueMember: #'0010'B uniqueMember: dc=example,dc=com#'1000'B -uniqueMember: dc=example,dc=com#'0'B +uniqueMember: dc=example,dc=com#''B description: cn=Name and Optional UID,ou=Related Syntaxes,dc=example,dc=com // only DN portion description: #'1'B // empty "" DN description: #'0010'B // empty "" DN with leading '0's description: dc=example,dc=com#'1000'B // with DN portion -description: dc=example,dc=com#'0'B // with DN portion and just one '0' +description: dc=example,dc=com#''B // with DN portion + bitstring with no bits diff --git a/tests/data/test-dn.ldif b/tests/data/test-dn.ldif index 412a546a23..15cc678137 100644 --- a/tests/data/test-dn.ldif +++ b/tests/data/test-dn.ldif @@ -226,12 +226,12 @@ uniqueMember: cn=Name and Optional UID,ou=Related Syntaxes,dc=example,dc=com uniqueMember: #'1'B uniqueMember: #'0010'B uniqueMember: dc=example,dc=com#'1000'B -uniqueMember: dc=example,dc=com#'0'B +uniqueMember: dc=example,dc=com#''B description: cn=Name and Optional UID,ou=Related Syntaxes,dc=example,dc=com // only DN portion description: #'1'B // empty "" DN description: #'0010'B // empty "" DN with leading '0's description: dc=example,dc=com#'1000'B // with DN portion -description: dc=example,dc=com#'0'B // with DN portion and just one '0' +description: dc=example,dc=com#''B // with DN portion + bitstring with no bits dn: cn=Should Fail 1,cn=Name and Optional UID,ou=Related Syntaxes,dc=example,dc=com objectClass: groupOfUniqueNames diff --git a/tests/scripts/test026-dn b/tests/scripts/test026-dn index 02d2afc833..32e2e8b81f 100755 --- a/tests/scripts/test026-dn +++ b/tests/scripts/test026-dn @@ -117,6 +117,19 @@ if test $RC != 0 ; then exit $RC fi +DN="dc=example,dc=com#'1000'B" +echo "Searching database for nameAndOptionalUID=\"$DN\"..." +echo "# Searching database for nameAndOptionalUID=\"$DN\"..." >> $SEARCHOUT +$LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT1 \ + "(uniqueMember=$DN)" >> $SEARCHOUT 2>&1 + +RC=$? +if test $RC != 0 ; then + echo "ldapsearch failed ($RC)!" + test $KILLSERVERS != no && kill -HUP $KILLPIDS + exit $RC +fi + DN="dc=example,dc=com" echo "Searching database for uniqueMember~=\"$DN\" (approx)..." echo "# Searching database for uniqueMember~=\"$DN\" (approx)..." >> $SEARCHOUT @@ -130,7 +143,7 @@ if test $RC != 0 ; then exit $RC fi -DN="dc=example,dc=com#'001000'B" +DN="dc=example,dc=com#'1000'B" echo "Searching database for uniqueMember~=\"$DN\" (approx)..." echo "# Searching database for uniqueMember~=\"$DN\" (approx)..." >> $SEARCHOUT $LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT1 \ -- 2.39.5