Findings 1, 3, 5, 13, 23, 28, 29 and 30 (#3706): one Progress log row, one Performance row in layout-parity.md, revision-history rows.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Build wordcraft.wxs a second time as a dual-purpose package
(Scope=perUserOrMachine: ALLUSERS=2, MSIINSTALLPERUSER=1), shipped as
wordcraft-<ver>-windows-user-<arch>.msi. Registry keys move from HKLM to
HKMU so the same components land in HKLM per-machine and HKCU per-user.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Asked to confirm a non-UTF-8 Turkish dictionary still loads: before this PR
tr_TR was read with read_to_string, so a non-UTF-8 file never loaded; now it
goes through read_capped and decode, which didn't know ISO 8859-9 (Latin-5,
the encoding of older tr_TR dictionaries) and refused it as unsupported.
decode now reads `SET ISO8859-9`, and a test writes an ISO 8859-9 .aff/.dic
to disk and finds words with ğ ı ş İ ç ö ü, as stems and with suffixes.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CX1hMKX28764Lrx5moxs1o
Ultrareview finding 3: on Linux, when /proc/net/tcp(6) doesn't list the
listener on Zotero's port (WSL2 mirrored networking with Zotero on
Windows, a local proxy, a sandbox), every connection was refused, so
Zotero couldn't be used at all there. Per the owner's decision, refuse
only when both sockets are found and the listener's uid differs from
ours; otherwise log at debug and apply the plain loopback rule, as on
macOS/Windows/BSD. Test: an_unlisted_listener_falls_back_to_the_loopback_rule.
docs/zotero.md and the progress-log row say so. Non-Linux owner check
stays with #3831.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Audit finding 21 (CWE-306): run_command handed document callback authority to
whatever accepted the TCP connection. Zotero's protocol is fixed and has no
authentication, so WordCraft now establishes what it can about the peer itself:
- the address must be loopback, refused before connecting (ZoteroError::Refused);
- on Linux/Android, before the command is sent, the kernel socket table
(/proc/net/tcp, tcp6) must show the listener's end of this connection owned
by the same UID as ours; another user's listener, or one whose owner can't be
established, is refused. No unsafe, no new dependencies.
macOS, Windows and the BSDs have no such table without OS calls; there the
loopback rule is the guard. The residual risk is documented in docs/zotero.md.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- repeating_difat_sample is built only for tests: this crate's, and the
readers' through a `test-support` feature they turn on as a
dev-dependency; it is no longer in the production API.
- Tests write valid compound files with the cfb crate in Word's and Excel's
shapes (WordDocument + table stream with Data, summary and ObjectPool
streams; Workbook with summary streams), in 512- and 4096-byte sectors,
plus an 8 MB one whose FAT sectors spill into a DIFAT chain; each passes
cfb_guard::check and opens (no Word- or Excel-made files are added).
- The .doc work budget notes what it leaves out (floating objects, link
targets, alt text, Prm formatting) and logs one warning per kind once the
document is read (#3692).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CX1hMKX28764Lrx5moxs1o
Findings 49, 60, 63, 64, 68, 75: progress-log row and a note on the .doc parity row.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
# Please enter the commit message for your changes. Lines starting
# with '#' will be kept; you may remove them yourself if you want to.
# An empty message aborts the commit.
#
# interactive rebase in progress; onto d588e0b8
# Last command done (1 command done):
# pick 6a1268ea # #1845: filter-as-you-type command search in Customize Ribbon, QAT and Keyboard pickers
# No commands remaining.
# You are currently rebasing branch 'feat/1845-command-filter' on 'd588e0b8'.
#
# Changes to be committed:
# modified: crates/ui-egui/src/dialogs_keyboard.rs
# modified: crates/ui-egui/src/dialogs_ribbon.rs
# modified: docs/ui-parity.md
#
# Conflicts:
# docs/ui-parity.md
* AutoFormat As You Type: optional period with double-space, off by default (#2848)
* Test the double-space option through the AutoCorrect dialog (#2848)
* File > Options > Proofing: an AutoCorrect Options button opens the dialog (#476)
* #2848: report doubleSpacePeriod in tools.autocorrect's params doc and result
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* 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>
* Layout: a no-break space is as wide as a space, not as the font's own U+00A0 glyph (fixes#4192)
* Layout parity: a no-break space is as wide as a space (#4192)
* Lists: draw Arabic letter numbering (arabicAlpha, arabicAbjad) instead of decimal
Both orders of the 28 letters; past the last letter they double, as Latin
and Russian letters do.
* Docs: layout parity lists Arabic list labels as drawn; status lines and revision history
With *Bold* and _italic_ as real formatting on, the opening mark is not
part of the word AutoCorrect reads, so typing `*teh end* ` gives bold
`The end ` instead of `teh end `. A sentence capital is decided from the
text before the mark.
Word's Accept and Reject menus have Accept and Move to Next, Reject and
Move to Next, Accept All Changes and Stop Tracking, and Reject All
Changes and Stop Tracking. WordCraft's menus had only Accept This
Change, Accept All Changes, Reject Change and Reject All Changes.
review.accept and review.reject take "next": after the change at the
caret is resolved, the first change from the caret on is selected,
including one that starts and ends there, such as an empty paragraph's
formatting. Past the last change, the first change in the document is
selected, as Next Change does. With the caret on no change, they select
the next change as before and resolve nothing. review.acceptAll and
review.rejectAll take "stopTracking", which also turns Track Changes
off in the same undo step. The ribbon's Accept and Reject menus list
the four new items. The big Accept and Reject buttons are unchanged.
ROADMAP.md's progress log and revision history, and docs/ui-parity.md's
Reading Mode row and revision history, record the catalog rows for
Read Mode's View menu: Column Width works, Page Color and Layout are
missing (catalog 503/520). Both status lines are bumped.