* Fix SVG previews broken by the stored-XSS forced-download
/view and the assets download route force every SVG to
application/octet-stream + attachment. That blocks the stored XSS from
GHSA-779p-m5rp-r4h4, but it also breaks the SVG node output and Media
Assets previews, which request the file with a plain <img>.
Exempt only that case. An SVG referenced by an <img> loads in secure
static mode with scripting and external references disabled, so the
payload cannot fire. The attack needs the SVG to become a document,
which arrives with a different Sec-Fetch-Dest. Browsers set that header
themselves and page script cannot override it. A missing header, from a
non-browser client or a proxy that strips it, fails closed.
The blocklist itself is unchanged; this is a call-site gate.
* Don't let a cache replay the inline SVG into document context
The Sec-Fetch-Dest exemption makes /view and the assets content route vary
their Content-Type and Content-Disposition on a request header, but neither
response said so. FileResponse emits Last-Modified/ETag and the cache_control
middleware skips /view (the filename is in the query string, not the path), so
the inline image/svg+xml variant is heuristically cacheable. A cache keyed on
the URL alone could hand an entry primed by an <img> load to a later top-level
navigation of the same URL, turning the SVG back into a document and
re-enabling the stored XSS the forced download blocks.
Set Vary: Sec-Fetch-Dest and Cache-Control: no-store on both branches, not just
the exempt one: a cached attachment replayed to an <img> would re-break the
preview this fix exists to restore.
Also strip parameters from content_type before building the assets response.
mime_type there is uploader-supplied and unvalidated, and aiohttp rejects a
charset in the content_type argument with ValueError, so a stored
"image/svg+xml; charset=utf-8" turned a valid inline SVG into a 500.
Route-level guards now pin the headers on both branches and the parameterised
mime type; all three fail against the previous commit.
outputs_count (get_outputs_summary) counts every output item across all
nodes for a job, including non-previewable files (e.g. SaveLatent's
.latent file). The Media Assets sidebar badge reads outputs_count, but
the expanded asset view only ever renders previewable outputs (image,
video, audio, 3D, text), so the badge can show a higher number than
what a user sees when they drill in.
Add count_previewable_outputs(), reusing the existing is_previewable()
filter, and expose it as previewable_outputs_count on /api/jobs job
entries (list, detail, and queue placeholders). get_outputs_summary()
and outputs_count are left untouched so the true total stays available.
Some long running chaos testing on a 512GB RAM RTX6000 pro showed that this
is a little bit too low for common template workflows switching around. The
original number was just a guess from me, so go with the scientific result
instead.
These were alll non-dynamic (some non-ModelPatcher) code path calling
FreeMemory for management requiring up-front memory freeing. Convert it
to dynamic to avoid legacy free behaviour mixing into otherwise
dynamic workflows.
* Add native Uni3C controlnet support for Wan models
* Dispatch double_block patches in all Wan model variants
* Remove unused grid_sizes assignment in CameraWanModel, WanModel_S2V, HumoWanModel, and AnimateWanModel