chore: sync upstream (507 Commits) #10
No reviewers
Labels
No labels
herkunft/alpha-feedback
status
blockiert
status
zu-testen
typ
bug
typ
docs
typ
enhancement
typ
feature
typ
idea
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
iris/wordcraft!10
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "chore/sync-upstream-20261026"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Upstream-Sync von
upstream/main(507 Commits). Fast-Forward.2c99a427Merge pull request #4392 from benandez/fix/3866-followupab0eccd2Merge pull request #4377 from storytold/sonar/newcode-s3776-a0377edabMerge pull request #4376 from storytold/sonar/newcode-lints-1438775ceMerge pull request #4391 from aiongg/w6b94821ea#3866: review — count a step per page walked in the first-page index, so the hinted-page test sees an eager builde71c9ce3#3866: review — the first-page index is built only when the hinted page doesn't show the paragraphbbf07875Merge branch 'w3' into w69752ca58Merge branch 'w2' into w3e8282d95Merge branch 'w1' into w2f93c0cbeW1: the merge-records test expects the result beside the unsaved source, with no save prompt73af86b1Merge pull request #4355 from storytold/codex/egui-037-word-followup-20261025503a533eMerge branch 'w3' into w627068500Merge branch 'w2' into w316f6145cMerge branch 'w1' into w27d512a69Merge remote-tracking branch 'upstream/main' into w1craft-ui's pane host names each title bar after its pane, so the accessible name is "Move Pane: {title}" ("Move Pane: Styles") in all 22 catalogs. The pane tests find the title bars by that name.Spanish text was never checked: ProofLang had no Spanish variant, so every es-* run fell through to Other (no marks). And the RLA-ES dictionaries LibreOffice ships were refused by the affix engine for their `☎️` flag (☎ + variation selector U+FE0F), which Hunspell reads as ☎. - ProofLang::Es (Spain, plain es, spa), EsMx (es-MX), Es419 (es-419 and the other countries of the Americas) and EsUy (es-UY), chosen by region like the English dialects - each variety reads its own installed Hunspell dictionary with fallbacks (es_ES; es_MX; es_419/es_US/es_MX; es_UY/es_AR); nothing bundled - variation selectors in affix flag fields belong to the flag before them - Uruguayan vos forms accepted when the dictionary has the infinitive: imperatives (vení, andá), with pronouns (decime, decímelo), present (tenés); a vos form typed without its accent gets it back first - suggestions use the dictionary-driven Czech ranking (prueva → prueba, corector → corrector, tambien → también) - grammar: repeated word, spacing, missing opening ¿/¡, space after an opening mark, with Spanish messages - Review › Language, status bar, Language dialog and File › Options › Proofing list the four varieties; the two new names translated in every catalog; a Spanish interface writes new documents in the region's Spanish - the dictionaries-folder engine test holds the Italian and Spanish fixtures, so parallel proofing tests no longer lose their dictionaries - tests use hand-written synthetic dictionaries; engine end-to-end testsOne session holds several open documents. The active document stays in the Session's own fields, so commands and the UI keep working on it; the others are parked as DocState values and swapped in field by field (std::mem::swap, no clones or relayout). Session and DocState are destructured exhaustively, so a new field must be classified as per document or shared before it builds. - Session::documents, activate, add_document, close_document, is_untouched_blank, with_document, find_open, is_open; DocInfo. - Document ids come from a process-wide counter. - file.new opens beside the open documents; file.open replaces an untouched blank document, opens beside the others otherwise, and activates a file that is already open ("alreadyOpen": true). - file.closeDocument {id?, force?} closes a document without a window (refuses unsaved changes unless forced); file.close is unchanged. - view.switchWindows {id?} lists the open documents or activates one. - Envelopes, Labels, Finish & Merge and New from Template open their result as a new document; the main document stays open, with no undo step for the command. - Each document keeps its own recovery worker and copy; Read Aloud readings name their document; with_document tags UI requests with the document they came from.A same-origin page that frames wordcraft-web (a Nextcloud app, a personal file server) can now hand it a document and store what it saves, with the same postMessage protocol as GridCraft's and PdfCraft's bridges: wordcraft:ready / open / save {name, saveAs, bytes} / dirty / failed. In host mode Save, Save As and Export go to the parent instead of the save picker or a download (Services::host_save, with whether it was Save As). Save writes the opened file under its own name and format, as the desktop app does (an import-only .doc still becomes a .docx), and a Save or Save As that keeps everything makes that name the document's file, so the next Save goes to it. The parent guards leaving the page; ?author= names the user for comments and tracked changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>adjust_media capped only the decoded input. The frame, shadow and default styles then sized their bitmaps from it with unchecked u32 sums. A thin 1 x 2,000,000 PNG of a few KB and Thick Frame asked for about 1.8 TB. The failed allocation aborted the app outside Session::run's panic guard, so every window's unsaved work was lost. picture.border {"width":200} on it asked for 3.2 GB. Picture operations are now fallible. Every bitmap a style or border draws on comes from canvas(), which refuses a size the renderer couldn't draw either (two RGBA buffers within the 512 MB decode budget) before allocating, and the margins are added with checked arithmetic. The edit then fails with "picture is too large to edit" and the picture stays as it was.- Format Shape is a task pane with the others: its title bar comes from craft_ui::panes and its drag undo mark is forgotten while it is closed. - The in-repo catalogs are gone upstream; the pane strings this branch added to them (Styles Pane Position, Dock Left, Dock Right, Float, Pane Options, Move Pane: {title}, Resize Pane) go to craft-i18n. - Every craft-libs crate (craft-ui, craft-i18n, craft-print, craft-pdf, krilla) is pinned at storytold/craft-libs 16fb3d4. craft_ui's Printer has a label: the spooler's description of the printer.Update Field and the page-number fields ignored the capitalization switches, so TITLE \* Upper or FILENAME \* Lower showed the text as stored. A \* CardText or \* OrdText result started with a capital ("Twelve"), where Word shows it in lowercase unless a capitalization switch follows. A table formula with a \* switch, such as =SUM(A1:B2) \* CardText or =SUM(ABOVE) \* MERGEFORMAT, was a syntax error. The results of the document information fields, DOCPROPERTY, FILENAME, the dates, REF, PAGEREF, SEQ, STYLEREF and table formulas now take the field's \* Upper, \* Lower, \* Caps or \* FirstCap switch when Update Field computes them. PAGE, NUMPAGES, SECTION, SECTIONPAGES, PAGEREF and STYLEREF take it when they are laid out. Cardinal and ordinal text is lowercase ("twelve", "seventh") unless one of the switches follows. WordCraft now reads a table formula's \* switches separately from the formula. A whole-number result that a \* number format such as CardText or roman covers is written in that format; any other result, and any other \* switch, leaves the digits. Table Layout › Data › Formula keeps the \* switches as typed.A field or table formula with \* DollarText or \* Hex showed its digits, and PAGE \* ArabicDash showed the plain page number. \* DollarText now writes the result in lowercase cardinal text with "and" and the first two decimals (rounded) over 100, so { = 9.20 + 5.35 \* DollarText \* Upper } shows FOURTEEN AND 55/100. \* Hex writes uppercase hexadecimal digits (458 shows 1CA). PAGE \* ArabicDash shows the page number between hyphens ("- 31 -"); other fields, PAGEREF included, skip it. The page-number, SEQ, PAGEREF and count fields and table formulas read both switches. Cardinal, ordinal and dollar text keep the digits of a number past 999,999. Before, \* CardText showed such a number as "nine hundred ninety-nine thousand nine hundred ninety-nine" and \* OrdText as "nine hundred ninety-nine thousand nine hundred ninety-ninth".`mergefield_name` matched with `strip_prefix("MERGEFIELD")`. A field typed as `mergefield City` was therefore no merge field at all: Check for Errors skipped it, and Preview Results and Finish & Merge left it alone. A code such as `MERGEFIELDX a` went the other way and was read as a merge field named `X`. Field-type names ignore case (ECMA-376 Part 1, 17.16.1: "The field-type names DATE, Date, dAtE, and date are equivalent"). The other keywords in this file already go through the upper-cased `keyword()`. Now the type ends at the first space or quote and is compared ignoring case, which is the rule the shared HYPERLINK parser in #4222 follows. The two IF checks for a nested MERGEFIELD ignore case as well, so `IF { mergefield X } = ...` merges like its upper-case form. Old and new compared on 5,940 generated codes: 2,760 give the same name, 960 are case variants that are now found, and 2,220 start with a longer word such as `MERGEFIELDX` that no longer counts as MERGEFIELD. Test: merge_field_types_ignore_case.Preview Results and Finish & Merge took any IF whose code held the word MERGEFIELD anywhere, and with the type now matched in any case, a quoted value counted too: IF { PAGE } = "mergefield" "yes" "no" was evaluated as a rule on an empty field and showed "no". Both guards now ask what condition() already reads: the first nested field, through mergefield_name. An IF on other fields keeps its result.* With Regular expressions on, Replace with reads $1…$n, ${n}, ${name}, $name, $0/${0}, $$, \1…\9, \n (paragraph mark, splits the paragraph through the ^p path), \t and \\, alongside the ^ codes. Named groups resolve through meta::Regex::group_info(); missing, unknown and out-of-range groups expand to nothing. Plain and wildcard Replace are unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * #4177: review — special:false keeps regex group references Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * #4177: review — \$ and \^ in regex Replace keep the character as typed Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>Audit finding 79 (CWE-117): the CLI printed Zotero's alert text (and, with --trace, the method name and call/reply JSON) to stderr as received, so a peer on Zotero's port could end the "Zotero:" line, forge following output or send terminal escape sequences. escape_peer shows backslashes, control characters (C0, DEL, C1), line separators and bidi overrides as visible escapes (\\, \n, \u{1b}), keeping each record on its own attributable line. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>Finding 57: Writer::code replaced `\end{verbatim}` in a code line and then removed control characters, so `\end{verb<U+000E>atim}` became a real closing delimiter and the rest of the line was compiled as TeX. Control characters are now removed first and the replacement runs on the final text. Finding 52: the table reader unwrapped every nested \multicolumn / \multirow in a cell, rescanning the remaining braced content each time (quadratic; the nesting limit didn't apply). At most MAX_NEST wrappers are unwrapped now; real tables use one or two, which read as before. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>Finding 46: install_font logged the caller-supplied file name raw when the font couldn't be stored, and the desktop log writes line breaks as they come, so a name could forge extra log records. The name is now logged with {:?} (escaped and quoted), and so are the font-derived family names in the two glyph-outline warnings, which come from a document's own fonts. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>Finding 45 (CWE-407): Document::add_media compared each new image with every stored one, so an import with many distinct small images did quadratic work (40k images: 213 s before, 0.26 s after). A MediaIndex cache (not saved, ignored by ==) maps bytes to their first key, is rebuilt when media changed size behind its back, and every hit is checked against media. Generated image{n} names also skip taken names once instead of on every add. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>The Linux same-user check read /proc/net/tcp{,6} through a 64 MiB take(). Hitting the cap was silent, so a local user binding ~450k loopback listeners pushed the connection rows past it; both uids came back unknown and the "trust loopback" arm let their fake Zotero listener on 23116 through. A truncated last line could also glue to the next header. Now each table is streamed line by line (BufRead, nothing kept, no total cap, lines capped at 4 KiB) and stops once both rows are found. Any read error refuses. "Unknown, trust loopback" remains only for a listener absent from a table read in full (WSL2, proxies). Tests: rows after 70 MiB of filler, and a read error mid-table. rich.rs: document that the MAX_RUNS cap still allows one first run per paragraph (bounded by MAX_PARAS). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>