CodamAIDocs
Topicdone

Pictures and SVG

Three ways to a picture in the document: assets of the template (asset:<name>), attachments of the request (attachment:<name>, PNG or JPEG) and SVG from the payload through crms.svg with an allow-list. What is refused.

Variants
asset of the revision (asset:<name>)attachment of the request (attachment:<name>)SVG from the payload (crms.svg)attachment refused (name, type, content, limits)attachments with FINAL or the wrong formatSVG outside the allow-list

What this is about

A report often needs pictures: the customer’s logo, a signature, photos of an inspection, a diagram. CRMS never loads anything from the network or the file system. A picture reaches the document in exactly one of three ways.

The three ways

Where a picture comes from
AssetAttachmentSVG
Belongs tothe template's revisionthe one requestthe payload, as text
In the templateasset:<name>attachment:<name>${crms.svg(field)}
Allowed kindswhat the template approved, e.g. logo, fontimage/png, image/jpegSVG within the allow-list
FormatsHTML, PDF, DOCXPDF onlyHTML, PDF, DOCX
With FINALyesnoyes

You upload assets with the template, see How a template is built. The two namespaces asset: and attachment: stay apart. An attachment can never replace an asset of the approved revision, not even with the same name.

Attachments: pictures of this one request

An attachment is a picture that exists only for this call. Which picture the template shows is usually decided by the payload: the template writes <img src="attachment:${signature}"/>, and you put the name into the payload.

Request
POST /crms/render
Content-Type: application/json
Content-Encoding: gzip
{
  "template": "inspection-report",
  "format": "PDF",
  "mode": "TRANSIENT",
  "data": { "signature": "signature-inspector.png" },
  "attachments": [
    { "name": "signature-inspector.png",
      "contentType": "image/png",
      "content": "iVBORw0KGgo…" }
  ]
}
Response
HTTP 200
Content-Type: application/pdf

%PDF-1.7 …   ← the signature is in the PDF

Over REST, each attachment comes with name, contentType and content in Base64. Base64 makes the data a third larger. With Content-Encoding: gzip you get almost all of it back; crms-client compresses requests with attachments by itself. Embedded, you pass the bytes directly as a RenderAttachment.

CRMS checks the attachments together with the payload and reports all violations in one answer (422 payload-rejected). The field is attachments[<i>], the position in the list, or attachments for a limit.

RuleWhen
attachments-too-many|<max>more attachments than allowed (default 200, CODAMAI_CRMS_ATTACHMENTS_MAX_COUNT)
attachments-too-large|<max>together larger than allowed (default 50 MiB, CODAMAI_CRMS_ATTACHMENTS_MAX_BYTES)
name-invalidnot a plain file name: letters, digits, ., _, - are allowed, at most 128 characters, not starting with .
name-duplicatean earlier attachment of this request already has the same name
type-not-allowedneither image/png nor image/jpeg
emptyno bytes
content-mismatchthe bytes do not start like a PNG or JPEG file, as declared

Beyond a limit, CRMS no longer looks at the attachments one by one.

Attachments present?ModeFormatResult
no––no check of attachments
yesFINAL–422 attachments-not-for-final
yesPREVIEW or TRANSIENTHTML, DOCX, XLSX, CSV, ODS422 attachments-not-for-format|<format>
yesPREVIEW or TRANSIENTPDFattachments are checked and drawn

If the template names an attachment:<name> the request does not bring, the PDF fails with render-resource-refused. CRMS does not hand out a document with holes where pictures should be.

SVG from the payload: crms.svg

A diagram your application draws itself, for example a topology, you send as SVG text in the payload. Normally a template always writes text from the payload as text, never as markup: ${diagram} shows the angle brackets. It only reaches the document as a graphic through the function crms.svg, which every template has:

<div class="figure">${crms.svg(diagram)}</div>

crms belongs to CRMS. A payload field named crms does not replace the function.

CRMS reads the SVG as XML, without DTD and without entities other than the five predefined ones, and checks it against an allow-list:

WhatAllowedNot allowed
Root<svg> in the SVG namespaceanything else
Elementssvg, g, defs, symbol, use, path, rect, circle, ellipse, line, polyline, polygon, text, tspan, textPath, linearGradient, radialGradient, stop, marker, clipPath, title, desc, styleamong others script, foreignObject, image, a, animations, filter, metadata
Attributesgeometry, fill and stroke, text, gradients, markers, id, class, style, aria-*, plus xlink:href, xml:space, xml:langany on… attribute, attributes from other namespaces
Referencesonly to a place in the same SVG: href="#id", url(#id)any address outside
CSSin style attributes and <style>@import, CSS escapes with \

CRMS removes an XML declaration at the start. The rest goes into the document exactly as it was checked. If something is not allowed, rendering fails with 422 template-svg-rejected. CRMS cleans nothing out, because a diagram with silently removed parts would be a wrong diagram. A value that is not text, for example a number, is also template-svg-rejected.

Output typeWhat crms.svg makes of it
DOCUMENTHTML shows the SVG inline. PDF draws it as vector graphics, without scripts and without external resources. If it cannot be drawn, that is render-pdf-failed
WORDThe function writes a placeholder that must stand where a run stands in Word, that is inside a <w:p>. CRMS checks the SVG once more, converts it into a PNG and inserts it as a picture at its declared size. The SVG’s <title> becomes the picture description
TABLErefused: template-svg-not-for-output-type|table

For DOCX, CRMS reads the size from width and height of the root (px, pt, pc, mm, cm, in). If they are missing, it uses the viewBox, otherwise 300 × 150 pixels. The PNG has twice the pixels so it stays sharp in print, at most 4096 pixels per side.

Pitfalls

Next

Search