oid_registry: allow arbitrary size OIDs

The current OID registry parser uses 64 bit arithmetic which limits us to
supporting 64 bit or smaller OIDs.  This isn't usually a problem except
that it prevents us from representing the 2.25.  prefix OIDs which are the
OID representation of UUIDs and have a 128 bit number following the
prefix.  Rather than import not often used perl arithmetic modules,
replace the current perl 64 bit arithmetic with a callout to bc, which is
arbitrary precision, for decimal to base 2 conversion, then do pure string
operations on the base 2 number.

[James.Bottomley@HansenPartnership.com: tidy up perl with better my placement also set bc to arbitrary size]
  Link: https://lkml.kernel.org/r/dbc90c344c691ed988640a28367ff895b5ef2604.camel@HansenPartnership.com
Link: https://lkml.kernel.org/r/833c858cd74533203b43180208734b84f1137af0.camel@HansenPartnership.com
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Cc: David Howells <dhowells@redhat.com>
Cc: Blaise Boscaccy <bboscaccy@linux.microsoft.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
James Bottomley 2025-11-25 13:19:56 -05:00 committed by Andrew Morton
parent 6c790212c5
commit 0319227099

View file

@ -60,10 +60,12 @@ for (my $i = 0; $i <= $#names; $i++) {
# Determine the encoded length of this OID
my $size = $#components;
for (my $loop = 2; $loop <= $#components; $loop++) {
my $c = $components[$loop];
$ENV{'BC_LINE_LENGTH'} = "0";
my $c = `echo "ibase=10; obase=2; $components[$loop]" | bc`;
chomp($c);
# We will base128 encode the number
my $tmp = ($c == 0) ? 0 : int(log($c)/log(2));
my $tmp = length($c) - 1;
$tmp = int($tmp / 7);
$size += $tmp;
}
@ -100,16 +102,24 @@ for (my $i = 0; $i <= $#names; $i++) {
push @octets, $components[0] * 40 + $components[1];
for (my $loop = 2; $loop <= $#components; $loop++) {
my $c = $components[$loop];
# get the base 2 representation of the component
$ENV{'BC_LINE_LENGTH'} = "0";
my $c = `echo "ibase=10; obase=2; $components[$loop]" | bc`;
chomp($c);
# Base128 encode the number
my $tmp = ($c == 0) ? 0 : int(log($c)/log(2));
my $tmp = length($c) - 1;
$tmp = int($tmp / 7);
for (; $tmp > 0; $tmp--) {
push @octets, (($c >> $tmp * 7) & 0x7f) | 0x80;
# zero pad upto length multiple of 7
$c = substr("0000000", 0, ($tmp + 1) * 7 - length($c)).$c;
# Base128 encode the number
for (my $j = 0; $j < $tmp; $j++) {
my $b = oct("0b".substr($c, $j * 7, 7));
push @octets, $b | 0x80;
}
push @octets, $c & 0x7f;
push @octets, oct("0b".substr($c, $tmp * 7, 7));
}
push @encoded_oids, \@octets;