+ break;
+
+ case '+': /* string concatenation */
+ i = slap_set_size( rset );
+ j = slap_set_size( lset );
+
+ set = cp->set_op->o_tmpcalloc( i * j + 1, sizeof( struct berval ),
+ cp->set_op->o_tmpmemctx );
+ if ( set == NULL ) {
+ break;
+ }
+
+ for ( last = 0, i = 0; !BER_BVISNULL( &lset[ i ] ); i++ ) {
+ for ( j = 0; !BER_BVISNULL( &rset[ j ] ); j++ ) {
+ struct berval bv;
+ long k;
+
+ bv.bv_len = lset[ i ].bv_len + rset[ j ].bv_len;
+ bv.bv_val = cp->set_op->o_tmpalloc( bv.bv_len + 1,
+ cp->set_op->o_tmpmemctx );
+ if ( bv.bv_val == NULL ) {
+ slap_set_dispose( cp, set, 0 );
+ set = NULL;
+ goto done;
+ }
+ AC_MEMCPY( bv.bv_val, lset[ i ].bv_val, lset[ i ].bv_len );
+ AC_MEMCPY( &bv.bv_val[ lset[ i ].bv_len ], rset[ j ].bv_val, rset[ j ].bv_len );
+ bv.bv_val[ bv.bv_len ] = '\0';
+
+ for ( k = 0; k < last; k++ ) {
+ if ( bvmatch( &set[ k ], &bv ) ) {
+ cp->set_op->o_tmpfree( bv.bv_val, cp->set_op->o_tmpmemctx );
+ break;
+ }
+ }
+
+ if ( k == last ) {
+ set[ last++ ] = bv;
+ }
+ }
+ }
+ BER_BVZERO( &set[ last ] );
+ break;
+
+ default:
+ break;
+ }
+
+done:;
+ if ( !( op_flags & SLAP_SET_LREFARR ) && lset != NULL ) {
+ if ( !( op_flags & SLAP_SET_LREFVAL ))
+ cp->set_op->o_tmpfree( lset->bv_val, cp->set_op->o_tmpmemctx );
+ cp->set_op->o_tmpfree( lset, cp->set_op->o_tmpmemctx );
+ }
+
+ if ( !( op_flags & SLAP_SET_RREFARR ) && rset != NULL ) {
+ if ( !( op_flags & SLAP_SET_RREFVAL ))
+ cp->set_op->o_tmpfree( rset->bv_val, cp->set_op->o_tmpmemctx );
+ cp->set_op->o_tmpfree( rset, cp->set_op->o_tmpmemctx );