forked from 1b-agent/opencadstudio-upstream
A second adversarial round (with empirical reproduction against the vendored image 0.25) found the budget contract still had holes: - The probe billed 4 bytes/px, but 16-bit formats allocate their native layout during decode (8/px for RGBA16 PNG; TIFF stacks ~3x codec scratch on top). In-budget 16-bit images were falsely refused with self-contradictory notes, and the decode transient could exceed the budget the tiers claimed to enforce. The probe now reads the color type alongside the dimensions and bills the real peak (native layout + RGBA where they coexist, plus the TIFF codec factor), so refusals are honest and per-platform-correct, and the TIFF allowance follows the same accounting. - GIF: the probe reads the LOGICAL SCREEN, but a crafted frame may declare itself arbitrarily larger (empirically: a 10x10 probed screen with an 8192x8192 frame — 320 MB and 29 s from a probe-claimed-400-byte image). The GIF frame buffer is now capped to the probed size plus slack; frame bombs refuse like any other oversize. - Remote bodies on web streamed incrementally with the 64 MB cap enforced DURING the read (array_buffer() materialized a hostile chunked reply in full before any check could fire), aborting and cancelling the reader the moment the cap is crossed. - Degenerate raster entities (zero/non-finite size or vectors) no longer produce NaN placement math that aborted whole PDF exports — they resolve to the broken-reference placeholder. - Same-name resolution now has a deterministic winner (newest registration, via insertion order) instead of HashMap iteration order; URL query strings no longer break by-name matching; the image pick matches its refusal note by the quoted file name (substring collisions like a.tif/2011.tif attributed errors to the wrong file); a dropped remote outcome at the queue cap triggers one unconditional catch-up re-resolution instead of waiting for another event; the unknown-size refusal says so instead of printing 0x0; and the build script fails cleanly when there are no fonts to verify.
173 lines
6.6 KiB
TOML
173 lines
6.6 KiB
TOML
[package]
|
|
name = "OpenCADStudio"
|
|
version = "2026.37.0"
|
|
edition = "2021"
|
|
build = "build.rs"
|
|
default-run = "OpenCADStudio"
|
|
|
|
[workspace]
|
|
members = [
|
|
"crates/ocs_plugin_api",
|
|
"crates/ocs_save",
|
|
"crates/ocs_web_worker",
|
|
"crates/dwg-thumbnailer",
|
|
"crates/dwg-thumbnailer-win",
|
|
]
|
|
|
|
[target.'cfg(windows)'.build-dependencies]
|
|
winresource = "0.1"
|
|
|
|
[dependencies]
|
|
serde_json = "1"
|
|
serde = { version = "1", features = ["derive"] }
|
|
calamine = "0.36.1"
|
|
base64 = "0.22"
|
|
semver = "1"
|
|
url = "2"
|
|
iced = { git = "https://github.com/iced-rs/iced.git", rev = "23604ff22ab0aad9e00b9327cb7b8546ed84db39", features = ["image", "svg", "advanced", "canvas", "smol", "markdown"] }
|
|
iced_runtime = { git = "https://github.com/iced-rs/iced.git", rev = "23604ff22ab0aad9e00b9327cb7b8546ed84db39" }
|
|
iced_core = { git = "https://github.com/iced-rs/iced.git", rev = "23604ff22ab0aad9e00b9327cb7b8546ed84db39" }
|
|
iced_aw = { git = "https://github.com/HakanSeven12/iced_aw.git", branch = "agent/fix-iced-fonts", features = ["menu", "context_menu", "color_picker", "drop_down"] }
|
|
bytemuck = { version = "1.25", features = ["derive"] }
|
|
glam = { version = "0.33", features = ["bytemuck"] }
|
|
rfd = "0.17"
|
|
clap = { version = "4", features = ["derive", "string"] }
|
|
env_logger = "0.11"
|
|
acadrust = { git = "https://github.com/HakanSeven12/cadcodec.git", rev = "568a12c", features = ["serde"] }
|
|
cadkernel = { git = "https://github.com/HakanSeven12/cadkernel.git", rev = "dcf0840", features = ["acis", "offset"] }
|
|
cadkernel-constraints = { git = "https://github.com/HakanSeven12/cadkernel.git", rev = "dcf0840" }
|
|
dwg-thumbnailer = { path = "crates/dwg-thumbnailer" }
|
|
# Shared SAVE serialization dispatch + web-worker wire format: one
|
|
# implementation for the inline (fallback/native) path and the worker path.
|
|
ocs_save = { path = "crates/ocs_save" }
|
|
flate2 = "1"
|
|
# Raster decode set: png/jpeg/bmp/tiff plus webp/gif (both pure-Rust in
|
|
# image 0.25, so the wasm target stays C-free). Every format named here must
|
|
# also appear in the IMAGE picker filter (io::pick_image_file) and the web
|
|
# drop filter (io::web_drop::is_image_name).
|
|
image = { version = "0.25", default-features = false, features = ["png", "jpeg", "bmp", "tiff", "webp", "gif"] }
|
|
hayro = "0.7.1"
|
|
# PDF writer shared by desktop export and the web export/preview/print path.
|
|
printpdf = { version = "0.9.1", default-features = false, features = ["images"] }
|
|
# Rasterises assets/logo.svg into the window icon at startup, so the taskbar
|
|
# icon comes from the same file every other build target does. Already in the
|
|
# tree behind iced's svg feature; named here only to use it directly.
|
|
resvg = { version = "0.45", default-features = false }
|
|
i18n-embed = { version = "0.16", features = ["fluent-system"] }
|
|
i18n-embed-fl = "0.10"
|
|
rust-embed = "8"
|
|
inventory = "0.3"
|
|
rustc-hash = "2"
|
|
sha2 = "0.10"
|
|
fontdb = "0.23"
|
|
ttf-parser = "0.25"
|
|
cosmic-text = "0.15"
|
|
unicode-bidi = "0.3"
|
|
lyon_tessellation = "1.0.20"
|
|
|
|
[dev-dependencies]
|
|
fluent-syntax = "0.12"
|
|
naga = { version = "27", features = ["wgsl-in"] }
|
|
|
|
[target.'cfg(target_os = "windows")'.dependencies]
|
|
# Win32_Graphics_Gdi + Win32_Security are required for PRINTER_INFO_2W (the
|
|
# level-2 printer enumeration fallback in src/io/print_to_printer.rs).
|
|
windows-sys = { version = "0.61", features = ["Win32_UI_Shell", "Win32_UI_WindowsAndMessaging", "Win32_System_Com", "Win32_System_Registry", "Win32_Storage_FileSystem", "Win32_Foundation", "Win32_Graphics_Printing", "Win32_Graphics_Gdi", "Win32_Security"] }
|
|
|
|
[target.'cfg(target_os = "linux")'.dependencies]
|
|
ashpd = { version = "0.13.13", default-features = false, features = ["async-io", "wayland"] }
|
|
|
|
# For `src/bin/ocs_launcher.rs` only (the .app's real CFBundleExecutable,
|
|
# see that file for why) — already in the tree transitively via winit, pinned
|
|
# here to the same versions Cargo already resolves for it.
|
|
[target.'cfg(target_os = "macos")'.dependencies]
|
|
objc2 = "0.5"
|
|
objc2-app-kit = { version = "0.2", features = ["NSApplication", "NSResponder", "NSRunningApplication"] }
|
|
objc2-foundation = { version = "0.2", features = ["NSArray", "NSURL", "NSString", "NSObject", "NSNotification", "NSThread", "NSEnumerator"] }
|
|
|
|
[patch.crates-io]
|
|
iced_core = { git = "https://github.com/iced-rs/iced.git", rev = "23604ff22ab0aad9e00b9327cb7b8546ed84db39" }
|
|
iced_widget = { git = "https://github.com/iced-rs/iced.git", rev = "23604ff22ab0aad9e00b9327cb7b8546ed84db39" }
|
|
|
|
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
|
getrandom = "0.3"
|
|
ocs_plugin_api = { path = "crates/ocs_plugin_api", features = ["host"] }
|
|
bincode = "1.3"
|
|
meshopt = "0.6.2"
|
|
i18n-embed = { version = "0.16", features = ["desktop-requester"] }
|
|
rayon = "1"
|
|
open = "5"
|
|
ureq = { version = "3", default-features = false, features = ["rustls", "platform-verifier", "win-system-proxy"] }
|
|
|
|
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
|
ocs_plugin_api = { path = "crates/ocs_plugin_api" }
|
|
i18n-embed = { version = "0.16", features = ["web-sys-requester"] }
|
|
rust-embed = { version = "8", features = ["debug-embed"] }
|
|
console_error_panic_hook = "0.1"
|
|
log = "0.4"
|
|
getrandom = { version = "0.3", features = ["wasm_js"] }
|
|
wasm-bindgen = "0.2"
|
|
wasm-bindgen-futures = "0.4"
|
|
js-sys = "0.3"
|
|
bincode = "1.3"
|
|
web-sys = { version = "=0.3.85", features = [
|
|
"Window",
|
|
"Storage",
|
|
"StorageManager",
|
|
"Navigator",
|
|
"Document",
|
|
"Element",
|
|
"HtmlAnchorElement",
|
|
"Blob",
|
|
"File",
|
|
"FileSystemDirectoryHandle",
|
|
"FileSystemFileHandle",
|
|
"FileSystemGetDirectoryOptions",
|
|
"FileSystemGetFileOptions",
|
|
"FileSystemWritableFileStream",
|
|
"WritableStream",
|
|
"Url",
|
|
"Response",
|
|
# The wasm remote-raster fetch (image_model::fetch_remote_web) builds a
|
|
# `Request` with an `AbortController` signal for its deadline; the fetch
|
|
# rejection is classified via `DomException` (AbortError = timeout) and
|
|
# the body size is pre-checked against the Content-Length `Headers`.
|
|
"Request",
|
|
"RequestInit",
|
|
"AbortController",
|
|
"AbortSignal",
|
|
"DomException",
|
|
"Headers",
|
|
"Worker",
|
|
"WorkerOptions",
|
|
"WorkerType",
|
|
"MessageEvent",
|
|
"ErrorEvent",
|
|
"Clipboard",
|
|
"KeyboardEvent",
|
|
"KeyboardEventInit",
|
|
"EventInit",
|
|
"EventTarget",
|
|
"BeforeUnloadEvent",
|
|
"console",
|
|
"Node",
|
|
"HtmlElement",
|
|
"HtmlCanvasElement",
|
|
"CanvasRenderingContext2d",
|
|
"ImageData",
|
|
"DragEvent",
|
|
"DataTransfer",
|
|
"FileList",
|
|
"Event",
|
|
"ReadableStreamDefaultReader",
|
|
"ReadableStream",
|
|
] }
|
|
iced = { git = "https://github.com/iced-rs/iced.git", rev = "23604ff22ab0aad9e00b9327cb7b8546ed84db39", features = ["webgl", "fira-sans"] }
|
|
|
|
[profile.release]
|
|
strip = true
|
|
|
|
[[bench]]
|
|
name = "performance_benchmarks"
|
|
harness = false
|