This file is indexed.

/usr/share/perl5/Mail/IMAPClient/BodyStructure/Parse.grammar is in libmail-imapclient-perl 3.30-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
# Directives
# ( none)
# Start-up Actions

{
    my $mibs  = "Mail::IMAPClient::BodyStructure";
    my $subpartCount = 0;
    my $partCount    = 0;

    sub take_optional_items($$@)
    {   my ($r, $items) = (shift, shift);
        foreach (@_)
        {   my $opt = $_ .'(?)';
            exists $items->{$opt} or next;
            $r->{$_} = UNIVERSAL::isa($items->{$opt}, 'ARRAY')
                     ? $items->{$opt}[0] : $items->{$opt};
        }
    }

    sub merge_hash($$)
    {   my $to   = shift;
        my $from = shift or return;
	while( my($k,$v) = each %$from) { $to->{$k} = $v }
    }
}

# Atoms

TEXT:		/^"TEXT"|^TEXT/i 	{ $return = "TEXT"   }
PLAIN:		/^"PLAIN"|^PLAIN/i 	{ $return = "PLAIN"  }
HTML:		/"HTML"|HTML/i 		{ $return = "HTML"   }
MESSAGE:	/^"MESSAGE"|^MESSAGE/i 	{ $return = "MESSAGE"}
RFC822:		/^"RFC822"|^RFC822/i  	{ $return = "RFC822" }
NIL:		/^NIL/i			{ $return = "NIL"    }
RFCNONCOMPLY:	/^\(\)/i		{ $return = "NIL"    }
NUMBER:		/^(\d+)/		{ $return = $item[1] }

# Strings:

SINGLE_QUOTED_STRING: "'" /(?:\\'|[^'])*/ "'" { $return = $item{__PATTERN1__} }
DOUBLE_QUOTED_STRING: '"' /(?:\\"|[^"])*/ '"' { $return = $item{__PATTERN1__} }

BARESTRING:	...!/^[)('"]/	/^(?!\(|\))(?:\\ |\S)+/
	{ $return = $item{__PATTERN1__} }

STRING:		DOUBLE_QUOTED_STRING | SINGLE_QUOTED_STRING | BARESTRING

STRINGS:	"(" STRING(s) ")" { $return = $item{'STRING(s)'} }

textlines:	NIL | NUMBER

rfc822message:  MESSAGE RFC822    { $return = "MESSAGE RFC822" }

bodysubtype:	PLAIN | HTML | NIL | STRING

key:		STRING
value:		NIL | NUMBER | STRING | KVPAIRS

kvpair:		...!")" key value
	{ $return = { $item{key} => $item{value} } }

KVPAIRS:	"(" kvpair(s) ")"
       { $return = { map { (%$_) } @{$item{'kvpair(s)'}} } }

bodytype:	STRING
bodyparms:	NIL | KVPAIRS
bodydisp:	NIL | KVPAIRS
bodyid:		...!/[()]/ NIL | STRING
bodydesc:	...!/[()]/ NIL | STRING
bodysize:	...!/[()]/ NIL | NUMBER
bodyenc:	NIL | STRING | KVPAIRS
bodyMD5:	NIL | STRING
bodylang:	NIL | STRING | STRINGS
bodyextra:	NIL | STRING | STRINGS
bodyloc:	NIL | STRING

personalname:	NIL | STRING
sourceroute:	NIL | STRING
mailboxname:	NIL | STRING
hostname:	NIL | STRING

addressstruct:	"(" personalname sourceroute mailboxname hostname ")"
	{ bless { personalname => $item{personalname}
		, sourceroute  => $item{sourceroute}
		, mailboxname  => $item{mailboxname}
		, hostname     => $item{hostname}
	        }, 'Mail::IMAPClient::BodyStructure::Address';
	}

subject:	NIL | STRING
inreplyto:	NIL | STRING
messageid:	NIL | STRING
date:		NIL | STRING

ADDRESSES:	NIL | RFCNONCOMPLY
	| "(" addressstruct(s) ")" { $return = $item{'addressstruct(s)'} }

cc:		ADDRESSES
bcc:		ADDRESSES
from:		ADDRESSES
replyto:	ADDRESSES
sender:		ADDRESSES
to:		ADDRESSES

envelopestruct:	"(" date subject from sender replyto to cc
	        bcc inreplyto messageid ")"
	{ $return = bless {}, "Mail::IMAPClient::BodyStructure::Envelope";
	  $return->{$_} = $item{$_}
	     for qw/date subject from sender replyto to cc/
	       , qw/bcc inreplyto messageid/;
	  1;
	}

basicfields: 	bodysubtype bodyparms(?) bodyid(?)
		bodydesc(?) bodyenc(?) bodysize(?)
	{  $return = { bodysubtype => $item{bodysubtype} };
	   take_optional_items($return, \%item,
	      qw/bodyparms bodyid bodydesc bodyenc bodysize/);
	   1;
	}

textmessage: 	TEXT <commit> basicfields textlines(?) bodyMD5(?)
		bodydisp(?) bodylang(?) bodyextra(?)
	{
	  $return = $item{basicfields} || {};
	  $return->{bodytype} = 'TEXT';
	  take_optional_items($return, \%item
            , qw/textlines bodyMD5 bodydisp bodylang bodyextra/);
	  1;
	}

othertypemessage: bodytype basicfields bodyMD5(?) bodydisp(?)
	          bodylang(?) bodyextra(?)
	{ $return = { bodytype => $item{bodytype} };
	  take_optional_items($return, \%item
             , qw/bodyMD5 bodydisp bodylang bodyextra/ );
	  merge_hash($return, $item{basicfields});
	  1;
	}

nestedmessage:	rfc822message <commit> bodyparms bodyid bodydesc bodyenc
#		bodysize envelopestruct bodystructure textlines
		bodysize envelopestruct(?) bodystructure(?) textlines(?)
		bodyMD5(?) bodydisp(?) bodylang(?) bodyextra(?)
	{
	  $return = {};
	  $return->{$_} = $item{$_}
	      for qw/bodyparms bodyid bodydesc bodyenc bodysize/;
#             envelopestruct bodystructure textlines/;

	  take_optional_items($return, \%item
            , qw/envelopestruct bodystructure textlines/
	    , qw/bodyMD5 bodydisp bodylang bodyextra/);

	  merge_hash($return, $item{bodystructure}[0]);
	  merge_hash($return, $item{basicfields});
	  $return->{bodytype}    = "MESSAGE" ;
	  $return->{bodysubtype} = "RFC822" ;
	  1;
	}

multipart:	subpart(s) <commit> bodysubtype
		bodyparms(?) bodydisp(?) bodylang(?) bodyloc(?) bodyextra(?)
		<defer: $subpartCount = 0>
	{ $return =
	    { bodysubtype   => $item{bodysubtype}
	    , bodytype      => 'MULTIPART'
	    , bodystructure => $item{'subpart(s)'}
	    };
	  take_optional_items($return, \%item
              , qw/bodyparms bodydisp bodylang bodyloc bodyextra/);
	  1;
	}

subpart:  "(" part ")" {$return = $item{part}} <defer: ++$subpartCount;>

part:	  multipart        { $return = bless $item{multipart}, $mibs }
	| textmessage      { $return = bless $item{textmessage}, $mibs }
	| nestedmessage    { $return = bless $item{nestedmessage}, $mibs }
	| othertypemessage { $return = bless $item{othertypemessage}, $mibs }

bodystructure:	"(" part(s) ")"
	{ $return = $item{'part(s)'} }

start:		/.*?\(.*?BODYSTRUCTURE \(/i part(1)  /\).*\)\r?\n?/
	{ $return = $item{'part(1)'}[0] }

envelope:	/.*?\(.*?ENVELOPE/ envelopestruct /.*\)/
	{ $return = $item{envelopestruct} }