This file is indexed.

/usr/share/perl5/Image/MetaData/JPEG/access/comments.pl is in libimage-metadata-jpeg-perl 0.153-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
###########################################################
# A Perl package for showing/modifying JPEG (meta)data.   #
# Copyright (C) 2004,2005,2006 Stefano Bettelli           #
# See the COPYING and LICENSE files for license terms.    #
###########################################################
package Image::MetaData::JPEG;
use Image::MetaData::JPEG::Segment;
no  integer;
use strict;
use warnings;

###########################################################
# This method accepts a string and returns a list whose   #
# elements are not larger than the length limit imposed   #
# by a JPEG segment: a segment cannot have a length which #
# couldn't be written in a 2-byte unsigned integer, that  #
# is 2^16 - 1; since the byte count must be written in    #
# this space, the real comment is limited to 2^16 - 3.    #
# The length of all but the last element in the list is   #
# maximal. The input string is not changed. Note that ""  #
# maps to (""), while an undefined value maps to (). So,  #
# it is possible to specify an empty comment.             #
###########################################################
{ my $max_length = 2**16 - 3;
  sub split_comment_string {
      return () unless defined $_[0];
      map { substr $_[0], $max_length*$_, $max_length }
      0 .. (-1 + length $_[0]) / $max_length;
  }
}

###########################################################
# This method returns the number of comment segments in   #
# the picture (it should be as fast as possible).         #
###########################################################
sub get_number_of_comments {
    my ($this) = @_;
    # return the length of the output of this method
    return scalar $this->get_segments('COM');
}

###########################################################
# This method returns a list, with an element for each    #
# comment block in the file (the element contains the     #
# comment string). Note that an empty list can be retur-  #
# ned (in case there are no comment blocks).              #
###########################################################
sub get_comments {
    my ($this) = @_;
    # loop over all segments, and return the appropriate
    # field of those which are comments.
    my @com_segs = $this->get_segments('COM');
    return map { $_->search_record_value('Comment') } @com_segs;
}

###########################################################
# This method adds one or more new comment segments to    #
# the JPEG file, based on the string passed by the user.  #
# If there is already at least one comment segment, the   #
# new segments are created right after the last one.      #
# Otherwise, the standard position search is applied.     #
# ------------------------------------------------------- #
# In case the passed string is too big (there is a 64KB   #
# limit in JPEG segments), it is broken down in smaller   #
# strings and multiple "Comment" segments are inserted in #
# the file (they are contiguous).                         #
###########################################################
sub add_comment {
    my ($this, $string) = @_;
    # create one or more comment blocks, based on the user
    # string; the string must be split if it is too long.
    my @new_comments = 
	map { new Image::MetaData::JPEG::Segment("COM", \ $_) }
        split_comment_string($string);
    # get the list of comment indexes
    my @indexes = $this->get_segments('COM', 'INDEXES');
    # our position is right after the last comment
    my $position = @indexes ? 1 + $indexes[$#indexes] : undef;
    # actually insert the comments (we don't need update() here);
    # if position is undefined, the standard search is used
    $this->insert_segments(\ @new_comments, $position);
}

###########################################################
# This method replaces the $index-th comment segment with #
# one or more new segments based on $string (the index of #
# the first comment segment is 0). If $string is too big  #
# (see add_comment), it is broken down and multiple seg-  #
# ments are created. If $string is undef, the comment     #
# segment is erased. If $index is out-of-bound, only a    #
# warning is printed.                                     #
###########################################################
sub set_comment {
    my ($this, $index, $string) = @_;
    # return immediately if $index is negative or undefined
    return $this->warn('Undefined $index') unless defined $index;
    return $this->warn("Negative index ($index)") if $index < 0;
    # get the list of comment segment indexes
    my @indexes = $this->get_segments('COM', 'INDEXES');
    # if $index is out of bound, warn and return. 
    return $this->warn("Index $index out of bound [0,$#indexes]")
	if ($#indexes < $index);
    # otherwise, set an index to the target comment segment
    my $position = $indexes[$index];
    # create one or more comment blocks, based on the user
    # string; the string must be split if it is too long.
    my @new_comments = 
	map { new Image::MetaData::JPEG::Segment('COM', \ $_) }
        split_comment_string($string);
    # replace the target segment with the new segments created
    # from the user string; @new_comments is the void list if
    # $string is undefined (this stands for comment deletion).
    # Since all comments are deleted or added, but not modified,
    # there is no need to call update here!
    $this->insert_segments(\ @new_comments, $position, 1);
}

###########################################################
# This method eliminates the $index-th comment segment    #
# (first index is 0). It is only a shortcut for the more  #
# general set_comment (called with $string = undef).      #
###########################################################
sub remove_comment {
    my ($this, $index) = @_;
    # call set_comment with an undefined string
    $this->set_comment($index, undef);
}

###########################################################
# This method (a wrapper around the drop_segments method) #
# eliminates all comments currently present in the pic.   #
###########################################################
sub remove_all_comments {
    my ($this) = @_;
    # use this more general method
    $this->drop_segments('^COM$');
}

###########################################################
# This method joins some comments into a single one, with #
# the supplied separation string. This utility is neces-  #
# sary because there are readers out there which do not   #
# read past the first comment. This method overwrites the #
# first comment selected by the arguments and delete the  #
# others. A warning is issued for each illegal comment    #
# index (undefined, not a number, out of range).          #
# The final comment length is checked (<64Kb).            #
# ------------------------------------------------------- #
# If no separation string is provided, it defaults to \n. #
# If no index is provided in @selection, it is assumed    #
# that the method must join all the comments into the     #
# first one, and delete the others.                       #
###########################################################
sub join_comments {
    my ($this, $separation, @selection) = @_;
    # get all the comment indexes
    my @indexes = $this->get_segments('COM', 'INDEXES');
    # get all the comment strings
    my @comments = $this->get_comments();
    # an undefined separation string defaults to "\n"
    $separation = "\n" unless defined $separation;
    # an undefined @selection stands for "all the indexes"
    @selection = 0..$#indexes unless @selection;
    # discard the elements of @selection which do not make
    # sense, and leave the others in ascending numerical order
    @selection = sort {$a <=> $b} map {
	my $error = undef;
	if    (! defined $_)         { $error = "Undefined comment index"; }
	elsif ($_ =~ /[^\d]/)        { $error = "'$_' not a whole number"; }
	elsif ($_<0 || $_>$#indexes) { $error = "index $_ out of range"; }
	$this->die("$error: discarding index") if defined $error;
	defined $error ? () : $_;
    } @selection;
    # return immediately if @selection is empty
    $this->die('No valid comment indexes') unless @selection;
    # concatenate valid comments in a single string (write a copy
    # of the separation string between every two comments).
    my $joint_comment = join $separation, map { $comments[$_] } @selection;
    # extract the first comment segment index in the selection list
    # as the target segment index. Then remove all other comments;
    # be careful to remove comments starting from higher indexes!
    my $target_index = shift @selection;
    $this->remove_comment($_) for (sort {$b <=> $a} @selection);
    # replace the target comment with $joint_comment
    $this->set_comment($target_index, $joint_comment);
}

# successful package load
1;