[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re: ber_scanf and ber_printf strangeness



Hello,

On Thursday 24 May 2007 00:17:37 Howard Chu wrote:
> Howard Chu wrote:
> > Szombathelyi György wrote:
> >> Hi!
> >>
> >> I'm developing kldap, a Qt wrapper for LDAP-functions. When I tested
> >> ber_scanf and ber_printf functions, I found this strangeness:
> >> Encode a sequence of octet strings via ber_printf
> >> ber_printf(ber,"{v}",list_of_strings);
> >> But decoding only succeeds if I use the following scanf formats:
> >> ber_scanf(ber,"v",...) - yes, without '{}', or
> >> ber_scanf(ber,"{ooo}")
> >> As I read the ber_scanf man page, 'v' format actually decodes a sequence
> >> of octet strings, so my examples are correct according to these. But the
> >> code example on the end shows that '{v}' should be used. So what is the
> >> right way?
> >
> > It looks like the manpage example is wrong.
>
> I take that back. The example matches the ldap-c-api draft document. The
> liblber code matches as well.
>

I assembled a small test program, to demonstrate the problem. As I wrapping 
the ber functions into a C++ class, I cannot pass the variadic parameters "as 
is", instead I call repeatedly ber_scanf with only one argument at a time. 

So the encoding:
ber_printf(ber,"i{v}",integer param,list param);

can be decoded with:
ber_scanf(ber,"i{v}",integer,list);
and
ber_scanf(ber,"i",integer);
ber_scanf(ber,"v",list);
But NOT with:
ber_scanf(ber,"i",integer);
ber_scanf(ber,"{");
ber_scanf(ber,"v",list);
ber_scanf(ber,"}");

Attached the .c file, where there are 3 methods of decoding, and the second 
one is failing, but it seems to logical to me that it should work.

> Seems your version of liblber is broken, or you're not calling ber_scanf
> with the right arguments.

Using OpenLDAP 2.3.30.

Thanks,
György

#include <lber.h>
#include <ldap.h>

#include <stdio.h>

int main() 
{
  BerElement *ber1,*ber2;
  struct berval *bv;

  char *a="first";
  char *b="second";
  char **list1[3],**list2;
  int i1=0xaa,i2;

  ber1=ber_alloc_t(LBER_USE_DER);
  
  list1[0] = a;
  list1[1] = b;
  list1[2] = 0;

  /* Fill ber1 */
  ber_printf(ber1,"i{v}",i1,list1);

  /* Copy ber1 to ber2 */ 
  ber_flatten( ber1, &bv );
  ber2 = ber_init( bv );
  ber_bvfree( bv );
   
  /* Decode ber2 */
  /* Method 1 - The line below works as expected */
//  ber_scanf(ber2,"i{v}",&i2,&list2);

  /* Method 2 - If I use the decoding below, it don't work */
/*
  ber_scanf(ber2,"i",&i2);
  ber_scanf(ber2,"{");
  ber_scanf(ber2,"v",&list2);
  ber_scanf(ber2,"}");
*/

  /* Method 3 - But these two lines works */

  ber_scanf(ber2,"i",&i2);
  ber_scanf(ber2,"v",&list2);
  

  /* Print decoded values */
  printf("%x\n",i2);
  while (*list2) {
    printf("%s\n",*list2);
    list2++;
  }
}