Repository navigation
Read signed .p7m files as the file inside them - #1096
Merged
Merged
Conversation
KnifeLemon
force-pushed
the
feat/p7m-signed-files
branch
from
November 4, 2026 04:08
f61fe18 to
01c483c
Compare
A .p7m is a CMS / PKCS #7 SignedData envelope (Italian e-invoices *.xml.p7m, signed PDFs *.pdf.p7m). The new built-in "p7m" engine takes the signed file out with SignedCms (DER, BER, Base64 or PEM; envelopes signed again are opened again, at most 8 deep; at most 512 MB). The signature is not verified or trusted: no chain, no revocation, no network. The format inside comes from the inner name (invoice.xml.p7m) or the first bytes. A new IEnvelopeOpener lets JobQueue ask for it before planning, and RoutePlanner.PlanThrough opens the envelope first and plans on from there, so P7M -> PDF -> PNG and P7M -> XML -> JSON are one conversion. Outputs are named after the file inside (invoice.pdf.p7m -> invoice.pdf). p7m is a read-only document input graded general; the documents donut learns it (schema 66). New strings are in all 20 languages. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
KnifeLemon
force-pushed
the
feat/p7m-signed-files
branch
from
November 4, 2026 04:53
4359688 to
90403b5
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Filee now reads
.p7msigned files. It takes the signed file out of the envelope, then converts it on from its own format:invoice.pdf.p7m→invoice.pdf, or →invoice.pngthrough PDFium;IT…_FPA01.xml.p7m→ XML, or → JSON through the data engine. The.p7mis left as it was.Why
#1010 asked for Italian e-signatures. A
.p7mis a CMS / PKCS #7 SignedData envelope (CAdES), the usual form for Italian e-invoices (*.xml.p7m) and signed PDFs (*.pdf.p7m). It is signed, not encrypted, so the original can be taken out as it is.How
p7mis a read-only document input (FORMAT-RULES rule 5), graded general inFormatFields. Every Italian business sends and receives these, but they come from signing tools, not a mainstream consumer default. The General count inFormatFieldsTestsgoes from 94 to 95. New installs get it on the documents donut (its category's extensions). Existing libraries learn the extension with a v66LearnExtensionsstep, as FIT and KRA did, and no slot changes. The schema goes to 66, because feat(tools): Add background tool #1081 (Add background) took 64 and Read DBML database schemas as text (#854) #1094 (DBML) took 65 on main.Signed/P7mConverter.cs(p7m, built in): reads the file (at most 512 MB) and decodes Base64 / PEM text when it isn't DER. It checks the content type: SignedData is opened withSignedCms.Decode; EnvelopedData (encrypted S/MIME) is refused with its own reason. It unwraps again while the content is itself a SignedData, at most 8 deep. The signature is not verified or trusted: no chain building, no revocation, no network. The code comment says so, and so does the engine description in Settings → Engines.System.Security.Cryptography.Pkcswas already referenced byFilee.Engines.csprojand is used here for the first time.invoice.xml.p7m→ XML). Otherwise the first bytes decide: PDF and pictures (WebFormats.Sniff), XML, HTML, RTF, a MIME message (→ EML), ZIP with DOCX / XLSX / PPTX / ODT / ODS / ODP / EPUB recognised by their parts, or plain UTF-8 text..gzonly convert among archive formats, so I added a small, general hook:IEnvelopeOpener(Core):Opens(format)andInnerFormat(path, format).JobQueue.RunFileAsyncasks the opener before planning. Then target "same format", frames, OCR, translation and the "no route" detail all use the inner format.RoutePlanner.PlanThrough(from, through, to, …)gives the opening step first, thenPlan(through, to). So a signed scanned PDF with OCR on goes P7M → PDF → OCR → DOCX.p7mto every known format, so donut availability is what some inner file could become. At run time the route is exact, and an XML inside a "to MP4" slot fails withno route xml → mp4..p7mbytes over the result) are skipped.FormatRegistry.NameWithoutExtensionalso drops a known inner extension behind.p7m(invoice.pdf.p7m→invoice,contract.pdf.p7m.p7m→contract,report.final.p7m→report.final). Output names and the "ask where to save" name follow it.engine.p7m.nameandengine.p7m.description, pluserror.p7m_unreadable,_detached,_encrypted,_unknown_contentand_too_large. All are in all 20 language files,vi.jsonincluded.Tests
P7mTests(Engines, 8). A self-signed RSA certificate is made in the test and content is signed withSignedCms; there are no sample files. The tests cover:invoice.pdf, and going on toinvoice.png;EnvelopedCms) and unknown content;xml → mp4as the no-route detail.EnvelopeTests(Core, 13): the name rules, the format and documents donut, the v66 migration running once,PlanThrough(it never takes the directp7m → pngedge for a PDF inside), andJobQueuewith a fake opener (outputs named after the inner file, refusal reasons passed through, no route reported from the inner format).FormatFieldsTestsincluded). In Engines,P7mTestsandFonTestspass.FonTestsnow leaves the envelope opener out of its 'nothing makes FON' check:p7m → fonopens a signed FON and doesn't write one. In App,LocalizationTests,DefaultPlacement,*Availability*and*Engine*pass 276 of 276. The build anddotnet format --verify-no-changesare clean.Closes #1010
🤖 Generated with Claude Code