#!/usr/bin/perl -w ###################################################################### ### Name: ber-test.pl ### Date Created: Sat Feb 1 16:09:46 1997 ### Author: Simon Leinen <simon@switch.ch> ### RCS $Id: ber-test.pl,v 1.9 2004/02/17 21:38:56 leinen Exp $ ###################################################################### ### Regression Tests for BER encoding/decoding ###################################################################### use BER; use Carp; use integer; use strict; ## Prototypes sub regression_test (); sub encode_int_test ($$); sub decode_intlike_test ($$); sub eq_test ($$); sub equal_test ($$); sub string_hex ($ ); sub encode_int_regression_test (); my $exitcode = 0; regression_test; exit ($exitcode); #### Regression Tests sub regression_test () { eq_test ('encode_string ("public")', "\x04\x06\x70\x75\x62\x6C\x69\x63"); eq_test ('encode_ip_address ("\x82\x3b\x04\x02")', "\x40\x04\x82\x3b\x04\x02"); eq_test ('encode_ip_address ("130.59.4.2")', "\x40\x04\x82\x3b\x04\x02"); encode_int_test (0x4aec3116, "\x02\x04\x4A\xEC\x31\x16"); encode_int_test (0xec3116, "\x02\x04\x00\xEC\x31\x16"); encode_int_test (0x3c3116, "\x02\x03\x3C\x31\x16"); encode_int_test (-1234, "\x02\x02\xfb\x2e"); decode_intlike_test ('"\x02\x01\x01"', 1); decode_intlike_test ('"\x02\x01\xff"', -1); decode_intlike_test ('"\x02\x02\x01\x02"', 258); decode_intlike_test ('"\x02\x02\xff\xff"', -1); decode_intlike_test ('"\x02\x03\x00\xff\xfe"', 65534); decode_intlike_test ('"\x02\x03\xff\xff\xfd"', -3); decode_intlike_test ('"\x02\x04\x00\xff\xff\xfd"', 16777213); decode_intlike_test ('"\x02\x04\xff\xff\xff\xfc"', -4); decode_intlike_test ('"\x02\x05\x00\xff\xff\xff\xfc"', 4294967292); ## Tests for integers > 2^32 ## ## For really big integers (those that don't have an exact double ## representation, I guess), we have to write the comparands as ## strings, because otherwise they will be converted to NaN by ## Perl. The comparisons still work right thanks to Math::BigInt, ## which is used by BER.pm for large integers. ## decode_intlike_test ('"\x02\x06\x00\x01\x00\x00\x00\x00"', 4294967296); decode_intlike_test ('"\x02\x09\x00\xff\xff\xff\xff\xff\xff\xff\xff"', "18446744073709551615"); use Math::BigInt lib => 'GMP'; { ## We have to disable warnings because of Math::BigInt ## local $^W = 0; eq_test ('encode_int (new Math::BigInt ("18446744073709551615"))', "\x02\x09\x00\xff\xff\xff\xff\xff\xff\xff\xff"); } eq_test ('(BER::decode_string ("\x04\x06public"))[0]', "public"); eq_test ('(BER::decode_oid ("\x06\x04\x01\x03\x06\x01"))[0]', "\x06\x04\x01\x03\x06\x01"); die unless encode_int_regression_test (); } sub encode_int_test ($$) { my ($int, $encoded) = @_; eq_test ("encode_int ($int)", $encoded); } sub decode_intlike_test ($$) { my ($pdu, $wanted) = @_; equal_test ("(BER::decode_intlike ($pdu))[0]", $wanted); } sub eq_test ($$) { my ($expr, $wanted) = @_; my $result; undef $@; $result = eval $expr; croak "$@" if $@; (warn $expr." => ".string_hex ($result)." != ".string_hex ($wanted)), ++$exitcode unless $result eq $wanted; } sub equal_test ($$) { my ($expr, $wanted) = @_; my $result; undef $@; $result = eval $expr; croak "$@" if $@; (warn $expr." => ".$result." != ".$wanted), ++$exitcode unless $result == $wanted; } sub string_hex ($ ) { my $result = ''; my ($string) = @_; my ($i); for ($i = 0; $i < length $string; ++$i) { $result .= sprintf "%02x", ord (substr ($string, $i, 1)); } $result; } ### Test cases and harness kindly contributed by ### Mike Mitchell <mcm@unx.sas.com> ### sub encode_int_regression_test () { my $try; my @tries = ( 0, 1, 126, 127, 128, 129, 254, 255, 256, 257, 32766, 32767, 32768, 32769, 65534, 65535, 65536, 65537, 8388606, 8388607, 8388608, 8388609, 16777214, 16777215, 16777216, 16777217, -1, -126, -127, -128, -129, -254, -255, -256, -257, -32766, -32767, -32768, -32769, -65534, -65535, -65536, -65537, -8388606, -8388607, -8388608, -8388609, -16777214, -16777215, -16777216, -16777217, 5921370, -5921370, 2147483646, 2147483647, -2147483647, -2147483648 ); my $expected = <<EOM; 0: 02 01 00 1: 02 01 01 126: 02 01 7e 127: 02 01 7f 128: 02 02 00 80 129: 02 02 00 81 254: 02 02 00 fe 255: 02 02 00 ff 256: 02 02 01 00 257: 02 02 01 01 32766: 02 02 7f fe 32767: 02 02 7f ff 32768: 02 03 00 80 00 32769: 02 03 00 80 01 65534: 02 03 00 ff fe 65535: 02 03 00 ff ff 65536: 02 03 01 00 00 65537: 02 03 01 00 01 8388606: 02 03 7f ff fe 8388607: 02 03 7f ff ff 8388608: 02 04 00 80 00 00 8388609: 02 04 00 80 00 01 16777214: 02 04 00 ff ff fe 16777215: 02 04 00 ff ff ff 16777216: 02 04 01 00 00 00 16777217: 02 04 01 00 00 01 -1: 02 01 ff -126: 02 01 82 -127: 02 01 81 -128: 02 01 80 -129: 02 02 ff 7f -254: 02 02 ff 02 -255: 02 02 ff 01 -256: 02 02 ff 00 -257: 02 02 fe ff -32766: 02 02 80 02 -32767: 02 02 80 01 -32768: 02 02 80 00 -32769: 02 03 ff 7f ff -65534: 02 03 ff 00 02 -65535: 02 03 ff 00 01 -65536: 02 03 ff 00 00 -65537: 02 03 fe ff ff -8388606: 02 03 80 00 02 -8388607: 02 03 80 00 01 -8388608: 02 03 80 00 00 -8388609: 02 04 ff 7f ff ff -16777214: 02 04 ff 00 00 02 -16777215: 02 04 ff 00 00 01 -16777216: 02 04 ff 00 00 00 -16777217: 02 04 fe ff ff ff 5921370: 02 03 5a 5a 5a -5921370: 02 03 a5 a5 a6 2147483646: 02 04 7f ff ff fe 2147483647: 02 04 7f ff ff ff -2147483647: 02 04 80 00 00 01 -2147483648: 02 04 80 00 00 00 EOM my @wanted = split ("\n", $expected); foreach $try (@tries) { my ($r, $jnk, $val, @vals, $output, $wanted); undef @vals; $r = BER::encode_int($try); $output = "$try: "; @vals = unpack("C*", $r); foreach $val (@vals) { $output .= sprintf ("%02x ", $val); } ($r, $jnk) = BER::decode_intlike_s($r, 1); $output .= "Decode to $r didn't match!" if ($r != $try); $wanted = shift @wanted; die "Mismatch in encode_int_regression_test:\n" ."< $wanted\n> $output" unless $output eq $wanted; } 1; }