Mail::...PDFInfo(3pm)
π NAME π
Mail::SpamAssassin::Plugin::PDFInfo β bestie, this is the SpamAssassin plugin that catches spam by staring real hard at the PDF files people attach to your mail. It's the plugin page from the User Contributed Perl Documentation collection, section 3pm of the manual, and yes she's a whole vibe. π
β¨ SYNOPSIS β¨
loadplugin Mail::SpamAssassin::Plugin::PDFInfo
That's it. One line and she's loaded into your config. Slay. π
π¦ DESCRIPTION π¦
So this plugin exists to help detect spam using attached PDF files. That's the whole mission statement, no cap. πβ
And then it says: see "Usage:" below β and for more documentation go look at 20_pdfinfo.cf.
After that, the page just keeps a big ol' slab of original info for the history books, because the maintainers are sentimental like that. For later changes you go check the SVN repo. Here's the vintage text, preserved exactly as she was born, no edits, no filter, iconic behavior:
Original info kept for history. For later changes see SVN repo
-------------------------------------------------------
PDFInfo Plugin for SpamAssassin
Version: 0.8
Info: $Id: PDFInfo.pm 904 2007-08-12 01:36:23Z root $
Created: 2007-08-10
Modified: 2007-08-10
By: Dallas Engelken
Changes:
0.8 - added .fdf detection (thanks John Lundin) [axb]
0.7 - fixed empty body/pdf count buglet(thanks Jeremy) [axb]
0.6 - added support for tags - PDFCOUNT, PDFVERSION, PDFPRODUCER, etc.
- fixed issue on perl 5.6.1 where pdf_match_details() failed to call
_find_pdf_mime_parts(), resulting in no detection of pdf mime parts.
- quoted-printable support - requires MIME::QuotedPrint (which should be in everyones
install as a part of the MIME-Base64 package which is a SA req)
- added simple pdf_is_empty_body() function with counts the body bytes minus the
subject line. can add optional <bytes> param if you need to allow for a few bytes.
0.5 - fix warns for undef $pdf_tags
- remove { } and \ before running eval in pdf_match_details to avoid eval error
0.4 - added pdf_is_encrypted() function
- added option to look for image HxW on same line
0.3 - added 2nd fuzzy md5 which uses pdf tag layout as data
- renamed pdf_image_named() to pdf_named()
- PDF images are encapsulated and have no names. We are matching the PDF file name.
- renamed pdf_image_name_regex() to pdf_name_regex()
- PDF images are encapsulated and have no names. We are matching the PDF file name.
- changed pdf_image_count() a bit and added pdf_count().
- pdf_count() checks how many pdf attachments there are on the mail
- pdf_image_count() checks how many images are found within all pdfs in the mail.
- removed the restriction of the pdf containing an image in order to md5 it.
- added pdf_match_details() function to check the following 'details'
- author: Author of PDF if specified
- producer: Software used to produce PDF
- creator: Software used to produce PDF, usually similar to producer
- title: Title of PDF
- created: Creation Date
- modified: Last Modified
0.2 - support PDF octet-stream
0.1 - just ported over the imageinfo code, and renamed to pdfinfo.
- removed all support for png, gif, and jpg from the code.
- prepended pdf_ to all function names to avoid conflicts with ImageInfo in SA 3.2.
she's been through eight glow-ups and every single one ate π
πΈ Usage: πΈ
Okay bestie, here's the menu of eval functions you can call from your rules. Each one goes in a body rule with a RULENAME you pick, like:
body RULENAME eval:pdf_count(<min>,[max])
Let's go one by one, no skipping, I know you'd never. π«Ά
π pdf_count()
body RULENAME eval:pdf_count(<min>,[max])
min: required β the message contains at leastxpdf mime parts.max: optional β if you specify it, the message must not contain more thanxpdf mime parts.
π pdf_image_count()
body RULENAME eval:pdf_image_count(<min>,[max])
min: required β the message contains at leastximages in pdf attachments.max: optional β if you specify it, it must not contain more thanxpdf images.
π pdf_uri_count()
body RULENAME eval:pdf_uri_count(<min>,[max])
min: required β the message contains at leastxuris in pdf attachments.max: optional β if you specify it, it must not contain more thanxpdf uris.
π pdf_pixel_coverage()
body RULENAME eval:pdf_pixel_coverage(<min>,[max])
min: required β the message contains at least this much pixel area.max: optional β if you specify it, the message must not contain more than this much pixel area.
π pdf_named()
body RULENAME eval:pdf_named(<string>)
string: exact file name match. If you need a partial match, go seepdf_name_regex()instead, bestie, they're a duo. βοΈ
π pdf_name_regex()
body RULENAME eval:pdf_name_regex(<regex>)
regex: a regular expression β peep the examples in the ruleset.
π pdf_match_md5()
body RULENAME eval:pdf_match_md5(<string>)
string: 32-byte md5 hex.
π pdf_match_fuzzy_md5()
body RULENAME eval:pdf_match_fuzzy_md5(<string>)
string: 32-byte md5 hex β see the ruleset for how to obtain the fuzzy md5.
π pdf_match_details()
body RULENAME eval:pdf_match_details(<detail>,<regex>);
detail:author,creator,created,modified,producer,titleregex: a regular expression β see the examples in the ruleset.
π pdf_is_encrypted()
body RULENAME eval:pdf_is_encrypted()
π pdf_has_form()
body RULENAME eval:pdf_has_form()
π pdf_has_script()
body RULENAME eval:pdf_has_script()
π pdf_has_auto_script()
body RULENAME eval:pdf_has_auto_script()
π pdf_is_empty_body()
body RULENAME eval:pdf_is_empty_body(<bytes>)
bytes: maximum byte count to allow and still consider it empty.
π pdf_image_to_text_ratio()
body RULENAME eval:pdf_image_to_text_ratio(<min>,<max>)
- Ratio calculated as
body_length / total_image_area min: minimum ratiomax: maximum ratio
π pdf_image_size_exact()
body RULENAME eval:pdf_image_size_exact(<h>,<w>)
h: image height is exactlyhw: image width is exactlyw
π pdf_image_size_range()
body RULENAME eval:pdf_image_size_range(<minh>,<minw>,[<maxh>],[<maxw>])
minh: image height is atleastminhminw: image width is atleastminwmaxh: (optional) image height is no more thanmaxhmaxw: (optional) image width is no more thanmaxw
NOTE: See the ruleset for more examples that are not documented here. π The plugin is lowkey keeping secrets from this manual and honestly? relatable.
and that's the whole page, periodt. π This little legend came to you from perl v5.40.1, dated 2026-07-23, and it lives under Mail::...PDFInfo(3pm). Take care of her, she's been catching bad PDFs since 2007. π¦ππ
π¦ where this page comes from
- ubuntu stonking: spamassassin 4.0.2+svn1935691-1build1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms