From e3af7197a19ae843a1567de7b3a79d3aa3a96984 Mon Sep 17 00:00:00 2001 From: BinFlip Date: Sun, 9 Aug 2026 18:26:05 -0700 Subject: [PATCH 1/6] docs: expand .NET Reactor anti-tamper research notes --- docs/research/main.md | 2 +- docs/research/netreactor/anti-tamper.md | 166 ++++++++++++++++++------ 2 files changed, 129 insertions(+), 39 deletions(-) diff --git a/docs/research/main.md b/docs/research/main.md index 2340c729..100504dd 100644 --- a/docs/research/main.md +++ b/docs/research/main.md @@ -16,7 +16,7 @@ Research documentation for .NET obfuscators supported or investigated by dotscop | Obfuscator | Status | Documentation | |------------|--------|---------------| | [PureLogs](purelogs/main.md) | Active research (Phase 1 complete) | 10 analysis docs | -| [.NET Reactor](netreactor.md) | Gap analysis complete | Tier-based implementation plan | +| [.NET Reactor](netreactor/overview.md) | Sample analysis in progress (18 samples) | Per-protection reverse engineering + gap analysis | ## Obfuscator Comparison diff --git a/docs/research/netreactor/anti-tamper.md b/docs/research/netreactor/anti-tamper.md index f163c1e7..ba4f4902 100644 --- a/docs/research/netreactor/anti-tamper.md +++ b/docs/research/netreactor/anti-tamper.md @@ -4,6 +4,30 @@ Analysis of .NET Reactor 7.5.0 anti-tamper protection based on reverse engineeri `reactor_antitamp.exe` (48,640 bytes, 214 methods) against `original.exe` (14,336 bytes, 35 methods) using dotscope disassembly. +## Status (2026-04-24) — Landed + +`netreactor.antitamp` technique is implemented and wired into +`TechniqueRegistry::with_config`. `reactor_antitamp.exe` now executes +end-to-end under mono (full `=== Test App === → === Done ===` output), +taking NR mono executability to 9 / 17. The technique detects the +anti-tamper init via `.cctor` fan-in (no hard-coded names), marks the +init method + runtime container type + `{GUID}` marker + all +purely-injected `.cctor`s for removal, and attaches a Value-phase SSA +pass (`TokenResolverPass`) that folds the metadata-token resolver's +`accessor()` calls back into `ldtoken X` — without the fold, +user `typeof`/`is`/`typeof(List<>)` resolve to wrong types because the +resolver's hard-coded metadata-token arguments don't survive token +renumbering. The NR antitamp encrypted resource (256 B embedded +payload) is also cleaned up via the new +`CleanupRequest::add_manifest_resource(Token)` API: the technique +scans every method on the runtime container (and its nested types) for +`ldstr ` references, matches them against the assembly's +`ManifestResource` names, and marks each matched row; the writer's +existing resource-section compaction loop drops the embedded bytes and +remaps `offset_field` on surviving rows during regeneration. Output +now matches `original.exe` modulo only the known `.g.resources` +orphan. + ## File-Level Changes | Property | Original | Protected | Delta | @@ -94,42 +118,72 @@ Uses **RijndaelManaged (AES-256)** with a 32-byte IV from embedded static field and a key derived from string arguments. -## Anti-Tamper Verification Type +## Metadata-Token Resolver Type + +`YD8k0qML3PKMLfTJjJ.F46Ke0VXdMyeVlwqPE` (TypeDef 0x02000023 in the +current sample; name rotates between builds) — the NR metadata-token +resolver. Caches a `ModuleHandle` in a static field (`nxXPZyx8Ok`) and +exposes typed accessors that resolve raw metadata tokens to runtime +handles at load time. NR's rewriter replaces every user `ldtoken X` in +non-`.cctor` method bodies with `ldc.i4 ; call +accessor(int32)` — denying static analysis the direct type/field/method +reference and gating resolution behind the cached module handle. + +**⚠ Previous revisions of this doc incorrectly described the accessors +as `Interlocked.{Exchange,CompareExchange}` tamper-state wrappers; that +was a misreading of the first disassembly pass.** The actual bodies, +verified against the current 7.5.0 sample on 2026-04-24, use the +`ModuleHandle.GetRuntime{Type|Field|Method}HandleFromMetadataToken` BCL +methods — ordinary runtime metadata resolution, not interlocked state. -`YD8k0qML3PKMLfTJjJ.F46Ke0VXdMyeVlwqPE` — unique to anti-tamper, provides -thread-safe tamper state tracking: +### .cctor (token 0x060000d5 in current sample) + +Resolves the module via reflection and stores it to the static field: -### .cctor (token 0x060000d5) -Resolves the module via reflection and stores to a static field: ``` -ldtoken TypeDef(row 35) +ldtoken TypeDef(this type) call Type.GetTypeFromHandle() -callvirt Assembly.get_Assembly() +callvirt Type.get_Assembly() callvirt Assembly.GetModules() ldc.i4.0 / ldelem.ref -stsfld field(row 71) +callvirt Module.get_ModuleHandle() +stsfld +ret ``` -### Thread-Safe State Methods +### Accessor methods (4-instruction shape each) + +`RFfeRly7o(int32) -> RuntimeTypeHandle` — type-handle accessor: -`RFfeRly7o` (token 0x060000d2): Atomic exchange ``` -ldsflda field(row 71) +ldsflda ldarg.0 -call Interlocked.Exchange() +call instance ModuleHandle::GetRuntimeTypeHandleFromMetadataToken(int32) ret ``` -`T8QzrqFRj` (token 0x060000d3): Atomic compare-and-exchange +`T8QzrqFRj(int32) -> RuntimeFieldHandle` — field-handle accessor: + ``` -ldsflda field(row 71) +ldsflda ldarg.0 -call Interlocked.CompareExchange() +call instance ModuleHandle::GetRuntimeFieldHandleFromMetadataToken(int32) ret ``` -These provide thread-safe tamper state tracking — if tampering is detected during -concurrent type initialization, the state is atomically updated. +A corresponding `GetRuntimeMethodHandleFromMetadataToken` accessor is +not present in the current sample but the detector handles it for +forward compatibility. + +Why the fold matters: the `int32` argument is the *raw metadata token +value in the obfuscated assembly* (e.g. `0x01000003` = TypeRef row 3). +After cleanup remaps TypeRef rows, those hard-coded tokens would point +at different types. `TokenResolverPass` resolves each constant-argument +accessor call at deob time by replacing the `Call` with +`LoadToken(Token(raw_int))` — the generic token-remapping cleanup +pipeline then rewrites the `LoadToken`'s token to the correct post- +deobfuscation row, so user code keeps working and the resolver type +itself becomes truly orphan for the cleanup sweep. ## GUID-Annotated Marker Types @@ -147,27 +201,63 @@ the tamper verification hash. | Signal | Pattern | |--------|---------| | GUID types | `{GUID}` and `{GUID}` types | -| .cctor injection | Every type has `.cctor` calling the same target method | -| Interlocked ops | `Interlocked.Exchange`/`CompareExchange` in injected types | -| AES decryption | `RijndaelManaged` + 32-byte IV from `RuntimeHelpers.InitializeArray` | -| Trial guard | `DateTime(year, month, day)` + `TimeSpan.get_Days()` + 14-day check | - - -## Deobfuscation Strategy - -1. **Neutralize the .cctor chain**: Remove injected `.cctor` calls to the init method -2. **Remove verification types**: Delete `YD8k0qML3PKMLfTJjJ.F46Ke0VXdMyeVlwqPE`, - GUID-annotated types, and the shared runtime infrastructure -3. **Restore modified .cctors**: If a type originally had a `.cctor`, remove the - prepended `call` to the init method - -The NRS `AntiManipulationPatcher` (Stage 3) takes a different approach: it searches -for string literals "is tampered" and "Debugger Detected", then replaces the entire -method body with `ret`. Our approach can use the more reliable pattern of detecting -the `.cctor` injection and GUID marker types. +| `.cctor` fan-in | 5+ types' `.cctor`s converge on a single target method (implemented by `helpers::find_cctor_fan_in_target`) | +| Token-resolver accessor | Static method signature `(int32) -> ValueType` whose body is `ldsflda; ldarg.0; call ModuleHandle.GetRuntime*HandleFromMetadataToken; ret` (implemented by `helpers::find_nr_token_resolver`) | +| AES helper | `SymmetricAlgorithm`/`RijndaelManaged` + 32-byte IV loaded from an RVA field via `RuntimeHelpers.InitializeArray` (currently unused as a detection signal — left for future corroboration) | +| Trial guard | `DateTime(year, month, day)` + `TimeSpan.get_Days()` + 14-day check (owned by `netreactor.antitrial`) | + +The landed `netreactor.antitamp` detection requires (all must hold): + +1. **Gate**: `` trial guard present (same NR-context gate as + `licensecheck` / `privateimpl`). +2. **Primary**: `find_cctor_fan_in_target` returns `Some` (fan-in ≥ 5). +3. **Corroboration**: at least one `{GUID}` marker type OR one + `{GUID}` container is present. + + +## Deobfuscation Strategy (as implemented) + +1. **Mark the init method** (`init_method_token`) for cleanup — this + causes `NeutralizationPass` to NOP every surviving `call ` in + other method bodies (notably `::.cctor` and any `.cctor` + that had the init call prepended to user code). +2. **Mark the runtime container type** (`runtime_type_token` — the + init method's declaring type) — `expand_type_tokens` cascades to + its nested types (AES helper, CFF lookup tables, etc.), fields, and + methods. +3. **Mark purely-injected `.cctor`s** — thin bodies whose *only* + instruction stream is `call init; ret` (`classify_injected_cctors` + returns these). Modified `.cctor`s (init call prepended to user + code) are left in place — the NOP'd call is harmless and the user + portion survives. +4. **Mark `{GUID}` marker types** — the generic orphan sweep + refuses these (no non-cctor methods), so they need explicit + marking. `{GUID}` containers are + already owned by `netreactor.privateimpl`. +5. **Fold metadata-token resolver calls** — `TokenResolverPass` + (Value phase) rewrites `accessor()` → `LoadToken(Token)` + for every accessor of the detected resolver type. The resolver + type itself is marked for cleanup (detection gives its TypeDef + token) and becomes truly orphan after the fold. + +Compare to NRS's `AntiManipulationPatcher` (Stage 3), which searches +for string literals `"is tampered"` / `"Debugger Detected"` and nukes +the entire method body. That is name-fragile and, critically, drops +the runtime metadata-token accessors whether or not the init code is +removed — producing the same typeof-loss symptom we saw before landing +`TokenResolverPass`. ### dotscope Infrastructure Leverage -- **`NeutralizationPass`**: Can neutralize the anti-tamper check methods -- **Cleanup pipeline**: Orphan type removal handles the injected infrastructure -- **`.cctor` restoration**: Needs a pass to identify and remove prepended init calls +- **`NeutralizationPass`** — NOPs `call ` sites + (handles the init call in all surviving `.cctor`s and any user + method that happens to call the init). +- **`expand_type_tokens`** — cascades type-level deletions to nested + types, methods, fields. +- **`sweep_empty_module_cctor`** — picks up `::.cctor` once + the init (and trial) calls are NOP'd. +- **`find_unreferenced_types`** — orphan-sweeps the resolver type + after `TokenResolverPass` eliminates its only callers. +- **Token remapping / `RidRemapper`** — rewrites the `LoadToken` + tokens emitted by `TokenResolverPass` through the new TypeRef rows + during PE regeneration, keeping user `typeof`/`is` correct. From 43ee9181144ffc73473e8f501dbf123a89cb3e35 Mon Sep 17 00:00:00 2001 From: BinFlip Date: Sun, 9 Aug 2026 18:41:03 -0700 Subject: [PATCH 2/6] chore: assign copyright to ATRAPS LLC and ship the licence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Record ATRAPS LLC as copyright holder following the executed IP assignment. Two packaging defects surfaced while doing it. No licence text has ever shipped with this crate. LICENSE and NOTICE live at the workspace root, but the package root is dotscope/, and cargo only packages files under the package directory — so every published version declares `license = "Apache-2.0"` while shipping neither the licence nor the NOTICE. Both files now exist inside each member and are included in the packaged crate. LICENSE was also a symlink to LICENSE-APACHE rather than a file. Symlinks do not survive packaging cleanly, so LICENSE is now a regular file and the duplicate LICENSE-APACHE is removed. The README badge, the README link, and the crate-level doc badge in dotscope/src/lib.rs are repointed at it — that doc badge additionally pointed at a `main` branch that did not exist, so it was already dead. - LICENSE / NOTICE: "Copyright 2025-2026 ATRAPS LLC", the year range the commit history actually spans - Cargo.toml: drop `authors` from both members; point workspace `repository` / `homepage` at the org - README: name the holder and repoint badges and links at the org --- Cargo.toml | 4 +- LICENSE | 199 ++++++++++++++++++++++++- NOTICE | 4 +- README.md | 18 ++- dotscope-cli/Cargo.toml | 5 +- LICENSE-APACHE => dotscope-cli/LICENSE | 2 +- dotscope-cli/NOTICE | 24 +++ dotscope/Cargo.toml | 5 +- dotscope/LICENSE | 198 ++++++++++++++++++++++++ dotscope/NOTICE | 24 +++ dotscope/src/lib.rs | 2 +- 11 files changed, 464 insertions(+), 21 deletions(-) mode change 120000 => 100644 LICENSE rename LICENSE-APACHE => dotscope-cli/LICENSE (99%) create mode 100644 dotscope-cli/NOTICE create mode 100644 dotscope/LICENSE create mode 100644 dotscope/NOTICE diff --git a/Cargo.toml b/Cargo.toml index 8e758af7..2f1edc01 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,8 +6,8 @@ resolver = "2" [workspace.package] edition = "2021" license = "Apache-2.0" -repository = "https://github.com/BinFlip/dotscope" -homepage = "https://github.com/BinFlip/dotscope" +repository = "https://github.com/ATRAPSLLC/dotscope" +homepage = "https://github.com/ATRAPSLLC/dotscope" [profile.bench] debug = true diff --git a/LICENSE b/LICENSE deleted file mode 120000 index 6b579aae..00000000 --- a/LICENSE +++ /dev/null @@ -1 +0,0 @@ -LICENSE-APACHE \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..b87da574 --- /dev/null +++ b/LICENSE @@ -0,0 +1,198 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (which shall not include communications that are reasonably + considered separate from the work). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based upon (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and derivative works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control + systems, and issue tracking systems that are managed by, or on behalf + of, the Licensor for the purpose of discussing and improving the Work, + but excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to use, reproduce, modify, display, perform, + sublicense, and distribute the Work and such Derivative Works in + Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, trademark, patent, + attribution and disclaimer notices from the Source form + of the Work, excluding those notices that do not pertain to + any part of the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright notice to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Support. When redistributing the Work or + Derivative Works thereof, You may choose to offer, and charge a fee + for, warranty, support, indemnity or other liability obligations and/or + rights consistent with this License. However, in accepting such + obligations, You may act only on Your own behalf and on Your sole + responsibility, not on behalf of any other Contributor, and only if + You agree to indemnify, defend, and hold each Contributor harmless for + any liability incurred by, or claims asserted against, such Contributor + by reason of your accepting any such warranty or support. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in comments for the + particular language format. And that it is also recommended to have + a file's purpose and to note any changes briefly. + + Copyright 2025-2026 ATRAPS LLC + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/NOTICE b/NOTICE index 371fc19d..3c4369d7 100644 --- a/NOTICE +++ b/NOTICE @@ -1,7 +1,7 @@ dotscope -Copyright 2025-2026 Johann Kempter +Copyright 2025-2026 ATRAPS LLC -This product includes software developed by Johann Kempter. +This product includes software developed by ATRAPS LLC. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index 8c950092..06c2eab8 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ [![Crates.io](https://img.shields.io/crates/v/dotscope.svg)](https://crates.io/crates/dotscope) [![Documentation](https://docs.rs/dotscope/badge.svg)](https://docs.rs/dotscope) -[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE-APACHE) -[![Build Status](https://github.com/BinFlip/dotscope/workflows/CI/badge.svg)](https://github.com/BinFlip/dotscope/actions) -[![Coverage](https://codecov.io/gh/BinFlip/dotscope/branch/main/graph/badge.svg)](https://codecov.io/gh/BinFlip/dotscope) +[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE) +[![Build Status](https://github.com/ATRAPSLLC/dotscope/workflows/CI/badge.svg)](https://github.com/ATRAPSLLC/dotscope/actions) +[![Coverage](https://codecov.io/gh/ATRAPSLLC/dotscope/branch/main/graph/badge.svg)](https://codecov.io/gh/ATRAPSLLC/dotscope) A high-performance, cross-platform framework for analyzing, reverse engineering, and modifying .NET PE executables. Built in pure Rust, `dotscope` provides comprehensive tooling for parsing CIL (Common Intermediate Language) bytecode, metadata structures, disassembling .NET assemblies, and creating modified assemblies without requiring Windows or the .NET runtime. @@ -422,9 +422,11 @@ We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) f ## License -This project is licensed under the Apache License, Version 2.0. +Copyright 2025-2026 ATRAPS LLC. This project is licensed under the Apache +License, Version 2.0. -See [LICENSE-APACHE](LICENSE-APACHE) or for details. +See [LICENSE](LICENSE), [NOTICE](NOTICE), or + for details. ### Responsible Use Policy @@ -447,7 +449,7 @@ See [LICENSE-APACHE](LICENSE-APACHE) or "] +version = "0.8.5" edition.workspace = true license.workspace = true repository.workspace = true @@ -22,7 +21,7 @@ clap = { version = "4.6.4", features = ["derive", "env", "wrap_help"] } serde = { version = "1.0.229", features = ["derive"] } serde_json = "1.0.151" anyhow = "1.0.104" -comfy-table = "7.2.2" +comfy-table = "8.0.0" widestring = "1.2.1" ctrlc = "3.5.2" env_logger = "0.11.11" diff --git a/LICENSE-APACHE b/dotscope-cli/LICENSE similarity index 99% rename from LICENSE-APACHE rename to dotscope-cli/LICENSE index 0f25a428..b87da574 100644 --- a/LICENSE-APACHE +++ b/dotscope-cli/LICENSE @@ -183,7 +183,7 @@ particular language format. And that it is also recommended to have a file's purpose and to note any changes briefly. - Copyright 2025-2026 Johann Kempter + Copyright 2025-2026 ATRAPS LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/dotscope-cli/NOTICE b/dotscope-cli/NOTICE new file mode 100644 index 00000000..67645b80 --- /dev/null +++ b/dotscope-cli/NOTICE @@ -0,0 +1,24 @@ +dotscope-cli +Copyright 2025-2026 ATRAPS LLC + +This product includes software developed by ATRAPS LLC. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +---- + +This project includes the following third-party software: + +Third-party dependencies are listed in Cargo.toml and their licenses +can be found in their respective repositories. All dependencies are +compatible with the Apache 2.0 license. diff --git a/dotscope/Cargo.toml b/dotscope/Cargo.toml index 50d063e7..b6b84655 100644 --- a/dotscope/Cargo.toml +++ b/dotscope/Cargo.toml @@ -1,7 +1,6 @@ [package] name = "dotscope" -version = "0.8.4" -authors = ["Johann Kempter "] +version = "0.8.5" edition.workspace = true description = "A high-performance, cross-platform framework for analyzing and reverse engineering .NET PE executables" license.workspace = true @@ -70,7 +69,7 @@ hex = "0.4.3" num-bigint = { version = "0.5.1", optional = true } log = "0.4.33" flate2 = "1.1.9" -analyssa = "0.4.1" +analyssa = "0.5.0" lzma-rs = "0.3.0" z3 = { version = "0.20.2", optional = true } iced-x86 = { version = "1.21.0", default-features = false, features = ["std", "decoder", "instr_info"], optional = true } diff --git a/dotscope/LICENSE b/dotscope/LICENSE new file mode 100644 index 00000000..b87da574 --- /dev/null +++ b/dotscope/LICENSE @@ -0,0 +1,198 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (which shall not include communications that are reasonably + considered separate from the work). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based upon (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and derivative works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control + systems, and issue tracking systems that are managed by, or on behalf + of, the Licensor for the purpose of discussing and improving the Work, + but excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to use, reproduce, modify, display, perform, + sublicense, and distribute the Work and such Derivative Works in + Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, trademark, patent, + attribution and disclaimer notices from the Source form + of the Work, excluding those notices that do not pertain to + any part of the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright notice to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Support. When redistributing the Work or + Derivative Works thereof, You may choose to offer, and charge a fee + for, warranty, support, indemnity or other liability obligations and/or + rights consistent with this License. However, in accepting such + obligations, You may act only on Your own behalf and on Your sole + responsibility, not on behalf of any other Contributor, and only if + You agree to indemnify, defend, and hold each Contributor harmless for + any liability incurred by, or claims asserted against, such Contributor + by reason of your accepting any such warranty or support. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in comments for the + particular language format. And that it is also recommended to have + a file's purpose and to note any changes briefly. + + Copyright 2025-2026 ATRAPS LLC + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/dotscope/NOTICE b/dotscope/NOTICE new file mode 100644 index 00000000..3c4369d7 --- /dev/null +++ b/dotscope/NOTICE @@ -0,0 +1,24 @@ +dotscope +Copyright 2025-2026 ATRAPS LLC + +This product includes software developed by ATRAPS LLC. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +---- + +This project includes the following third-party software: + +Third-party dependencies are listed in Cargo.toml and their licenses +can be found in their respective repositories. All dependencies are +compatible with the Apache 2.0 license. diff --git a/dotscope/src/lib.rs b/dotscope/src/lib.rs index af25ef9d..67db3cc3 100644 --- a/dotscope/src/lib.rs +++ b/dotscope/src/lib.rs @@ -40,7 +40,7 @@ //! //! [![Crates.io](https://img.shields.io/crates/v/dotscope.svg)](https://crates.io/crates/dotscope) //! [![Documentation](https://docs.rs/dotscope/badge.svg)](https://docs.rs/dotscope) -//! [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](https://github.com/BinFlip/dotscope/blob/main/LICENSE-APACHE) +//! [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](https://github.com/ATRAPSLLC/dotscope/blob/main/LICENSE) //! //! A cross-platform framework for analyzing, deobfuscating, emulating, and modifying .NET PE executables. //! Built in pure Rust, `dotscope` provides comprehensive tooling for parsing CIL (Common Intermediate Language) From 17f6f01b636f0eb3fe19ee1330d15d0b8c086ac5 Mon Sep 17 00:00:00 2001 From: BinFlip Date: Sun, 9 Aug 2026 18:41:03 -0700 Subject: [PATCH 3/6] ci: retarget workflows from master to main MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prepares for the default-branch rename. `master` appeared in eight places in ci.yml — not only the push and pull_request triggers, but the job conditions gating fuzzing and the security audit, which compare against `refs/heads/master` and the PR base ref. Renaming the branch without these would leave those jobs silently never running. --- .github/workflows/ci.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 038c1656..336a41d7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,9 +2,9 @@ name: CI on: push: - branches: [ master ] + branches: [ main ] pull_request: - branches: [ master ] + branches: [ main ] concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} @@ -130,13 +130,13 @@ jobs: - name: Run tests (no default features) run: cargo test -p dotscope --no-default-features --release --verbose - # Fuzzing on pushes to master or PRs targeting master + # Fuzzing on pushes to main or PRs targeting main fuzzing: name: Quick Fuzzing runs-on: ubuntu-latest if: | - (github.event_name == 'push' && github.ref == 'refs/heads/master') || - (github.event_name == 'pull_request' && github.event.pull_request.base.ref == 'master') || + (github.event_name == 'push' && github.ref == 'refs/heads/main') || + (github.event_name == 'pull_request' && github.event.pull_request.base.ref == 'main') || contains(github.event.head_commit.message, '[fuzz]') steps: @@ -170,13 +170,13 @@ jobs: exit 1 fi - # Security audit on pushes to master or PRs targeting master + # Security audit on pushes to main or PRs targeting main security: name: Security Audit runs-on: ubuntu-latest if: | - (github.event_name == 'push' && github.ref == 'refs/heads/master') || - (github.event_name == 'pull_request' && github.event.pull_request.base.ref == 'master') + (github.event_name == 'push' && github.ref == 'refs/heads/main') || + (github.event_name == 'pull_request' && github.event.pull_request.base.ref == 'main') steps: - name: Checkout code From a29a4e1dcdae02e0f0e14860e2305018d8aa5837 Mon Sep 17 00:00:00 2001 From: BinFlip Date: Sun, 9 Aug 2026 18:41:20 -0700 Subject: [PATCH 4/6] build: update dependencies Upgrade `analyssa` 0.4.1 -> 0.5.0. That release fixes SSA rebuild and phi-transform correctness upstream: on a 125 MB reference binary its pass rollbacks went from 6,094 to 0 and verifier-reported undefined uses from ~28,960 to 0. No API changes were needed here. Upgrade `comfy-table` 7.2.2 -> 8.0.0. v8 removed the preset-string API entirely, so `Table::load_preset(presets::NOTHING)` becomes `Table::load_style(presets::NOTHING)`; presets are now `TableStyle` constants. `NOTHING` is still an empty style, so rendering is unchanged. Refresh everything else with `cargo update`. --- Cargo.lock | 322 ++++++++++++++++++++----------------- dotscope-cli/src/output.rs | 2 +- 2 files changed, 174 insertions(+), 150 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0f25dc92..af49f288 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,9 +20,9 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "aes" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1fc76eaeac4c9164506c466d4ffdd8ec9d0c5bf57ee97177c4d8eceb3a0e138" +checksum = "f8eb277bec05f56a0e0591f155a484cbd0f4f07ff2905051a48c72f004f7ed58" dependencies = [ "cipher", "cpubits", @@ -45,9 +45,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba" dependencies = [ "memchr", ] @@ -99,23 +99,23 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "analyssa" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79845a7f52583759a36e031fef550604c1d8d83b66fdeb7e3e0d31677bad144c" +checksum = "2879e5f80711226a2f0226ea504f34f6f13cdc983a64e4c5ab598c65884ebc4a" dependencies = [ "boxcar", "dashmap", "log", "num_enum", "rayon", - "thiserror 2.0.19", + "thiserror 2.0.20", ] [[package]] name = "android_system_properties" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +checksum = "ae221649c9976a6f6c56ae1facf410f3ddb33cc661c4b7b61020a912d4237fbc" dependencies = [ "libc", ] @@ -216,9 +216,9 @@ checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" [[package]] name = "archery" -version = "1.2.2" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e0a5f99dfebb87bb342d0f53bb92c81842e100bbb915223e38349580e5441d" +checksum = "33ca55ee147b1926dbea904f50fe4902494e97bc742205abbbf10c709e43815f" [[package]] name = "arg_enum_proc_macro" @@ -260,9 +260,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.91" +version = "0.1.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae36dc4177970ef04fde5178d3e2429882def40e57a451f919c098f72baa6cec" +checksum = "82f6aeea286b8eb4dd3431a1be1b59d290ace00f5bfd8e2a159bc2a05e2c1667" dependencies = [ "proc-macro2", "quote", @@ -294,9 +294,9 @@ dependencies = [ "log", "num-rational", "num-traits", - "pastey", + "pastey 0.1.1", "rayon", - "thiserror 2.0.19", + "thiserror 2.0.20", "v_frame", "y4m", ] @@ -326,9 +326,9 @@ dependencies = [ [[package]] name = "aws-lc-rs" -version = "1.17.3" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00bdb5da18dac48ca2cc7cd4a98e533e8635a58e2361d13a1a4ee3888e0d72f1" +checksum = "ce2b2dcc879c3bae0d371e77c99f2238400ef24ec001394befa67b6e543add9e" dependencies = [ "aws-lc-sys", "zeroize", @@ -336,9 +336,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.43.0" +version = "0.44.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43103168cc76fe62678a375e722fc9cb3a0146159ac5828bc4f0dfd755c2224c" +checksum = "f09fae7be8bb3174e05c6afdb34199e6dc0c7c04ba9fa237b1967adfbde27483" dependencies = [ "cc", "cmake", @@ -527,13 +527,13 @@ dependencies = [ [[package]] name = "bytemuck_derive" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f65693059b6b9c588b9f62fed1cedbf0a8b805631457ea162d68f0de186f3de5" +checksum = "fc0e56a716f1e132ff6bf4bdac1c944a3fcdc1cae65f70a4a2a1ac3b401d2d1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.119", + "syn 3.0.3", ] [[package]] @@ -565,7 +565,7 @@ dependencies = [ "cached_proc_macro_types", "hashbrown 0.15.5", "once_cell", - "thiserror 2.0.19", + "thiserror 2.0.20", "web-time", ] @@ -609,7 +609,7 @@ dependencies = [ "rand_distr 0.5.1", "rayon", "safetensors 0.7.0", - "thiserror 2.0.19", + "thiserror 2.0.20", "tokenizers 0.22.2", "yoke 0.8.3", "zip", @@ -626,7 +626,7 @@ dependencies = [ "objc2-foundation", "objc2-metal", "once_cell", - "thiserror 2.0.19", + "thiserror 2.0.20", "tracing", ] @@ -645,7 +645,7 @@ dependencies = [ "rayon", "safetensors 0.7.0", "serde", - "thiserror 2.0.19", + "thiserror 2.0.20", ] [[package]] @@ -684,9 +684,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.3.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c89588d05638b5b4594a3348a2d6c20277e43a7f5c5202b05cc56888475a47b8" +checksum = "5d262e149917187838d5b42777c8253bcb64500067342904e7d429499a6f277e" dependencies = [ "find-msvc-tools", "jobserver", @@ -784,9 +784,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.6.4" +version = "4.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91e0c145792ef73a6ad36d27c75ac09f1832222a3c209689d90f534685ee5b7" +checksum = "473c7e07f409a8d772161724aa8db6a765a2532a70f9667eeb7b49d3d02fbdca" dependencies = [ "clap_builder", "clap_derive", @@ -794,9 +794,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.6.2" +version = "4.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f09628afdcc538b57f3c6341e9c8e9970f18e4a481690a64974d7023bd33548b" +checksum = "7b48fea5a88e9ae728a2dcbedbfc0e730f7d60da42e1cb049a83c9fb8b789889" dependencies = [ "anstream", "anstyle", @@ -862,9 +862,9 @@ dependencies = [ [[package]] name = "comfy-table" -version = "7.2.2" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "958c5d6ecf1f214b4c2bbbbf6ab9523a864bd136dcf71a7e8904799acfe1ad47" +checksum = "136c8c4c3823846e8ba6d4bda011b4e5d5827b8bb0ac26c31f9ab31abe9f54f2" dependencies = [ "crossterm 0.29.0", "unicode-segmentation", @@ -961,7 +961,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59677f27c443ba67b4ee6af37659eaed4b7a1e68d28c4169167e550f17b8718e" dependencies = [ "memmap2", - "thiserror 2.0.19", + "thiserror 2.0.20", ] [[package]] @@ -1339,9 +1339,9 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.11.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8" +checksum = "4583a4551df46e2792f82ceeac45e850d2e2d5debba0b91f102385cda5b11f06" [[package]] name = "defmac" @@ -1377,7 +1377,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" dependencies = [ - "thiserror 2.0.19", + "thiserror 2.0.20", ] [[package]] @@ -1538,13 +1538,13 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" +checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.119", + "syn 3.0.3", ] [[package]] @@ -1564,7 +1564,7 @@ dependencies = [ [[package]] name = "dotscope" -version = "0.8.4" +version = "0.8.5" dependencies = [ "aes", "analyssa", @@ -1601,7 +1601,7 @@ dependencies = [ "smallvec 1.15.2", "strum 0.28.0", "tempfile", - "thiserror 2.0.19", + "thiserror 2.0.20", "tokio", "uguid", "widestring", @@ -1610,7 +1610,7 @@ dependencies = [ [[package]] name = "dotscope-cli" -version = "0.8.4" +version = "0.8.5" dependencies = [ "anyhow", "clap", @@ -1684,9 +1684,9 @@ checksum = "b2972feb8dffe7bc8c5463b1dacda1b0dfbed3710e50f977d965429692d74cd8" [[package]] name = "either" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" +checksum = "9e5e8f6c15a24b9a3ee5efec809ccd006d3b30e8b3bb63c39af737c7f87daa1d" dependencies = [ "serde", ] @@ -1708,9 +1708,9 @@ dependencies = [ [[package]] name = "encoding_rs_io" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cc3c5651fb62ab8aa3103998dade57efdd028544bd300516baa31840c252a83" +checksum = "fba3fe847045ecff794b9c138293a80db914678c453ad63fbf0c6a9eb6e00b22" dependencies = [ "encoding_rs", ] @@ -1866,9 +1866,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" +checksum = "26b73573e6edcd2af0cdf47bd6cb58f0b3839491263c314eaad1ccf24430e1de" [[package]] name = "flate2" @@ -1922,13 +1922,13 @@ dependencies = [ [[package]] name = "foreign-types-macros" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +checksum = "ea5190182e6915eb873ddbc16e23b711b6eb1f9c00a0d0a3a91b5f6228475225" dependencies = [ "proc-macro2", "quote", - "syn 2.0.119", + "syn 3.0.3", ] [[package]] @@ -2505,7 +2505,7 @@ dependencies = [ "reqwest 0.12.28", "serde", "serde_json", - "thiserror 2.0.19", + "thiserror 2.0.20", "tokio", "ureq", "windows-sys 0.60.2", @@ -2534,7 +2534,7 @@ checksum = "12d23156ea4dbe6b37ad48fab2da56ff27b0f6192fb5db210c44eb07bfe6e787" dependencies = [ "html5ever 0.38.0", "tendril 0.5.1", - "thiserror 2.0.19", + "thiserror 2.0.20", "unicode-width", ] @@ -2560,9 +2560,9 @@ dependencies = [ [[package]] name = "http" -version = "1.4.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425" +checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0" dependencies = [ "bytes", "itoa", @@ -2599,9 +2599,9 @@ checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "hybrid-array" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "818356c5132c1fede50f837ca96afbe78ff42413047f4abb886217845e1b6c8c" +checksum = "707114b52a152fa7bdb290cd7cd5912d9467273b6d74e21b8d81aca1f8533f6b" dependencies = [ "typenum", ] @@ -2948,9 +2948,9 @@ dependencies = [ [[package]] name = "interprocess" -version = "2.4.2" +version = "2.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "069323743400cb7ab06a8fe5c1ed911d36b6919ec531661d034c89083629595b" +checksum = "798de1433ba514cc6c04c4144c2469af81396e4906195218737c776d47769572" dependencies = [ "doctest-file", "libc", @@ -2961,9 +2961,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.12.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" +checksum = "6a756c3fac73139e83f14c2d742155dd2b78d3ee56597b419a0579b7bdd6dd78" [[package]] name = "is_terminal_polyfill" @@ -2997,17 +2997,19 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jiff" -version = "0.2.34" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e184d09547b80eb7e20d141ba2fb1fbac843ca53f4cf1b31210adc4c1adc6e16" +checksum = "668b7183bd07af9a4885f5c35b0cc5c83c4607a913c16b7e17291832910d2dcc" dependencies = [ "defmt", "jiff-core", "jiff-static", + "jiff-tzdb-platform", "log", "portable-atomic", "portable-atomic-util", "serde_core", + "windows-link 0.2.1", ] [[package]] @@ -3021,9 +3023,9 @@ dependencies = [ [[package]] name = "jiff-static" -version = "0.2.34" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "323da076b7a6faf914dc677cb05a4b907742ff7375c8322c9e7f5061e5e0e9de" +checksum = "3a69dcb3a21cfb32ce1cd056169337ca284af0766dd766e7878819b251a49204" dependencies = [ "jiff-core", "proc-macro2", @@ -3031,6 +3033,21 @@ dependencies = [ "syn 2.0.119", ] +[[package]] +name = "jiff-tzdb" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "142bd39932ad231f10513df9ab62661fead8719872150b7ad02a2df79f4e141e" + +[[package]] +name = "jiff-tzdb-platform" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8" +dependencies = [ + "jiff-tzdb", +] + [[package]] name = "jni" version = "0.22.4" @@ -3043,7 +3060,7 @@ dependencies = [ "jni-sys", "log", "simd_cesu8", - "thiserror 2.0.19", + "thiserror 2.0.20", "walkdir", "windows-link 0.2.1", ] @@ -3092,9 +3109,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.103" +version = "0.3.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" +checksum = "0e0c1080212aad755ea003d18543e8768dd432c48819efd73a7bf1e39b7a5a3a" dependencies = [ "cfg-if", "futures-util", @@ -3147,9 +3164,9 @@ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libredox" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c943259e342f1e06ff2da7a83eabdfe7f92ce10262688dbf1895ff0b3e6e4652" +checksum = "2026a5056764a10b2bf5d56488cba40da507f5493a6a429340e2004d9ed085fa" dependencies = [ "libc", ] @@ -3248,19 +3265,19 @@ checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" [[package]] name = "macro_rules_attribute" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65049d7923698040cd0b1ddcced9b0eb14dd22c5f86ae59c3740eab64a676520" +checksum = "b3ae8f6d608c795738406608304d30a2dfbdc8e58e44f7ba43236da5208ded3c" dependencies = [ "macro_rules_attribute-proc_macro", - "paste", + "pastey 0.2.3", ] [[package]] name = "macro_rules_attribute-proc_macro" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670fdfda89751bc4a84ac13eaa63e205cf0fd22b4c9a5fbfa085b63c1f1d3a30" +checksum = "fc04a4c58212d57930a24bf47d3fa87485264a3a054e9c10e042eb373573ad3c" [[package]] name = "malloc_buf" @@ -3387,9 +3404,9 @@ dependencies = [ [[package]] name = "minijinja" -version = "2.21.0" +version = "2.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb3d648e68cea56d9858d535ee28f9538404e2dd8cb08ed0bd05dca379477f39" +checksum = "42d74234349a775546a83af0f0c0c0e3a73227dee4950a542cda81a47240b3e6" dependencies = [ "memo-map", "serde", @@ -3398,9 +3415,9 @@ dependencies = [ [[package]] name = "minijinja-contrib" -version = "2.21.0" +version = "2.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85342f6fac0be8ccd5bd00d9066be538f34f393f577b75d81b17c8398a6b43bb" +checksum = "35c96d8fae7fa4743bbcf06f486ff43f81837f5e8826f8bf525dbc4c0e03be5d" dependencies = [ "minijinja", "serde", @@ -3463,10 +3480,10 @@ dependencies = [ "mistralrs-macros", "rand 0.9.5", "reqwest 0.13.4", - "schemars 1.2.1", + "schemars 1.2.2", "serde", "serde_json", - "thiserror 2.0.19", + "thiserror 2.0.20", "tokio", "tracing", "tracing-subscriber", @@ -3555,7 +3572,7 @@ dependencies = [ "rustc-hash 2.1.3", "rustfft", "safetensors 0.7.0", - "schemars 1.2.1", + "schemars 1.2.2", "scraper", "serde", "serde-big-array", @@ -3566,7 +3583,7 @@ dependencies = [ "strum 0.27.2", "symphonia", "sysinfo", - "thiserror 2.0.19", + "thiserror 2.0.20", "tokenizers 0.21.4", "tokio", "tokio-rayon", @@ -3630,7 +3647,7 @@ dependencies = [ "half", "objc2-foundation", "objc2-metal", - "thiserror 2.0.19", + "thiserror 2.0.20", ] [[package]] @@ -3657,7 +3674,7 @@ dependencies = [ "safetensors 0.7.0", "serde", "serde_json", - "thiserror 2.0.19", + "thiserror 2.0.20", "tokio", "tracing", "yoke 0.8.3", @@ -4080,7 +4097,7 @@ dependencies = [ "serde_with", "sha1 0.10.7", "sha2 0.10.9", - "thiserror 2.0.19", + "thiserror 2.0.20", ] [[package]] @@ -4182,6 +4199,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35fb2e5f958ec131621fdd531e9fc186ed768cbe395337403ae56c17a74c68ec" +[[package]] +name = "pastey" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ee67f1008b1ba2321834326597b8e186293b049a023cdef258527550b9935b4" + [[package]] name = "pbkdf2" version = "0.13.0" @@ -4312,9 +4335,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d20d5497ef88037a52ff98267d066e7f11fcc5e99bbfbd58a42336193aacec3" +checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" [[package]] name = "portable-atomic-util" @@ -4495,7 +4518,7 @@ dependencies = [ "rustc-hash 2.1.3", "rustls", "socket2", - "thiserror 2.0.19", + "thiserror 2.0.20", "tokio", "tracing", "web-time", @@ -4518,7 +4541,7 @@ dependencies = [ "rustls", "rustls-pki-types", "slab", - "thiserror 2.0.19", + "thiserror 2.0.20", "tinyvec", "tracing", "web-time", @@ -4722,7 +4745,7 @@ dependencies = [ "rand 0.9.5", "rand_chacha 0.9.0", "simd_helpers", - "thiserror 2.0.19", + "thiserror 2.0.20", "v_frame", "wasm-bindgen", ] @@ -4826,7 +4849,7 @@ checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ "getrandom 0.2.17", "libredox", - "thiserror 2.0.19", + "thiserror 2.0.20", ] [[package]] @@ -4863,9 +4886,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.16" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fcfdb36bda0c880c5931cdc7a2bcdc8ba4556847b9d912bca70bc94708711ad" +checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" dependencies = [ "aho-corasick", "memchr", @@ -5070,9 +5093,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.42" +version = "0.23.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c54fcab019b409d04215d3a17cb438fd7fbf192ee61461f20f4fe18704bc138" +checksum = "0283386ce02abc0151e1761d08802dfe86c173b0b494af5cbc086574e453da06" dependencies = [ "aws-lc-rs", "log", @@ -5098,9 +5121,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.15.0" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "764899a24af3980067ee14bc143654f297b22eaebfe3c7b6b211920a5a59b046" +checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96" dependencies = [ "web-time", "zeroize", @@ -5204,7 +5227,7 @@ checksum = "5e1aee7486406df3541b5a657204a11be97175a467d77bc98e6d94a66289fb80" dependencies = [ "arraydeque", "smallvec 2.0.0-alpha.12", - "thiserror 2.0.19", + "thiserror 2.0.20", ] [[package]] @@ -5230,9 +5253,9 @@ dependencies = [ [[package]] name = "schemars" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2b42f36aa1cd011945615b92222f6bf73c599a102a300334cd7f8dbeec726cc" +checksum = "687274d293b6cdc6e73e0fee520bf2049650090d7164f87672d212a3c530cf4a" dependencies = [ "dyn-clone", "ref-cast", @@ -5243,14 +5266,14 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d115b50f4aaeea07e79c1912f645c7513d81715d0420f8bc77a18c6260b307f" +checksum = "d98c67716b46af2f0b8cf752abc930f6f9aecfbf671ecfb531db8a31dbe4e2ba" dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.119", + "syn 3.0.3", ] [[package]] @@ -5409,13 +5432,13 @@ dependencies = [ [[package]] name = "serde_derive_internals" -version = "0.29.1" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" +checksum = "f852137cce035d6a4df67ccce505ff6b3e9fd3a10e3e52b24dc71e650bb1a9bd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.119", + "syn 3.0.3", ] [[package]] @@ -5464,9 +5487,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.21.0" +version = "3.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a5c54c7310e7b8b9577c286d7e399ddd876c3e12b3ed917a8aabc4b96e9e8c" +checksum = "ee78f1fbe43ac4a0e47aadb3dbd357b69eb0d3793e948624cd03dd2750ab1c0a" dependencies = [ "base64 0.22.1", "bs58", @@ -5474,8 +5497,9 @@ dependencies = [ "hex", "indexmap 1.9.3", "indexmap 2.14.0", + "jiff", "schemars 0.9.0", - "schemars 1.2.1", + "schemars 1.2.2", "serde_core", "serde_json", "serde_with_macros", @@ -5484,9 +5508,9 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.21.0" +version = "3.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84d57bc0c8b9a17920c178daa6bb924850d54a9c97ab45194bb8c17ad66bb660" +checksum = "8705578779c2b6bd90d84d66eb2e206b708b1a4d7b9f17641b293545bf1c7e46" dependencies = [ "darling 0.23.0", "proc-macro2", @@ -6119,11 +6143,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.19" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09a43598840e33d5b0331f38c5e30d13bb11c11210a4b58f0d9b18a5a5eefcd9" +checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" dependencies = [ - "thiserror-impl 2.0.19", + "thiserror-impl 2.0.20", ] [[package]] @@ -6139,9 +6163,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.19" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43cbfe0cf76104d42a574802844187e84a305e531ed54455f11fbde0f10541cd" +checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" dependencies = [ "proc-macro2", "quote", @@ -6173,9 +6197,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.54" +version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e1d5e639ff6bab73cb6885cc7e7b1de96c3f32c68ec55f3952614bec1092244" +checksum = "cdb87b95ec50ddfa440816d227a17b2ccbdda963a316a727fda0fc4334f7d134" dependencies = [ "deranged", "num-conv", @@ -6263,7 +6287,7 @@ dependencies = [ "serde", "serde_json", "spm_precompiled", - "thiserror 2.0.19", + "thiserror 2.0.20", "unicode-normalization-alignments", "unicode-segmentation", "unicode_categories", @@ -6296,7 +6320,7 @@ dependencies = [ "serde", "serde_json", "spm_precompiled", - "thiserror 2.0.19", + "thiserror 2.0.20", "unicode-normalization-alignments", "unicode-segmentation", "unicode_categories", @@ -6321,13 +6345,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.7.1" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6328af13490e73a9b4694030fafd93f8c8c6a9dede33e821c3fc63eddf8042ba" +checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.119", + "syn 3.0.3", ] [[package]] @@ -6450,9 +6474,9 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.1.2+spec-1.1.0" +version = "1.1.3+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +checksum = "1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56" dependencies = [ "winnow 1.0.4", ] @@ -6609,7 +6633,7 @@ dependencies = [ "log", "rand 0.9.5", "sha1 0.10.7", - "thiserror 2.0.19", + "thiserror 2.0.20", "utf-8", ] @@ -6904,9 +6928,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.126" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" +checksum = "1b70935747edd64d89de3efa29d73789b806c15798f8e7dca4d8ac356b50ce70" dependencies = [ "cfg-if", "once_cell", @@ -6917,9 +6941,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.76" +version = "0.4.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62df1340f32221cb9c54d6a27b030e3dba64361d4a95bed55f9aacb44da291d" +checksum = "6b7777d5cc23d0e91404e53ce2d5e8ec7acae3026b16233dba62cd3246457950" dependencies = [ "js-sys", "wasm-bindgen", @@ -6927,9 +6951,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.126" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" +checksum = "77775f8f3f7217702089053b94958f8f54061a3f663417df76e19cbdcca29bc1" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -6937,9 +6961,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.126" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" +checksum = "e11d33f857dc2fb11b8bc75aee111aa9cbeb12cd9f25efd3d4c2a3dd4e235284" dependencies = [ "bumpalo", "proc-macro2", @@ -6950,9 +6974,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.126" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" +checksum = "7ef64dbcc55df09c7e5a46182d181c2cfa3e925f3da937ea764728b4bbb9dcbf" dependencies = [ "unicode-ident", ] @@ -6985,9 +7009,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.103" +version = "0.3.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8622dcb61c0bcc9fffa6938bed81210af2da9a7e4a1a834b2e37a59b6dfb6141" +checksum = "c435338968042f4f59a557f690a253676d47ce13ceb55d70100e7facf6620a30" dependencies = [ "js-sys", "wasm-bindgen", @@ -7005,9 +7029,9 @@ dependencies = [ [[package]] name = "web_atoms" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "075474b12bcb3d2e3d4546580e9de478eeeead668a1761e2a8860c836b7ef297" +checksum = "ba8b815c1b593dc0baf78dd0f4fc8fdb2de53198fb1163738093e9a311c33fb3" dependencies = [ "phf", "phf_codegen", @@ -7592,18 +7616,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.55" +version = "0.8.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5a105cd7b140f6eeec8acff2ea38135d3cab283ada58540f629fe51e46696eb" +checksum = "556764e583adb45a9f8d413c2a147fa7e8d821e48e12b14fd560b607998b75eb" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.55" +version = "0.8.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fe976fb70c78cd64cccfe3a6fc142244e8a77b70959b30faf9d0ac37ee228eb" +checksum = "f2ab42fc20575779bd240faa45f94a74256f755c0fa9e89f0ede20d91d0cdfc1" dependencies = [ "proc-macro2", "quote", @@ -7690,9 +7714,9 @@ checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" [[package]] name = "zune-core" -version = "0.5.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb8a0807f7c01457d0379ba880ba6322660448ddebc890ce29bb64da71fb40f9" +checksum = "d56377fd46368984a170bc5aac5567e52ca5da874caa60bea39fcbca78fb658b" [[package]] name = "zune-inflate" diff --git a/dotscope-cli/src/output.rs b/dotscope-cli/src/output.rs index 7845aa64..a71ccf6c 100644 --- a/dotscope-cli/src/output.rs +++ b/dotscope-cli/src/output.rs @@ -73,7 +73,7 @@ impl TabWriter { pub fn new(columns: &[(&str, Align)]) -> Self { let mut table = Table::new(); table - .load_preset(presets::NOTHING) + .load_style(presets::NOTHING) .set_content_arrangement(ContentArrangement::Dynamic); let headers: Vec<&str> = columns.iter().map(|(name, _)| *name).collect(); From d640c320af58ba0f02a948eba7120db96c871bad Mon Sep 17 00:00:00 2001 From: BinFlip Date: Sun, 9 Aug 2026 18:41:20 -0700 Subject: [PATCH 5/6] ci: publish via trusted publishing, only from tags on main Replace the long-lived CARGO_REGISTRY_TOKEN repo secret with a short-lived OIDC token minted per run by crates-io-auth-action and revoked when the job ends. Grafted into the existing publish job rather than replacing the workflow, since release.yml also resolves the version, runs tests, and uploads binary artifacts. The containment check uses `git rev-parse HEAD` rather than $GITHUB_SHA because this job checks out the release tag explicitly. --- .github/workflows/release.yml | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f80de51a..2d8f63f8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -157,11 +157,25 @@ jobs: runs-on: ubuntu-latest needs: [version, test] + permissions: + contents: read + id-token: write # required to mint the crates.io OIDC token + steps: - name: Checkout code uses: actions/checkout@v7 with: ref: ${{ github.event.release.tag_name }} + fetch-depth: 0 # merge-base needs real history + + # A GitHub release can be cut from any commit, including one that never + # landed on main. Publishing is restricted to release tags that are + # actually contained in main. + - name: Refuse releases not contained in main + run: | + git fetch --no-tags origin +refs/heads/main:refs/remotes/origin/main + git merge-base --is-ancestor "$(git rev-parse HEAD)" refs/remotes/origin/main \ + || { echo "::error::release commit is not contained in main"; exit 1; } - name: Install Rust toolchain uses: dtolnay/rust-toolchain@stable @@ -172,10 +186,14 @@ jobs: - name: Verify package can be published run: cargo publish -p dotscope --dry-run + - name: Authenticate to crates.io + uses: rust-lang/crates-io-auth-action@v1 + id: auth + - name: Publish to crates.io run: cargo publish -p dotscope env: - CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }} # Verify documentation builds correctly verify-docs: From 4cf7cccb853f1f362499c73ac01c315b210f134c Mon Sep 17 00:00:00 2001 From: BinFlip Date: Sun, 9 Aug 2026 18:41:20 -0700 Subject: [PATCH 6/6] chore: release 0.8.5 0.8.4 is already published and its metadata is immutable, so the shipped licence text, corrected copyright holder, dropped `authors` field, and organisation URLs only reach crates.io in a new version. Both workspace members move to 0.8.5. Only `dotscope` is published; `dotscope-cli` has never been on crates.io and stays that way. --- CHANGELOG.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0da0c059..60e98fa4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,41 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.8.5] - 2026-08-09 + +### Fixed + +- **No licence text was shipped with the crate.** `LICENSE` and `NOTICE` live at the + workspace root, but the package root is `dotscope/`, and cargo only packages files + under the package directory — so every published version declared + `license = "Apache-2.0"` while shipping neither the licence nor the NOTICE. + Both files now exist inside the package and are included in the published crate. +- `LICENSE` was a symlink to `LICENSE-APACHE`. Symlinks do not survive packaging + cleanly; `LICENSE` is now a regular file and the duplicate `LICENSE-APACHE` is gone, + with the README badge and the crate-level doc badge repointed at it. + +### Dependencies + +- Upgraded `analyssa` 0.4.1 → 0.5.0, which fixes SSA rebuild and phi-transform + correctness: on a 125 MB reference binary the upstream pass rollbacks went from + 6,094 to 0 and verifier-reported undefined uses from ~28,960 to 0. No API changes + were needed here. +- Upgraded `comfy-table` 7.2.2 → 8.0.0. The preset-string API was removed in v8; + `Table::load_preset(presets::NOTHING)` becomes `Table::load_style(presets::NOTHING)`, + where presets are now `TableStyle` constants. Rendering is unchanged. +- Refreshed all remaining dependencies (`cargo update`), including `aes`, `clap`, + `thiserror`, and `smallvec`. + +### Changed + +- Recorded ATRAPS LLC as copyright holder in `LICENSE` and `NOTICE`. +- Dropped the deprecated `authors` field from both workspace members and repointed + `repository` / `homepage` at the organisation. +- Default branch renamed from `master` to `main`; CI triggers and the fuzzing and + security-audit job conditions were updated to match. +- Publishing now uses crates.io trusted publishing instead of a stored registry token, + and refuses to publish a release whose commit is not contained in `main`. + ## [0.8.4] - 2026-07-26 ### Added