{"record":{"id":"dc518c4e79f77094","repo":"666ghj/MiroFish","slug":"generated-svg-contains-an-unreviewed-image","errorCode":null,"errorMessage":"generated SVG contains an unreviewed image","messagePattern":"generated SVG contains an unreviewed image","errorType":"exception","errorClass":"StarHistoryError","httpStatus":null,"severity":"error","filePath":"scripts/star_history.py","lineNumber":1219,"sourceCode":"                \"y\": \"12\",\n                \"width\": \"22\",\n                \"height\": \"22\",\n                \"href\": OWNER_AVATAR_DATA_URI,\n                \"clip-path\": \"url(#clip-circle-title)\",\n            }\n            watermark_attributes = {\n                \"x\": \"635\",\n                \"y\": \"508.333\",\n                \"width\": \"20\",\n                \"height\": \"20\",\n                \"href\": WATERMARK_LOGO_DATA_URI,\n            }\n            if element.attrib == avatar_attributes:\n                avatar_count += 1\n            elif element.attrib == watermark_attributes:\n                watermark_count += 1\n            else:\n                raise StarHistoryError(\"generated SVG contains an unreviewed image\")\n        for raw_name, value in element.attrib.items():\n            if raw_name.startswith(\"{\") or raw_name not in allowed_for_element:\n                raise StarHistoryError(\"generated SVG contains a forbidden attribute\")\n            if (\n                not value.isascii()\n                or \"\\\\\" in value\n                or \"/*\" in value\n                or \"*/\" in value\n                or any(ord(character) < 0x20 for character in value)\n            ):\n                raise StarHistoryError(\"generated SVG contains an unsafe attribute value\")\n            exact_values = exact_attribute_values.get(raw_name)\n            if exact_values is not None and value not in exact_values:\n                raise StarHistoryError(\"generated SVG contains an unsafe attribute value\")\n            if raw_name == \"href\":\n                if local_name != \"image\" or value not in {\n                    OWNER_AVATAR_DATA_URI,\n                    WATERMARK_LOGO_DATA_URI,","sourceCodeStart":1201,"sourceCodeEnd":1237,"githubUrl":"https://github.com/666ghj/MiroFish/blob/b5b53acc57189a4a42e44a23e149dc655c98fe82/scripts/star_history.py#L1201-L1237","documentation":"Raised by `_validate_svg`'s image audit (scripts/star_history.py:1219). `<image>` elements are permitted only in exactly two reviewed forms: the owner avatar (fixed x/y/size, OWNER_AVATAR_DATA_URI href, clip-path) and the watermark logo (WATERMARK_LOGO_DATA_URI). Any other `<image>` — different geometry, href, or extra attributes — is 'unreviewed' and rejected, since images are the main data-URI injection channel.","triggerScenarios":"An `<image>` element whose `element.attrib` dict is not byte-identical to `avatar_attributes` or `watermark_attributes`: changed coordinates, a different/extra attribute, a swapped data URI, or a third image added by fork code. Even a reordered-but-equal dict is fine (dict equality ignores order), but any value change fires.","commonSituations":"Forks repositioning the avatar/watermark or substituting their own logo data URI without updating the reviewed attribute sets; attempts to embed arbitrary pictures; template refactors that add `opacity` or `id` to the image elements.","solutions":["If you forked branding: replace OWNER_AVATAR_DATA_URI / WATERMARK_LOGO_DATA_URI constants rather than editing the `<image>` attributes, and keep geometry exactly as templated.","If geometry must change, update both the template and the mirrored `avatar_attributes`/`watermark_attributes` literals inside `_validate_svg` so the audit stays in sync.","Never add extra `<image>` elements; the design allows exactly one avatar and one watermark.","Diff your rendered SVG against a known-good output to find which attribute diverged."],"exampleFix":"# fork: swap branding safely\n# before: template edited to <image href=\"data:image/png;base64,MYLOGO...\" ...> alongside old audit -> raises\n\n# after: keep the template untouched; replace the constant\nOWNER_AVATAR_DATA_URI = \"data:image/png;base64,MYLOGO...\"  # geometry & audit unchanged","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    _validate_svg(payload)\nexcept StarHistoryError as exc:\n    if \"unreviewed image\" in str(exc):\n        raise ValueError(\"<image> must exactly match the avatar or watermark template\") from exc\n    raise","preventionTips":["Change branding by swapping the OWNER_AVATAR_DATA_URI/WATERMARK_LOGO_DATA_URI constants, not the <image> attributes.","Keep image geometry (x/y/width/height/clip-path) byte-identical to the reviewed literals if you must move them — update both template and audit together.","Never allow external http(s) hrefs on images; the reviewed set is data-URI only."],"tags":["svg","image","data-uri","security","self-check"],"backgroundTag":null,"analyzedSha":"b5b53acc57189a4a42e44a23e149dc655c98fe82","analyzedAt":"2026-08-14T22:29:33.146Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}