Skip to content

Commit

Permalink
continue refactor on bitfield, range section and publisher restriction
Browse files Browse the repository at this point in the history
  • Loading branch information
peczenyj committed Dec 12, 2023
1 parent d7a9a89 commit 6a4ca72
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 60 deletions.
33 changes: 6 additions & 27 deletions lib/GDPR/IAB/TCFv2.pm
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ sub check_publisher_restriction {
my ( $self, $purpose_id, $restrict_type, $vendor ) = @_;

return $self->{publisher_restrictions}
->check_publisher_restriction( $purpose_id, $restrict_type, $vendor );
->contains( $purpose_id, $restrict_type, $vendor );
}

sub _format_date {
Expand Down Expand Up @@ -495,32 +495,11 @@ sub _parse_vendor_legitimate_interests {
sub _parse_publisher_restrictions {
my ( $self, $pub_restrict_offset ) = @_;

my ( $num_restrictions, $next_offset ) =
get_uint12( $self->{data}, $pub_restrict_offset );

my %restrictions;

for ( 1 .. $num_restrictions ) {
my ( $purpose_id, $restriction_type, $vendor_restrictions );

( $purpose_id, $next_offset ) =
get_uint6( $self->{data}, $next_offset );

( $restriction_type, $next_offset ) =
get_uint2( $self->{data}, $next_offset );

( $vendor_restrictions, $next_offset ) = $self->_parse_range_section(
ASSUMED_MAX_VENDOR_ID,
$next_offset
);

$restrictions{$purpose_id} ||= {};

$restrictions{$purpose_id}->{$restriction_type} = $vendor_restrictions;
}

my $publisher_restrictions = GDPR::IAB::TCFv2::PublisherRestrictions->new(
restrictions => \%restrictions,
my ($publisher_restrictions, $next_offset) = GDPR::IAB::TCFv2::PublisherRestrictions->Parse(
data => $self->{data},
offset => $pub_restrict_offset,
max_id =>ASSUMED_MAX_VENDOR_ID,
options => $self->{options},
);

$self->{publisher_restrictions} = $publisher_restrictions;
Expand Down
8 changes: 0 additions & 8 deletions lib/GDPR/IAB/TCFv2/BitField.pm
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,6 @@ sub contains {
return is_set( $self->{data}, $id - 1 );
}

sub all {
my $self = shift;

my @data = split //, $self->{data};

return [ grep { $data[ $_ - 1 ] } 1 .. $self->{max_id} ];
}

sub TO_JSON {
my $self = shift;

Expand Down
16 changes: 10 additions & 6 deletions lib/GDPR/IAB/TCFv2/BitUtils.pm
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,11 @@ our @EXPORT_OK = qw<is_set
sub is_set {
my ( $data, $offset ) = @_;

croak "index out of bounds on offset $offset"
if $offset + 1 > length($data);
my $data_size = length($data);

croak
"index out of bounds on offset $offset: can't read 1, only has: $data_size"
if $offset + 1 > $data_size;

my $r = substr( $data, $offset, 1 ) == 1;

Expand Down Expand Up @@ -139,8 +142,6 @@ sub get_uint36 {
sub _get_bits_with_padding {
my ( $data, $bits, $offset, $nbits ) = @_;

# TODO check if offset is in range of $data ?

my ( $data_with_padding, $next_offset ) =
_add_padding( $data, $bits, $offset, $nbits );

Expand All @@ -152,8 +153,11 @@ sub _get_bits_with_padding {
sub _add_padding {
my ( $data, $bits, $offset, $nbits ) = @_;

croak "index out of bounds on offset $offset"
if $offset + $nbits > length($data);
my $data_size = length($data);

croak
"index out of bounds on offset $offset: can't read $nbits, only has: $data_size"
if $offset + $nbits > $data_size;

my $padding = "0" x ( $bits - $nbits );

Expand Down
68 changes: 55 additions & 13 deletions lib/GDPR/IAB/TCFv2/PublisherRestrictions.pm
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,65 @@ use warnings;

use Carp qw<croak>;

sub new {
use GDPR::IAB::TCFv2::BitUtils qw<is_set
get_uint2
get_uint6
get_uint12
get_uint16
get_uint36
get_char6_pair
>;

sub Parse {
my ( $klass, %args ) = @_;

my $restrictions = $args{restrictions}
or croak "missing field 'restrictions'";
croak "missing 'data'" unless defined $args{data};
croak "missing 'offset'" unless defined $args{offset};
croak "missing 'max_id'"
unless defined $args{max_id};

croak "missing 'options'" unless defined $args{options};
croak "missing 'options.json'" unless defined $args{options}->{json};

my $data = $args{data};
my $offset = $args{offset};
my $max_id = $args{max_id};
my $options = $args{options};

my ( $num_restrictions, $next_offset ) = get_uint12( $data, $offset );

my %restrictions;

for ( 1 .. $num_restrictions ) {
my ( $purpose_id, $restriction_type, $vendor_restrictions );

( $purpose_id, $next_offset ) = get_uint6( $data, $next_offset );

( $restriction_type, $next_offset ) = get_uint2( $data, $next_offset );

( $vendor_restrictions, $next_offset ) =
GDPR::IAB::TCFv2::RangeSection->Parse(
data => $data,
offset => $next_offset,
max_id => $max_id,
options => $options,
);

$restrictions{$purpose_id} ||= {};

$restrictions{$purpose_id}->{$restriction_type} = $vendor_restrictions;
}

my $self = {
restrictions => $restrictions,
restrictions => \%restrictions,
};

bless $self, $klass;

return $self;
return wantarray ? ( $self, $next_offset ) : $self;
}

sub check_publisher_restriction {
sub contains {
my ( $self, $purpose_id, $restrict_type, $vendor ) = @_;

return 0
Expand Down Expand Up @@ -62,14 +105,13 @@ GDPR::IAB::TCFv2::PublisherRestrictions - Transparency & Consent String version
=head1 SYNOPSIS
my $range = GDPR::IAB::TCFv2::PublisherRestrictions->new(
restrictions => {
purpose id => {
restriction type => instance of GDPR::IAB::TCFv2::RangeSection
},
},
my ($publisher_restrictions, $next_offset) = GDPR::IAB::TCFv2::PublisherRestrictions->Parse(
data => $self->{data},
offset => $pub_restrict_offset,
max_id =>ASSUMED_MAX_VENDOR_ID,
options => $self->{options},
);
die "there is publisher restriction on purpose id 1, type 0 on vendor 284"
if $range->contains(1, 0, 284);
Expand Down
2 changes: 1 addition & 1 deletion lib/GDPR/IAB/TCFv2/RangeSection.pm
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ sub Parse {

croak
"a BitField for vendor consent strings using RangeSections require at least 31 bytes. Got $data_size"
if $data_size < 32;
if $data_size < 31;

my ( $num_entries, $next_offset ) = get_uint12( $data, $offset );

Expand Down
10 changes: 5 additions & 5 deletions t/00-load.t
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ subtest "check interfaces" => sub {
isa_ok 'GDPR::IAB::TCFv2::Constants::SpecialFeature', 'Exporter';
isa_ok 'GDPR::IAB::TCFv2::Constants::RestrictionType', 'Exporter';

my @methods = qw<Parse contains all TO_JSON>;
my @role_methods = qw<Parse contains TO_JSON>;

can_ok 'GDPR::IAB::TCFv2::BitField', @methods;
can_ok 'GDPR::IAB::TCFv2::RangeSection', @methods;
can_ok 'GDPR::IAB::TCFv2::BitField', @role_methods;
can_ok 'GDPR::IAB::TCFv2::RangeSection', @role_methods;
can_ok 'GDPR::IAB::TCFv2::PublisherRestrictions', @role_methods;

can_ok 'GDPR::IAB::TCFv2::PublisherRestrictions',
qw<new check_publisher_restriction TO_JSON>;
can_ok 'GDPR::IAB::TCFv2::RangeSection', qw<all>;

done_testing;
};
Expand Down

0 comments on commit 6a4ca72

Please sign in to comment.