[prev in list] [next in list] [prev in thread] [next in thread] 

List:       perl-ldap-dev
Subject:    Re: Minor bug in LDIF write_entry - base64 encode section
From:       "Andrew Johns" <ajohns () firstpointglobal ! com>
Date:       2004-10-12 8:09:29
Message-ID: 57739.192.168.100.1.1097568569.squirrel () 192 ! 168 ! 100 ! 1
[Download RAW message or body]

> On 12 Oct 2004, at 02:10, Andrew Johns wrote:
>> The reason is that the check for base64-encoding the attribute VALUE
>> (the
>> name is done correctly) ignores the 'less than' symbol '<' - the dn and
>> attribute names are handled correctly.
>>
>> It's a one-byte change to LDIF.pm as you can see below...
>>
>> $ diff LDIF.pm LDIF.pm.saved
>> 354c354
>> <     if ($v =~ /(^[ :<]|[\x00-\x1f\x7f-\xff])/) {
>> ---
>>>     if ($v =~ /(^[ :]|[\x00-\x1f\x7f-\xff])/) {
>
> No, the original code is correct. RFC2849 states
>
> value-spec               = ":" (    FILL 0*1(SAFE-STRING) /
>                                  ":" FILL (BASE64-STRING) /
>                                  "<" FILL url)
>
> SAFE-INIT-CHAR           = %x01-09 / %x0B-0C / %x0E-1F /
>                             %x21-39 / %x3B / %x3D-7F
>                             ; any value <= 127 except NUL, LF, CR,
>                             ; SPACE, colon (":", ASCII 58 decimal)
>                             ; and less-than ("<" , ASCII 60 decimal)
>
> SAFE-STRING              = [SAFE-INIT-CHAR *SAFE-CHAR]
>
> So any value beginning with : or < is not a SAFE-STRING and must be
> base64 encoded
>
> Graham.

Hi Graham,

You are absolutely correct in your statement, but your code differs :) or
I am going mad :)

In LDIF.pm.saved (the original) at line 354, it fails to check for the <
character, as you can see in the second line of my diff output, hence it
will not base64 encode the data to be written:
     if ($v =~ /(^[ :]|[\x00-\x1f\x7f-\xff])/) {

The remainder of this code block goes on to base64 encode the data to be
written to the file *if* the first character is a space, colon or in the
ranges specified.  Unfortunately, the < character (ascii dec=60, hex=3C)
is not in any of those ranges, hence my one byte change.

For example (see code below), without my modification, I get this:
eracl: <AccessRight name= etc etc

instead of this:
eracl:: PEFjY2 (remainder removed)

The code for this is included at the end of this email below - it simply
reads from one LDIF file and writes to another. I cannot supply you with
the LDIF files I am using unfortunately, for numerous reasons...

I hope we agree or you prove me wrong :)

Best Regards
dm00d

------------------------ convert-test.pl --------------------------------
#!/usr/bin/perl -w

use Net::LDAP::LDIF;
use Net::LDAP;
use MIME::Base64;

my $entry;

# Open the input LDIF file for reading/processing
my $ldif = Net::LDAP::LDIF->new( $ARGV[0], "r", onerror => 'die' );

# Open the output LDIF file for writing
#my $outputldif = Net::LDAP::LDIF->new( "output.ldif", "w", encode =>
"base64", onerror => 'die' );
# Graham - the above line made absolutely no difference....
my $outputldif = Net::LDAP::LDIF->new("output.ldif","w",onerror => 'die');

# Main loop - read and process LDIF records (that often span mult lines);
while( not $ldif->eof() ) {

        $entry = $ldif->read_entry();

        if ( $ldif->error() ) {
                print "\n\nError msg: ", $ldif->error(), "\n";
                print "Error lines:\n", $ldif->error_lines(), "\n";
                die;
        } else {
            $outputldif->write_entry($entry);
        }
}

# Finished processing the input file... close all handles
$ldif->done ( );
$outputldif->done ( );

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic