diff --git a/THIRD-PARTY-NOTICES.md b/THIRD-PARTY-NOTICES.md index a3ecaef..f0900ab 100644 --- a/THIRD-PARTY-NOTICES.md +++ b/THIRD-PARTY-NOTICES.md @@ -10,43 +10,34 @@ Served copies of the license texts live under --- -## acadrust 0.4.1 — Mozilla Public License 2.0 — **MODIFIED** +## acadrust 0.6.5 — Mozilla Public License 2.0 — unmodified | | | |---|---| | Component | `acadrust` (DWG/DXF parser, Rust) | -| Version | 0.4.1 | +| Version | 0.6.5 | | License | MPL-2.0 — full text: [`public/licenses/acadrust-MPL-2.0.txt`](./public/licenses/acadrust-MPL-2.0.txt) (`/licenses/acadrust-MPL-2.0.txt`) | -| Upstream | https://github.com/hakanaktt/acadrust · https://crates.io/crates/acadrust/0.4.1 | -| Upstream commit | `f249c2f816acf36ee51cd5533716bdd443c2517e` (from the crate's `.cargo_vcs_info.json`) | +| Upstream | https://github.com/hakanaktt/acadrust · https://crates.io/crates/acadrust/0.6.5 | +| Upstream commit | `289a616da6c68518218594aa80802cbe7fa71309` (from the crate's `.cargo_vcs_info.json`) | +| Crate SHA-256 | `5eaa72520f70eb6f7f09b06f44e1ed0d8fad5fa743364f2c3715c30df962ec7c` (the `Cargo.lock` checksum the build used) | | Author | Hakan AK | | Shipped as | compiled into `assets/acadrust_dwg_bg-*.wasm` (Executable Form) | -**This copy is modified.** One file differs from the published crate: - -``` -src/io/dwg/dwg_stream_readers/object_reader/entities.rs (read_mesh array-count bounds) -``` - -The modification bounds `read_mesh`'s array counts by the bits remaining in the -object stream instead of the blanket 100 000-item guard, which truncated and -thereby corrupted large SubD meshes. +**This copy is not modified.** The `.wasm` is built from the published crate +exactly as crates.io serves it. ### How to obtain the Source Code Form (MPL-2.0 §3.2) -1. Get the unmodified crate source — `cargo vendor`, or - `https://crates.io/api/v1/crates/acadrust/0.4.1/download`, or the upstream - commit above. -2. Apply [`public/licenses/acadrust-0.4.1-read_mesh.patch`](./public/licenses/acadrust-0.4.1-read_mesh.patch) - (`/licenses/acadrust-0.4.1-read_mesh.patch` on the deployed site): +Download the crate, which is the complete source compiled into the shipped +`.wasm`: - ```bash - tar xf acadrust-0.4.1.crate && cd acadrust-0.4.1 - patch -p1 < acadrust-0.4.1-read_mesh.patch - ``` +```bash +curl -L -o acadrust-0.6.5.crate https://static.crates.io/crates/acadrust/acadrust-0.6.5.crate +tar xzf acadrust-0.6.5.crate +``` -The result is the exact Source Code Form of the acadrust code compiled into the -shipped `.wasm`. Both the original and the modified file remain under MPL-2.0. +or `cargo vendor` in any project that depends on `acadrust = "=0.6.5"`, or the +upstream commit above. --- diff --git a/index.html b/index.html index 0fb01ee..7b532e0 100644 --- a/index.html +++ b/index.html @@ -341,10 +341,10 @@ 지도: docs/modules-dwg-dxf.html
+ acadrust source can be obtained (unmodified 0.6.5, see the notice). -->오픈소스 고지: THIRD-PARTY-NOTICES - (acadrust · MPL-2.0 · local patch) + (acadrust 0.6.5 · MPL-2.0 · source)
diff --git a/public/licenses/THIRD-PARTY-NOTICES.md b/public/licenses/THIRD-PARTY-NOTICES.md index a3ecaef..f0900ab 100644 --- a/public/licenses/THIRD-PARTY-NOTICES.md +++ b/public/licenses/THIRD-PARTY-NOTICES.md @@ -10,43 +10,34 @@ Served copies of the license texts live under --- -## acadrust 0.4.1 — Mozilla Public License 2.0 — **MODIFIED** +## acadrust 0.6.5 — Mozilla Public License 2.0 — unmodified | | | |---|---| | Component | `acadrust` (DWG/DXF parser, Rust) | -| Version | 0.4.1 | +| Version | 0.6.5 | | License | MPL-2.0 — full text: [`public/licenses/acadrust-MPL-2.0.txt`](./public/licenses/acadrust-MPL-2.0.txt) (`/licenses/acadrust-MPL-2.0.txt`) | -| Upstream | https://github.com/hakanaktt/acadrust · https://crates.io/crates/acadrust/0.4.1 | -| Upstream commit | `f249c2f816acf36ee51cd5533716bdd443c2517e` (from the crate's `.cargo_vcs_info.json`) | +| Upstream | https://github.com/hakanaktt/acadrust · https://crates.io/crates/acadrust/0.6.5 | +| Upstream commit | `289a616da6c68518218594aa80802cbe7fa71309` (from the crate's `.cargo_vcs_info.json`) | +| Crate SHA-256 | `5eaa72520f70eb6f7f09b06f44e1ed0d8fad5fa743364f2c3715c30df962ec7c` (the `Cargo.lock` checksum the build used) | | Author | Hakan AK | | Shipped as | compiled into `assets/acadrust_dwg_bg-*.wasm` (Executable Form) | -**This copy is modified.** One file differs from the published crate: - -``` -src/io/dwg/dwg_stream_readers/object_reader/entities.rs (read_mesh array-count bounds) -``` - -The modification bounds `read_mesh`'s array counts by the bits remaining in the -object stream instead of the blanket 100 000-item guard, which truncated and -thereby corrupted large SubD meshes. +**This copy is not modified.** The `.wasm` is built from the published crate +exactly as crates.io serves it. ### How to obtain the Source Code Form (MPL-2.0 §3.2) -1. Get the unmodified crate source — `cargo vendor`, or - `https://crates.io/api/v1/crates/acadrust/0.4.1/download`, or the upstream - commit above. -2. Apply [`public/licenses/acadrust-0.4.1-read_mesh.patch`](./public/licenses/acadrust-0.4.1-read_mesh.patch) - (`/licenses/acadrust-0.4.1-read_mesh.patch` on the deployed site): +Download the crate, which is the complete source compiled into the shipped +`.wasm`: - ```bash - tar xf acadrust-0.4.1.crate && cd acadrust-0.4.1 - patch -p1 < acadrust-0.4.1-read_mesh.patch - ``` +```bash +curl -L -o acadrust-0.6.5.crate https://static.crates.io/crates/acadrust/acadrust-0.6.5.crate +tar xzf acadrust-0.6.5.crate +``` -The result is the exact Source Code Form of the acadrust code compiled into the -shipped `.wasm`. Both the original and the modified file remain under MPL-2.0. +or `cargo vendor` in any project that depends on `acadrust = "=0.6.5"`, or the +upstream commit above. --- diff --git a/public/licenses/acadrust-0.4.1-read_mesh.patch b/public/licenses/acadrust-0.4.1-read_mesh.patch deleted file mode 100644 index 59193bd..0000000 --- a/public/licenses/acadrust-0.4.1-read_mesh.patch +++ /dev/null @@ -1,111 +0,0 @@ ---- a/src/io/dwg/dwg_stream_readers/object_reader/entities.rs -+++ b/src/io/dwg/dwg_stream_readers/object_reader/entities.rs -@@ -1682,20 +1682,49 @@ - MLineData { scale_factor, justification, start_point, normal, openclosed, lines_in_style, vertex_count, vertices, style_handle } - } - -+/// Cap an array count against the bits actually left in the object's main -+/// stream instead of the blanket [`MAX_ARRAY_COUNT`]. -+/// -+/// MESH is the one entity whose arrays legitimately run past 100 000 items: a -+/// road-surface mesh in a civil drawing carries hundreds of thousands of -+/// vertices. Clamping those to the blanket cap does not merely truncate the -+/// mesh — the reader then continues from the wrong bit offset, so the face, -+/// edge and crease lists that follow decode as garbage (observed: a 100 000 -+/// vertex clamp left a 14-face mesh with face sizes `[64, 0, 64, 23, 0, …]`). -+/// Bounding by the remaining bits keeps the corrupt-data protection — no -+/// unbounded allocation is possible — without mis-parsing a valid drawing. -+/// -+/// `min_bits_per_item` is the shortest legal encoding of one element: a -+/// BitDouble is 2 bits at minimum (the 0.0 / 1.0 forms), so a 3BD vertex is 6 -+/// and a BitLong is 2. -+fn stream_bounded_count(reader: &DwgMergedReader, raw: i32, min_bits_per_item: i64) -> i32 { -+ let raw = raw.max(0) as i64; -+ let total_bits = (reader.main().data_len() as i64).saturating_mul(8); -+ // The handle stream follows the main stream; anything past its start is not -+ // array data. handle_start() is 0 when the framing did not supply it. -+ let handle_start = reader.handle_start(); -+ let end_bits = if handle_start > 0 { handle_start.min(total_bits) } else { total_bits }; -+ let remaining = (end_bits - reader.position_in_bits()).max(0); -+ raw.min(remaining / min_bits_per_item.max(1)).min(i32::MAX as i64) as i32 -+} -+ - pub fn read_mesh(reader: &mut DwgMergedReader) -> MeshData { - let version = reader.read_bit_short(); - let blend_crease = reader.read_bit(); - let subdivision_level = reader.read_bit_long(); - -- let num_verts = safe_count(reader.read_bit_long()); -+ let raw_verts = reader.read_bit_long(); -+ let num_verts = stream_bounded_count(reader, raw_verts, 6); - let mut vertices = Vec::with_capacity(num_verts as usize); - for _ in 0..num_verts { vertices.push(reader.read_3bit_double()); } - -- let total_face_data = safe_count(reader.read_bit_long()); -+ let raw_face_data = reader.read_bit_long(); -+ let total_face_data = stream_bounded_count(reader, raw_face_data, 2); - let mut faces = Vec::new(); - let mut i = 0; - while i < total_face_data { -- let n = safe_count(reader.read_bit_long()); -+ let raw_n = reader.read_bit_long(); -+ let n = stream_bounded_count(reader, raw_n, 2); - i += 1; - let mut face = Vec::new(); - for _ in 0..n { -@@ -1705,7 +1734,8 @@ - faces.push(face); - } - -- let num_edges = safe_count(reader.read_bit_long()); -+ let raw_edges = reader.read_bit_long(); -+ let num_edges = stream_bounded_count(reader, raw_edges, 4); - let mut edges = Vec::with_capacity(num_edges as usize); - for _ in 0..num_edges { - let s = reader.read_bit_long(); -@@ -1713,7 +1743,8 @@ - edges.push((s, e)); - } - -- let num_creases = safe_count(reader.read_bit_long()); -+ let raw_creases = reader.read_bit_long(); -+ let num_creases = stream_bounded_count(reader, raw_creases, 2); - let mut crease_values = Vec::with_capacity(num_creases as usize); - for _ in 0..num_creases { crease_values.push(reader.read_bit_double()); } - -@@ -2350,14 +2381,31 @@ - pub fn read_ole2frame(reader: &mut DwgMergedReader, version: DwgVersion) -> Ole2FrameData { - let ver = reader.read_bit_short(); - let mode = if version.r2000_plus() { reader.read_bit_short() } else { 0 }; -- // OLE binary data can be very large (embedded images/documents), -- // so don't use safe_count (100 KB cap). Use a generous 10 MB cap instead. - let data_len = (reader.read_bit_long().max(0) as usize).min(10_000_000); - let data = reader.read_bytes(data_len); - let trailing_byte = if version.r2000_plus() { reader.read_byte() } else { 3 }; -- let upper_left = reader.read_3bit_double(); -- let lower_right = reader.read_3bit_double(); -+ -+ let mut upper_left = Vector3::new(0.0, 0.0, 0.0); -+ let mut lower_right = Vector3::new(0.0, 0.0, 0.0); -+ -+ // Extract 4-corner coordinates stored in the OLE binary data header starting at offset 2 -+ if data.len() >= 66 { -+ let ul_x = f64::from_le_bytes(data[2..10].try_into().unwrap()); -+ let ul_y = f64::from_le_bytes(data[10..18].try_into().unwrap()); -+ let ul_z = f64::from_le_bytes(data[18..26].try_into().unwrap()); -+ let lr_x = f64::from_le_bytes(data[50..58].try_into().unwrap()); -+ let lr_y = f64::from_le_bytes(data[58..66].try_into().unwrap()); -+ let lr_z = if data.len() >= 74 { f64::from_le_bytes(data[66..74].try_into().unwrap()) } else { 0.0 }; -+ -+ if ul_x.is_finite() && ul_y.is_finite() && lr_x.is_finite() && lr_y.is_finite() -+ && (ul_x != 0.0 || ul_y != 0.0 || lr_x != 0.0 || lr_y != 0.0) { -+ upper_left = Vector3::new(ul_x, ul_y, if ul_z.is_finite() { ul_z } else { 0.0 }); -+ lower_right = Vector3::new(lr_x, lr_y, if lr_z.is_finite() { lr_z } else { 0.0 }); -+ } -+ } -+ - let ole_type = if version.r2000_plus() { reader.read_byte() } else { 2 }; -+ - Ole2FrameData { version: ver, mode, data, trailing_byte, upper_left, lower_right, ole_type } - } - diff --git a/src/viewer2d/acadrust-dwg/acadrust_dwg.d.ts b/src/viewer2d/acadrust-dwg/acadrust_dwg.d.ts index 42effc3..3b92c31 100644 --- a/src/viewer2d/acadrust-dwg/acadrust_dwg.d.ts +++ b/src/viewer2d/acadrust-dwg/acadrust_dwg.d.ts @@ -24,6 +24,7 @@ export interface InitOutput { readonly parse_dwg_json: (a: number, b: number) => [number, number, number, number]; readonly __wbindgen_malloc: (a: number, b: number) => number; readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number; + readonly __externref_table_alloc: () => number; readonly __wbindgen_externrefs: WebAssembly.Table; readonly __externref_table_dealloc: (a: number) => void; readonly __wbindgen_free: (a: number, b: number, c: number) => void; diff --git a/src/viewer2d/acadrust-dwg/acadrust_dwg.js b/src/viewer2d/acadrust-dwg/acadrust_dwg.js index a2ef7d2..ea75166 100644 --- a/src/viewer2d/acadrust-dwg/acadrust_dwg.js +++ b/src/viewer2d/acadrust-dwg/acadrust_dwg.js @@ -65,6 +65,10 @@ function __wbg_get_imports() { const ret = typeof(arg0) === 'string'; return ret; }, + __wbg___wbindgen_is_undefined_c05833b95a3cf397: function(arg0) { + const ret = arg0 === undefined; + return ret; + }, __wbg___wbindgen_throw_344f42d3211c4765: function(arg0, arg1) { throw new Error(getStringFromWasm0(arg0, arg1)); }, @@ -80,6 +84,14 @@ function __wbg_get_imports() { const ret = new Object(); return ret; }, + __wbg_now_e7c6795a7f81e10f: function(arg0) { + const ret = arg0.now(); + return ret; + }, + __wbg_performance_3fcf6e32a7e1ed0a: function(arg0) { + const ret = arg0.performance; + return ret; + }, __wbg_set_575dd786d51585f8: function(arg0, arg1, arg2) { const ret = arg0.set(arg1, arg2); return ret; @@ -90,6 +102,22 @@ function __wbg_get_imports() { __wbg_set_8a16b38e4805b298: function(arg0, arg1, arg2) { arg0[arg1 >>> 0] = arg2; }, + __wbg_static_accessor_GLOBAL_4ef717fb391d88b7: function() { + const ret = typeof global === 'undefined' ? null : global; + return isLikeNone(ret) ? 0 : addToExternrefTable0(ret); + }, + __wbg_static_accessor_GLOBAL_THIS_8d1badc68b5a74f4: function() { + const ret = typeof globalThis === 'undefined' ? null : globalThis; + return isLikeNone(ret) ? 0 : addToExternrefTable0(ret); + }, + __wbg_static_accessor_SELF_146583524fe1469b: function() { + const ret = typeof self === 'undefined' ? null : self; + return isLikeNone(ret) ? 0 : addToExternrefTable0(ret); + }, + __wbg_static_accessor_WINDOW_f2829a2234d7819e: function() { + const ret = typeof window === 'undefined' ? null : window; + return isLikeNone(ret) ? 0 : addToExternrefTable0(ret); + }, __wbindgen_cast_0000000000000001: function(arg0) { // Cast intrinsic for `F64 -> Externref`. const ret = arg0; @@ -126,6 +154,12 @@ function __wbg_get_imports() { }; } +function addToExternrefTable0(obj) { + const idx = wasm.__externref_table_alloc(); + wasm.__wbindgen_externrefs.set(idx, obj); + return idx; +} + let cachedDataViewMemory0 = null; function getDataViewMemory0() { if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) { @@ -146,6 +180,10 @@ function getUint8ArrayMemory0() { return cachedUint8ArrayMemory0; } +function isLikeNone(x) { + return x === undefined || x === null; +} + function passArray8ToWasm0(arg, malloc) { const ptr = malloc(arg.length * 1, 1) >>> 0; getUint8ArrayMemory0().set(arg, ptr / 1); diff --git a/src/viewer2d/acadrust-dwg/acadrust_dwg_bg.wasm b/src/viewer2d/acadrust-dwg/acadrust_dwg_bg.wasm index 36bd496..1034849 100644 Binary files a/src/viewer2d/acadrust-dwg/acadrust_dwg_bg.wasm and b/src/viewer2d/acadrust-dwg/acadrust_dwg_bg.wasm differ diff --git a/src/viewer2d/acadrust-dwg/acadrust_dwg_bg.wasm.d.ts b/src/viewer2d/acadrust-dwg/acadrust_dwg_bg.wasm.d.ts index 309dbd8..9e468c7 100644 --- a/src/viewer2d/acadrust-dwg/acadrust_dwg_bg.wasm.d.ts +++ b/src/viewer2d/acadrust-dwg/acadrust_dwg_bg.wasm.d.ts @@ -5,6 +5,7 @@ export const parse_dwg: (a: number, b: number) => [number, number, number]; export const parse_dwg_json: (a: number, b: number) => [number, number, number, number]; export const __wbindgen_malloc: (a: number, b: number) => number; export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number; +export const __externref_table_alloc: () => number; export const __wbindgen_externrefs: WebAssembly.Table; export const __externref_table_dealloc: (a: number) => void; export const __wbindgen_free: (a: number, b: number, c: number) => void; diff --git a/src/viewer2d/dwgParser.ts b/src/viewer2d/dwgParser.ts index f8307bd..4295159 100644 --- a/src/viewer2d/dwgParser.ts +++ b/src/viewer2d/dwgParser.ts @@ -1,6 +1,6 @@ /** * DWG parser — rust/dwg-wasm wrapper around the acadrust crate (MPL-2.0, - * vendored with a local read_mesh patch; see hmwebviewer rust/dwg-wasm). Emits + * 0.6.5 from crates.io, unmodified; see hmwebviewer rust/dwg-wasm). Emits * the parseResult shape Viewer2D.load() consumes. Lazy-imported so the wasm is * only fetched when a DWG is actually opened. *