Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,47 @@ compatibility (see [RELEASING.md](RELEASING.md)).

## [Unreleased]

## [0.11.1] — 2026-07-13

### Fixed

- **`ml_normalize` is now idempotent on NFKD-exposed symbol bases (#498).** The
`"cldr"` preset was non-idempotent on negated-relation symbols whose NFKD
decomposition strips a combining overlay to expose a nameable base (e.g. `≇`
U+2247 → `≅` U+2245 + U+0338 overlay). Because demojize ran before
accent-stripping, the freshly-exposed base was only named on a *second* call,
so `ml_normalize(x) != ml_normalize(ml_normalize(x))` across the enumerated
17-member negated-symbol class. A second CLDR demojize pass now runs right
after accent-stripping, so bases exposed within a call reach a true fixed
point in a single call.
- **`normalize_confusables` is now idempotent and complete on confusable +
combining-mark input (#523).** Confusable folding and canonical composition
interact both ways — a fold can expose a composition (`¥`+◌̀ → `Y`+◌̀ → `Ỳ`) and
a composition can expose a new fold (`Ҫ`+◌̧ → `Ç` → `C`, since `Ç` is itself a
confusable) — so a single pass was not always a fixed point, and could even
leave a residual confusable in the output. The fold/compose pass now iterates
to a fixed point, restoring both idempotency and completeness. Guarded by a new
exhaustive Tier-3 test over every confusable × combining-mark pair (~9M).

### Documentation

- **Documented `unidecode()` Cyrillic soft/hard-sign collisions (#511).** The
compatibility `unidecode()` path maps the Cyrillic soft sign (ь) and hard sign
(ъ) to the empty string, so otherwise-distinct inputs can collide; the
limitation is now called out with a pointer to the script-aware
`transliterate(…, lang=…)` path that preserves them.

### Internal

- **Binding publishers are gated on the published core (#500).** The npm and
RubyGems publish jobs build their native addon/gem against `disarm` as a
crates.io dependency, so on a release they now wait for the core crate to land
on crates.io before building instead of racing it — removing the manual
re-run every prior release required. No library-behavior change.
- **Held `phf`/`phf_codegen` at 0.13 to preserve MSRV 1.81 (#510).** phf 0.14
moves to edition 2024 / Rust 1.85; a dependabot group now keeps the pair in
lockstep and pins it below 0.14 until the MSRV is deliberately raised.

## [0.11.0] — 2026-06-21

### Performance
Expand Down
2 changes: 1 addition & 1 deletion CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ identifiers:
- type: doi
value: "10.5281/zenodo.20618323"
description: "XMR metric and broad-sample adversarial-defense benchmark (v2 technical note)"
version: "0.11.0"
version: "0.11.1"
license: MIT
repository-code: "https://github.com/raeq/disarm"
url: "https://docs.disarm.dev"
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "disarm"
version = "0.11.0"
version = "0.11.1"
Comment thread
raeq marked this conversation as resolved.
edition = "2021"
rust-version = "1.81"
license = "MIT"
Expand Down
2 changes: 1 addition & 1 deletion bindings/node/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "disarm",
"version": "0.11.0",
"version": "0.11.1",
"description": "Unicode confusable/text-security building blocks, powered by Rust",
"main": "index.js",
"types": "index.d.ts",
Expand Down
2 changes: 1 addition & 1 deletion bindings/ruby/lib/disarm/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@

module Disarm
# Kept in lockstep with the Rust crate / Python package version.
VERSION = "0.11.0"
VERSION = "0.11.1"
end
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "maturin"

[project]
name = "disarm"
version = "0.11.0"
version = "0.11.1"
description = "Unicode canonicalization and TR39 visual confusable analysis for Python: building blocks for text-security pipelines (homoglyph/bidi/zalgo/invisible-character handling) plus standards-based phonetic transliteration — powered by Rust"
readme = "README.md"
requires-python = ">=3.10"
Expand Down
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading