Commit graph

163 commits

Author SHA1 Message Date
Horizontal42
741ea16e40 keep evaluateDocument's error boundary around tokenize/parse, not just evaluate
tokenize() and parseLine() ran outside the try/catch, and the parser
has no recursion-depth guard for nested parens. A pathologically
nested line overflowed the stack with an uncaught RangeError, killing
the whole document instead of nulling just that line — the exact
thing evaluateDocument is supposed to prevent.
2026-08-12 20:02:09 +03:00
Horizontal42
aa29c12b37 flush pending autosave before migrating the data folder
save_documents debounces 400ms; migrateDataDir used to fire without
waiting for it, so a save still in flight to the old folder could
land after migrate had already moved documents.json away, silently
recreating it in the abandoned folder and stranding the last edit.
2026-08-12 20:00:26 +03:00
Horizontal42
c3bc67bd5b gate every dir-taking IPC command against a Rust-owned trust anchor
load_documents, save_documents, run_backups, backup_deleted_sheet,
open_backups_folder and data_dir_has_documents all took a `dir` param
straight from the frontend and used it unchecked — any IPC caller
(a buggy extension, compromised webview content) could point Rust at
an arbitrary path, and migrate_data_dir's old_dir was the worst of it:
combined with strategy="move" it deletes documents.json and everything
under backups/ at whatever path it's handed.

Add DataDirGate: a path only counts as authorized if it was proven
user-chosen, either just now via the native folder picker or because
it's the data-dir.txt this file itself wrote after a previous
successful commit. save_file/load_file refuse to touch that filename
so the frontend can't forge its own authorization. docs_dir() now
returns Result and every command above goes through it.

migrate_data_dir authorizes the target before copying but only writes
data-dir.txt once every file has actually landed, so a migration that
dies partway leaves the app still pointing at a folder that works.
2026-08-12 20:00:00 +03:00
Horizontal42
3bc946bd44 consistent size cap for OS-opened sheet files
read_text_file (drag&drop) capped sheets at 1MB with an extension
whitelist; get_launch_file and the single-instance file-open handler
only checked the extension. Route both through read_sheet_file so a
file association or second launch gets the same cap.
2026-08-12 19:59:12 +03:00
Horizontal42
dea7314842 move cache file I/O off the async runtime thread
rates.json, market.json and rates-<date>.json reads/writes ran
straight on the tokio worker calling the Tauri command, blocking the
shared async runtime for the duration. Wrap them in
tauri::async_runtime::spawn_blocking via read_file_async/write_atomic_async.
2026-08-12 19:57:55 +03:00
Horizontal42
2d682448c6 dedupe historical-rate map parsing
fetch_historical_rates and fetch_historical_rates_batch each built the
same USD-anchored, uppercased rate map inline. Extract parse_rate_map
and cover it with tests.
2026-08-12 19:56:11 +03:00
Horizontal42
a8121dbc90 share atomic-write bytes helper between write_atomic and image export
write_image_file hand-rolled the same temp+rename dance write_atomic
already did for text, just for bytes. Split write_atomic into a
write_atomic_bytes core and have both callers use it.
2026-08-12 19:54:37 +03:00
Horizontal42
d7b88cc9c9 atomic write for deleted-sheet backups
fs::write left the one safety-net copy of a deleted sheet exposed to
mid-write corruption; use the existing temp+rename helper like every
other user-data write.
2026-08-12 19:54:06 +03:00
Horizontal42
b399b95263 sync Cargo.lock with 1.2.4 2026-08-09 16:33:24 +03:00
Horizontal42
7dee94caa1 sync package-lock.json with 1.2.4 2026-08-09 16:33:24 +03:00
Horizontal42
6ab5b9e5d9 update tauri.conf version to 1.2.4 2026-08-09 16:31:24 +03:00
Horizontal42
78538511b8 bump cargo version to 1.2.4 2026-08-09 16:31:04 +03:00
Horizontal42
330d49cfe0 bump version to 1.2.4 2026-08-09 16:30:53 +03:00
Horizontal42
dad3de70a5
bound migrate_data_dir cleanup to known files, add dialog-verified new_dir 2026-08-09 16:27:08 +03:00
Horizontal42
354705cf15
scope read_text_file to files from real drop events 2026-08-09 16:23:33 +03:00
Horizontal42
135ef290df
fix stale drag rects on scroll, drop unused jsdom deps 2026-08-09 16:21:04 +03:00
Horizontal42
d08d807961 fix flaky debounce test: poll with real timers instead of guessing tick count 2026-08-09 16:19:45 +03:00
Horizontal42
59df3a7264
flatten parser into a Pratt parser 2026-08-09 16:00:19 +03:00
Horizontal42
d3731be6ef
add missing evaluation error tests 2026-08-09 15:59:56 +03:00
Horizontal42
55d8401a44
batch historical rates IPC calls with a pooled http client 2026-08-09 15:59:44 +03:00
Horizontal42
bba294c6d5
extract renderDocList helpers 2026-08-09 15:59:19 +03:00
Horizontal42
423d22d462
add evaluator quantity conversion tests 2026-08-09 15:59:13 +03:00
Horizontal42
bcb38c9c1c
split evaluate switch into per-kind helpers 2026-08-09 15:58:53 +03:00
Horizontal42
54c9cc63b0
surface non-EvalError exceptions in evaluation engine 2026-08-09 15:57:35 +03:00
Horizontal42
62ef8cc8cd
assert console availability directly instead of matching an error message 2026-08-09 15:57:33 +03:00
Horizontal42
5554205193
document PctOp usage 2026-08-09 15:57:30 +03:00
Horizontal42
2762e4461c
split extensions load into isolated helpers 2026-08-09 15:57:28 +03:00
Horizontal42
3a657a2d5d
dedupe evaluation logic in Workspace 2026-08-09 15:57:25 +03:00
Horizontal42
edfa55e4dc
extract sparkline SVG rendering into its own module 2026-08-09 15:57:22 +03:00
Horizontal42
a384b98dcb
add isCalendarUnit edge case tests 2026-08-09 15:57:20 +03:00
Horizontal42
8f200bcd61
add engine vocab module tests 2026-08-09 15:57:17 +03:00
Horizontal42
460a12e695
improve date order detection tests with real Intl calls 2026-08-09 15:57:15 +03:00
Horizontal42
dcac3ae425
add registry tests 2026-08-09 15:57:13 +03:00
Horizontal42
6716f1b6da
add coverage for storage utility functions 2026-08-09 15:57:10 +03:00
Horizontal42
c958f30662 Revert "rotate updater signing pubkey"
This reverts commit c0bea836bc.
2026-07-29 15:54:41 +03:00
Horizontal42
c0bea836bc rotate updater signing pubkey 2026-07-29 15:46:13 +03:00
Horizontal42
40cdf22461 sync Cargo.lock with 1.2.3 2026-07-29 15:35:03 +03:00
Horizontal42
8bfe65a1c4 update tauri.conf version to 1.2.3 2026-07-29 15:35:03 +03:00
Horizontal42
2798bfcafa bump cargo version to 1.2.3 2026-07-29 15:35:03 +03:00
Horizontal42
c63ec63e2f bump version to 1.2.3 2026-07-29 15:35:03 +03:00
Horizontal42
08876adae8 bump postcss to patch path-traversal advisory (GHSA-r28c-9q8g-f849) 2026-07-29 15:34:54 +03:00
Horizontal42
b0f6e9e89b run extensions in a quickjs wasm sandbox
replaces new Function() in the main window; per-script and per-call
interrupt deadlines, memory and stack limits, graceful skip if the
wasm module fails to load. csp script-src drops 'unsafe-eval' for
'wasm-unsafe-eval'.
2026-07-29 14:38:28 +03:00
Horizontal42
5c4f2db2d2 fix clippy collapsible_match warning in safe_name 2026-07-29 14:14:49 +03:00
Horizontal42
a6fc5b90f3 harden safe_name path validation 2026-07-29 14:14:49 +03:00
Horizontal42
1a12d75ec6 add regression test for sequence error recovery 2026-07-29 14:14:49 +03:00
Horizontal42
ca6fa6d381 cache findSheetByTitle lookups 2026-07-29 14:14:49 +03:00
Horizontal42
c89242b626 debounce variable highlight scanning in editor 2026-07-29 14:14:49 +03:00
Horizontal42
5ccb46b01c cache sheet results for numeric search 2026-07-29 14:14:49 +03:00
Horizontal42
fd93b00bf5 extract drag-and-drop logic from renderDocList 2026-07-29 14:14:49 +03:00
Horizontal42
8ef2f8b445 extract UI bindings out of initUI 2026-07-29 14:14:49 +03:00