Skip to content

Editing Attachments

Jonathan D.A. Jewell edited this page Sep 15, 2026 · 1 revision

Attachments

A page can carry files. Upload one from the page's attach form and BerryWiki stores it at assets/<page-id>/<filename> in the wiki folder, alongside the Markdown, where plain git sees it like anything else. Reference it the ordinary way:

![alt](assets/0197a1c0-0000-7000-8000-000000000004/diagram.png)

The path keys on the page's id, not its filename, so renaming or moving a page does not orphan its attachments.

What is allowed

Nine extensions, matched case-insensitively, each pinned to the exact content type it will be served with:

Extension Served as
png image/png
jpg, jpeg image/jpeg
gif image/gif
webp image/webp
pdf application/pdf
txt text/plain; charset=utf-8
csv text/csv; charset=utf-8
md text/plain; charset=utf-8

This is an allow-list, not a block-list. An extension that is not in the table is refused — there is no sniffing, and no "unknown type" fallback that serves bytes with a guessed header.

Why SVG, HTML and JavaScript are not on it

An SVG served as image/svg+xml can execute script inside itself. So can an HTML file. Serving either from the same origin as the editor would be a cross-site-scripting hole that arrives looking like a picture. They are left off the list deliberately, and that is not an oversight to be fixed by adding them later.

Note the md row: Markdown uploads are served as plain text, never rendered. An uploaded file is data, not a page.

Limits

  • 1 MiB per attachment (MAX_ATTACHMENT).
  • 8 KiB for the multipart envelope around it (MAX_ENVELOPE).

Both are checked before the body is read into memory.

Two details worth knowing

The form cannot lie about what it accepts. The help text under the upload control is generated from the same ALLOWED table the request handler checks against, so the page can never advertise something the code would refuse.

A disallowed extension is a 404, not a 403. Asking for assets/<id>/payload.svg gets the same answer as asking for a file that was never uploaded. There is no route that confirms "this exists but you may not have it".

What is not there

  • No delete route. An attachment is removed by deleting the file in git.
  • Conflicts on attachments are Opaque — see Syncing and Conflicts. BerryWiki does not read the bytes to classify them, because they may not be text at all.

Clone this wiki locally