Fix/adjust diffusion: round 33 P1 batch for PR #5754

Two round-33 reviewer findings: hub-floor consistency and the
multipart upload filename validator gap.

Dependencies: reverted the round-26 huggingface_hub>=1.3.0 floor
in no-torch-runtime.txt and pyproject.toml (round 33 P1 #1-#5,
4/12 vote consensus). studio.txt forces huggingface_hub==0.36.2
to match the transformers==4.57.6 pin in extras-no-deps.txt, so
the 1.3.0 floor was internally inconsistent. Reviewers
reproduced the resolver conflict on a fresh install.

Empirical justification (re-verified on the live B200 host before
the revert): huggingface_hub 0.36.2 + transformers 4.57.6 +
diffusers 0.37.1 imports Flux2KleinPipeline cleanly and runs
end-to-end image generation. transformers 4.57.6 carries its own
transformers.utils.hub.is_offline_mode and does not actually need
huggingface_hub.is_offline_mode at import time. The original bump
was guarding against the (never-realised) transformers 5.x path,
which extras-no-deps explicitly pins away.

Validation: multipart /seed/upload-unstructured-file now applies
the same _no_control_chars and _reject_embedded_hf_token checks
to file.filename that SeedInspectUploadRequest.filename already
applies in the JSON variant (round 33 P1 #7). The filename is
reflected back to the client, persisted in the per-file meta
JSON, and echoed by error responses, so the JSON-side hardening
must not be asymmetric with the multipart path.

Skipped (consistent with prior rounds):
  * Find_spec vs full import (R33 P1 #6): preserves test
    compatibility with the huggingface_hub stub fixture.
  * React hooks set-state-in-effect lint (R33 P1 #8): codebase
    has 146 pre-existing violations of the same rule;
    studio-frontend-ci does not gate on lint.
  * Direct DiffusionBackend.load_model bypass (R33 P1 #9): the
    route is the only production entry point, and the backend
    helper now publishes its own diffusion-backend pending tag
    (round 32 P1 #3). Direct-caller hardening would require
    duplicating the lease check into load_model itself, which
    is out of scope for the route-layer security boundary.
  * One-segment Hub IDs (R33 P2 #10): strict 2-segment Hub id
    check is intentional; one-segment names are not valid Hub
    ids.
  * Cwd-relative shadow of Hub IDs (R33 P2 #11): documented
    side-channel tradeoff accepted in round 31 commit msg.

97 targeted backend tests pass.
This commit is contained in:
Daniel Han-Chen 2026-05-25 16:57:28 +00:00
commit e3ce1c818e
3 changed files with 33 additions and 11 deletions

View file

@ -81,10 +81,15 @@ huggingfacenotorch = [
"datasets>=3.4.1,!=4.0.*,!=4.1.0,<4.4.0",
"accelerate>=0.34.1",
"peft>=0.18.0,!=0.11.0",
# Round 26 P1 #9: floor at 1.3.0 because the diffusion stack below
# pulls transformers 5.x which calls hub.is_offline_mode (hub 1.x).
# Keep <2.0 to avoid any future hub ABI break.
"huggingface_hub>=1.3.0,<2.0",
# Round 33 P1: reverted the round-26 hub>=1.3.0 floor. studio.txt
# forces hub==0.36.2 to match the transformers 4.57.6 pin in
# extras-no-deps.txt; the 1.3.0 floor here was internally
# inconsistent and reviewers reproduced the resolver conflict.
# Align with the colab-new extra's 0.34.0 floor (line 610). The
# transformers-5.x is_offline_mode concern that motivated the
# original bump never triggers because transformers is pinned at
# 4.57.6 on the supported install path.
"huggingface_hub>=0.34.0",
"hf_transfer",
# Studio Images page depends on Flux2KleinPipeline /
# Flux2Pipeline, both shipped in diffusers>=0.37.0. Floor was

View file

@ -43,13 +43,16 @@ safetensors>=0.4.3
datasets>=3.4.1,!=4.0.*,!=4.1.0,<4.4.0
accelerate>=0.34.1
peft>=0.18.0,!=0.11.0
# Round 26 P1 #8: floor at 1.3.0 because transformers 5.x (allowed by
# the range below) calls huggingface_hub.is_offline_mode, only present
# in hub 1.x. Under --no-deps the resolver does not enforce this
# transitively, so a pre-existing 0.36.2 used to be kept and the next
# `from transformers import AutoConfig` raised ImportError. Upper bound
# <2.0 keeps us off any future ABI break.
huggingface_hub>=1.3.0,<2.0
# Round 33 P1: reverted the round-26 hub>=1.3.0 floor. Studio's
# install_python_stack later forces hub==0.36.2 via studio.txt
# (constraint by transformers==4.57.6 pinned in extras-no-deps.txt),
# so the 1.3.0 floor was internally inconsistent with the steady
# install state. extras-no-deps holds transformers at 4.x, so the
# transformers-5.x is_offline_mode concern that motivated the
# original bump never actually triggers on the supported install
# path. Verified live on B200: hub 0.36.2 + transformers 4.57.6 +
# diffusers 0.37.1 imports Flux2KleinPipeline cleanly and runs
# end-to-end image generation.
hf_transfer
# Floor 0.37.0 introduces Flux2KleinPipeline + Flux2Pipeline which the
# Studio Images page imports for the default curated picker.

View file

@ -433,6 +433,20 @@ async def upload_unstructured_file(
tracked_ids = [fid.strip() for fid in existing_file_ids.split(",") if fid.strip()]
original_filename = file.filename or "upload"
# Round 33 P1 #7: file.filename is reflected back to the client,
# persisted in the meta JSON, and echoed by error paths. Mirror
# the SeedInspectUploadRequest.filename hardening so a multipart
# upload cannot smuggle control characters or URL-form HF tokens
# through the path the JSON variant already rejects. Import
# locally to avoid a routes -> models cycle.
from models.inference import _no_control_chars, _reject_embedded_hf_token
try:
_no_control_chars(original_filename, "filename")
_reject_embedded_hf_token(original_filename, "filename")
except ValueError as exc:
raise HTTPException(status_code = 400, detail = str(exc)) from exc
ext = Path(original_filename).suffix.lower()
if ext not in UNSTRUCTURED_ALLOWED_EXTS:
raise HTTPException(