# files/privacy-breach -- lintian check script -*- perl -*- # Copyright © 1998 Christian Schwarz and Richard Braakman # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, you can find it on the World Wide # Web at http://www.gnu.org/copyleft/gpl.html, or write to the Free # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, # MA 02110-1301, USA. package Lintian::Check::Files::PrivacyBreach; use v5.20; use warnings; use utf8; use Const::Fast; use Unicode::UTF8 qw(encode_utf8); use Lintian::Pointer::Item; use Lintian::SlidingWindow; use Moo; use namespace::clean; with 'Lintian::Check'; const my $BLOCKSIZE => 16_384; const my $EMPTY => q{}; const my $PRIVACY_BREAKER_WEBSITES_FIELDS => 3; has PRIVACY_BREAKER_WEBSITES => ( is => 'rw', lazy => 1, default => sub { my ($self) = @_; return $self->profile->load_data( 'files/privacy-breaker-websites', qr/\s*\~\~/, sub { my ($regex, $tag, $suggest)= split(/ \s* ~~ \s* /msx, $_[1],$PRIVACY_BREAKER_WEBSITES_FIELDS); $tag //= $EMPTY; # trim both ends $tag =~ s/^\s+|\s+$//g; if (length($tag) == 0) { $tag = $_[0]; } my %ret = ( 'tag' => $tag, 'regexp' => qr/$regex/xsm, ); if (defined($suggest)) { $ret{'suggest'} = $suggest; } return \%ret; }); }); has PRIVACY_BREAKER_FRAGMENTS => ( is => 'rw', lazy => 1, default => sub { my ($self) = @_; return $self->profile->load_data( 'files/privacy-breaker-fragments', qr/\s*\~\~/, sub { my ($regex, $tag) = split(/\s*\~\~\s*/, $_[1], 2); return { 'keyword' => $_[0], 'regex' => qr/$regex/xsm, 'tag' => $tag, }; }); }); has PRIVACY_BREAKER_TAG_ATTR => ( is => 'rw', lazy => 1, default => sub { my ($self) = @_; return $self->profile->load_data( 'files/privacy-breaker-tag-attr', qr/\s*\~\~\s*/, sub { my ($keywords,$regex) = split(/\s*\~\~\s*/, $_[1], 2); $regex =~ s/&URL/(?:(?:ht|f)tps?:)?\/\/[^"\r\n]*/g; my @keywordlist; my @keywordsorraw = split(/\s*\|\|\s*/,$keywords); foreach my $keywordor (@keywordsorraw) { my @keywordsandraw = split(/\s*&&\s*/,$keywordor); push(@keywordlist, \@keywordsandraw); } return { 'keywords' => \@keywordlist, 'regex' => qr/$regex/xsm, }; }); }); sub detect_privacy_breach { my ($self, $file) = @_; my %privacybreachhash; return unless $file->is_regular_file; my $pointer = Lintian::Pointer::Item->new; $pointer->item($file); open(my $fd, '<:raw', $file->unpacked_path) or die encode_utf8('Cannot open ' . $file->unpacked_path); my $sfd = Lintian::SlidingWindow->new; $sfd->handle($fd); $sfd->blocksize($BLOCKSIZE); while (my $block = $sfd->readwindow) { my $lowercase = lc($block); # strip comments for my $x (qw(