chore: sync upstream (57 Commits) #17

Merged
alf merged 57 commits from chore/sync-upstream-20261102 into main 2026-11-02 16:20:26 +00:00
Owner

Upstream-Sync von upstream/main (57 Commits). Fast-Forward.

Upstream-Sync von `upstream/main` (57 Commits). Fast-Forward. - 9d7baea5 Fix #2823: Propagate boxes SAM 2 around the matte shown on the stroked frame (#2826) - ad7abfa5 Merge PR #2792 (author's repin, same as main) - f6b09d78 test(ui): the fake sound card waits to pull until the starting frame is checked - 35ce2186 Follow-up to #2804: ProRes frame headers carry the colr atom's colour codes - 7441ccf1 Follow-up to #2781: Swedish Keys, File, Top and Bottom read as they're used - d2fa9c19 Follow-up to #2792: pin craft-ecproj-format to craft-libs main (ca1b5e2e, #409) - f3cedac8 Merge PR #2792 - 1467d949 Merge PR #2804 - 4375b689 Merge PR #2798 - 6f896170 Merge PR #2790 - a658ec73 Merge PR #1266 - 4515418f Merge PR #2742 - 546da0a1 Merge PR #2679 - 5068f426 Merge PR #2781 - e0cd2914 Merge PR #2783
alf added 57 commits 2026-11-02 16:20:25 +00:00
The pre-scan lexed one object after every `trailer` marker over the rest of
the file, so an unterminated string or dictionary after each of many markers
made opening a crafted PDF quadratic. Each lex now gets a 4 KiB window; when
it runs out, the file is refused if `/Encrypt` appears past the window (one
search per file), so long trailers can't hide the key.
A shortcut belongs to the application, a panel or a context (editing text, a paint or
camera tool active, a mask selected). The narrowest active scope runs a chord: an active
context, the focused panel, the panel sharing its shortcuts (Timeline and Composition),
the application. A context's shortcuts never run outside it.

- shortcuts.rs: scope table for engine commands and menu entries, scope_rank,
  scope_label; UiCommand can state its scope.
- Conflicts: the same chord in two scopes is an override (both keep working), reported
  with overrides: true; shortcuts.conflicts lists same-scope pairs only.
- Scoped now, keys unchanged: Remember / Apply Interpretation and Delete Without
  Confirmation (Project), Duplicate Render Item (Render Queue).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: DeepSeek V4.1 Flash <noreply@deepseek.com>
Co-Authored-By: DeepSeek V4.1 Flash <noreply@deepseek.com>
Co-Authored-By: DeepSeek V4.1 Flash <noreply@deepseek.com>
Co-Authored-By: DeepSeek V4.1 Flash <noreply@deepseek.com>
The fallback searched for the literal bytes `/Encrypt`, so a long trailer
with the key written as `/Encr#79pt` (or any other #-escaped spelling) got
past it. It now finds the last name token that decodes to `Encrypt`, with
the lexer's own name decoding, and checks whether that token ends past the
window. It is still one linear pass per file. Longer names that only start
with `Encrypt` (`/Encrypted`) no longer count.
Co-Authored-By: DeepSeek V4.1 Flash <noreply@deepseek.com>
Co-Authored-By: DeepSeek V4.1 Flash <noreply@deepseek.com>
Co-Authored-By: DeepSeek V4.1 Flash <noreply@deepseek.com>
- shortcuts::pick chooses the binding for a key press: narrowest scope, then a
  physical-key binding, then the first. When two other panels (or two active
  contexts) claim the chord at the same rank, neither runs and the status bar
  says which panels own it.
- Physical and logical bindings compete by scope rank in one pass, so a
  narrower logical binding beats a physical one of an unrelated panel.
- An additional viewer (PanelKind::Viewer) ranks as the Composition panel.
- Two contexts on the same keys are reported as a conflict.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: DeepSeek V4.1 Flash <noreply@deepseek.com>
The pre-scan window could end inside a trailer key, so a decoy like
`/Encrypted` cut right after `/Encrypt` was taken for the Encrypt key
and an unencrypted file was refused. A window that ends mid-token now
ends before that token instead, and the past-the-window fallback reads
the name whole (a real `/Encrypt` cut as `/Encryp|t` is still refused).

Tests for that boundary, for a trailer with a long /ID, and for `#`
without two hex digits staying as written in a name.
A `trailer` marker inside an unreferenced stream followed by `(` and more
than 4 KiB of text made the lexer stop at the window's end, so a later
`/Encrypt` name anywhere in the file refused a plain file. The unbounded
scan read a string there and opened it. The past-the-window fallback now
applies only when no object starts in the window or the first one opens
a dictionary (`<<`, including one split by the window's end).

Regression test with `trailer(` and `trailer[` in a stream and a later
Encrypt name.
Brings the Swedish catalog up to date with upstream main (e71dd629).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Chewybone-sudo <347238078+Chewybone-sudo@users.noreply.github.com>
Co-authored-by: Chewybone-sudo <347238078+Chewybone-sudo@users.noreply.github.com>
effectcraft-project writes and checks the envelope of .ecproj files with
craft-ecproj-format from craft-libs: File (savedBy, then the saved view
and the project) with to_json and to_json_compact for Save Compact
Project Files, check_schema and its message, SCHEMA_VERSION and
saved_by, which stay re-exported under their names. Project, SavedView
and the schema 1 conversion stay here.

Saved files are byte-identical. saved_by now reads only a JSON object,
so a project written as a JSON array no longer reports a savedBy.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The craft-ecproj-format pin moves to storytold/craft-libs#409's new
head, where Head::read is the one reader and saved_by() is removed.
effectcraft-project's saved_by reads savedBy with Head::read, and from
ReadError::TooNew for a project with a newer schema.

saved_by now returns None for text that is not a JSON object with a u32
schema. EffectCraft calls it only on files Project::from_json opened,
so opening and importing projects are unchanged.
ProRes renders had no colr atom, so the stream reported no primaries,
transfer or matrix. Write an nclc atom, as FilmCraft does for MOV, with
the codes of what the render path makes: the project's output space when
it has a working space, BT.709 otherwise.

sRGB output stays at transfer 1, which is still open on #340 and #464.
The frames don't change, so the pinned ProRes bytes move by exactly the
atom's 18 bytes.
craft-libs #409 merged as ca1b5e2. The crate's source is the same as
at the earlier pin d74959f.
The PR pinned the head of a fork branch, not in craft-libs history; the crate
source is byte-identical at both revs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keyframes column, a file field, crop/alignment edges.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
They said BT.709 for every output, so a non-709 render disagreed with its atom.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Under load its thread pulled samples before the test read the clock, so
'from the first frame' saw frame 1 and a_started_preview_follows_its_sound flaked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fix #2823: Propagate boxes SAM 2 around the matte shown on the stroked frame (#2826)
Some checks failed
ci.yml / Fix #2823: Propagate boxes SAM 2 around the matte shown on the stroked frame (#2826) (pull_request) Failing after 0s
nix.yml / Fix #2823: Propagate boxes SAM 2 around the matte shown on the stroked frame (#2826) (pull_request) Failing after 0s
sonarcloud.yml / Fix #2823: Propagate boxes SAM 2 around the matte shown on the stroked frame (#2826) (pull_request) Failing after 0s
ci.yml / Fix #2823: Propagate boxes SAM 2 around the matte shown on the stroked frame (#2826) (push) Failing after 0s
nix.yml / Fix #2823: Propagate boxes SAM 2 around the matte shown on the stroked frame (#2826) (push) Failing after 0s
sonarcloud.yml / Fix #2823: Propagate boxes SAM 2 around the matte shown on the stroked frame (#2826) (push) Failing after 0s
9d7baea5cc
* Fix #2823: Propagate boxes SAM 2 around the matte shown on the stroked frame

The tracker's box prompt came from the classic graph cut of the strokes,
which can leak into the background; SAM 2 then filled the whole box.
Build the box from the model's own matte (segment_with), the one shown
before Propagate. segment_with falls back to the classic cut when the
model can't segment, so non-model paths are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Fix #2823: box a lone object around the matte shown on correction frames too

A correction frame shows a matte propagated from the frame before, not a
fresh model cut, so the tracker's box came from a different matte than
the one on screen. With one object the box now comes from Chain::ensure,
the matte shown on that frame. Several objects share one shown matte, so
each keeps the model's cut of its own strokes. Cancelling while the shown
matte is computed stops instead of falling back, and the prompt frame is
read only when needed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
alf merged commit 9d7baea5cc into main 2026-11-02 16:20:26 +00:00
alf deleted branch chore/sync-upstream-20261102 2026-11-02 16:20:26 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
iris/effectcraft!17
No description provided.