canon 0.3.29 → 0.3.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CLAUDE.md +4 -0
- data/lib/canon/version.rb +1 -1
- data/lib/canon/xml/c14n.rb +44 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 308416a45e76807d58f00f40a88d5d6f53617d2a9dac468da8add04fa8175a2f
|
|
4
|
+
data.tar.gz: 2fa30986100df7b8238263546513705513635bd6c39f1552f0e0f8774f510f5f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0ffdb20ffc91117fdf24afb405f1684aea837316c1481ed5cc7e435bff4bf5d409876d9ca5851e187d3cd128b192ce3516b49114e6ac5d56a327dd87330f0ec9
|
|
7
|
+
data.tar.gz: aaeac239ac4707d8034eb92c8205753e3ec94ff203bf0b4023c33d0b7a92d57742e632ee29998de5a2ed041e45ea7bf2453b2479bb24ed9b9164dacba8db4ab1
|
data/CLAUDE.md
CHANGED
|
@@ -143,6 +143,10 @@ Engine parity is complete through libleptris 1.9.8 / leptris-ruby 1.9.33 / moxml
|
|
|
143
143
|
|
|
144
144
|
Engine A/B testing: `CANON_XML_BACKEND=nokogiri bundle exec rspec` (or `=moxml` to force leptris when it isn't the resolved default). The default suite must stay green under BOTH values; the only expected pendings are the upstream-tracked ones. The benchmark header (`rake performance:quick`) reports the active engine.
|
|
145
145
|
|
|
146
|
+
### C14N Engines
|
|
147
|
+
|
|
148
|
+
`Canon::Xml::C14n.canonicalize` stays on canon's Ruby C14N 1.1 processor by default. leptris' native C-side C14N 1.1 is ~50x faster on large documents and byte-identical on the main corpus, but diverges from the spec on edge cases (attribute ordering, prefix preservation, `>`/tab escaping, document-level PIs — leptris#1015, all pinned in `spec/canon/xml/c14n_engine_parity_spec.rb`). `CANON_C14N_BACKEND=leptris` opts in; when the parity gate runs clean the default flips. `canonicalize_subset` and `with_comments: true` always use the Ruby processor.
|
|
149
|
+
|
|
146
150
|
### YAML Engines
|
|
147
151
|
|
|
148
152
|
`Canon::YamlBackend` selects the YAML engine: `:psych` (default) or `:yeptris` (FFI over libyeptris, the YAML counterpart of the leptris XML stack — `CANON_YAML_BACKEND=yeptris` opts in; the optional `yeptris` Gemfile group must be enabled). `Canon::YamlParsing` is the single gateway for string loads; `Canon::JsonParsing` mirrors it for JSON (the same yeptris engine serves both — `Yeptris::YAML.load` auto-detects JSON and routes to the native C-API materializer; JSON falls back to stdlib unless `YamlBackend.yeptris_native?`, since the FFI ladder is ~29x slower than the stdlib C extension). `YAML.dump` stays on Psych everywhere — canonical output bytes are canon's product and the writers differ. **JSON defaults to the strict yeptris surface whenever the native materializer is installed** (yeptris 0.1.13.4 ships platform gems — zero compilation, zero env; parity spec-pinned to `JSON.parse` upstream). The YAML default stays `:psych` until the yeptris Psych-parity gaps close (yeptris-ruby#30 sexagesimal scalars, #31 >64-bit integers — #29 empty documents was fixed in 0.1.12); `spec/canon/yaml_engine_parity_spec.rb` is the executable gate, with upstream-tracked cases pending. Never `require "yeptris/psych"` — it rebinds the global `::Psych` constant for the whole process; only the namespaced `Yeptris::YAML` API is used.
|
data/lib/canon/version.rb
CHANGED
data/lib/canon/xml/c14n.rb
CHANGED
|
@@ -10,6 +10,10 @@ module Canon
|
|
|
10
10
|
# @param with_comments [Boolean] Include comments in canonical form
|
|
11
11
|
# @return [String] Canonical form in UTF-8
|
|
12
12
|
def self.canonicalize(xml, with_comments: false)
|
|
13
|
+
if (native = native_canonicalize(xml, with_comments))
|
|
14
|
+
return native
|
|
15
|
+
end
|
|
16
|
+
|
|
13
17
|
# Build XPath data model
|
|
14
18
|
root_node = DataModel.from_xml(xml)
|
|
15
19
|
|
|
@@ -18,6 +22,46 @@ module Canon
|
|
|
18
22
|
processor.process(root_node)
|
|
19
23
|
end
|
|
20
24
|
|
|
25
|
+
# leptris' C-side C14N 1.1 — ~50x faster than the Ruby processor
|
|
26
|
+
# but NOT yet byte-identical on canon's edge-case corpus
|
|
27
|
+
# (attribute ordering, `>` escaping, document-level PIs, one
|
|
28
|
+
# prefix case — leptris#1015; the parity spec pins
|
|
29
|
+
# each). Opt-in via CANON_C14N_BACKEND=leptris until those
|
|
30
|
+
# close; comments mode keeps the Ruby path regardless (the
|
|
31
|
+
# native seam exposes no with-comments form).
|
|
32
|
+
def self.native_canonicalize(xml, with_comments)
|
|
33
|
+
return nil if with_comments
|
|
34
|
+
return nil if RUBY_ENGINE == "opal"
|
|
35
|
+
return nil unless ENV["CANON_C14N_BACKEND"].to_s.casecmp("leptris").zero?
|
|
36
|
+
return nil unless Canon::XmlBackend.moxml? &&
|
|
37
|
+
Canon::XmlParsing.moxml_adapter_name == :leptris
|
|
38
|
+
return nil unless native_c14n_available?
|
|
39
|
+
|
|
40
|
+
doc = Canon::XmlParsing.moxml_context.parse(xml, readonly: true,
|
|
41
|
+
strict: false)
|
|
42
|
+
begin
|
|
43
|
+
doc.native.canonicalize(::Leptris::XML::FFI::C14N_1_1, nil,
|
|
44
|
+
mode: ::Leptris::XML::FFI::C14N_MODE_CANONICAL)
|
|
45
|
+
ensure
|
|
46
|
+
doc.free
|
|
47
|
+
end
|
|
48
|
+
rescue StandardError
|
|
49
|
+
# Malformed inputs are the Ruby path's domain (recovery parse
|
|
50
|
+
# + parse_errors surfacing), not the native lane's.
|
|
51
|
+
nil
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def self.native_c14n_available?
|
|
55
|
+
return @native_c14n_available unless @native_c14n_available.nil?
|
|
56
|
+
|
|
57
|
+
@native_c14n_available = defined?(::Leptris::XML::FFI::C14N_1_1) &&
|
|
58
|
+
::Leptris::XML::FFI.constants.include?(:C14N_MODE_CANONICAL)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def self.reset_native_probe!
|
|
62
|
+
@native_c14n_available = nil
|
|
63
|
+
end
|
|
64
|
+
|
|
21
65
|
# Canonicalize a document subset selected by XPath expression.
|
|
22
66
|
#
|
|
23
67
|
# Implements W3C C14N 1.1 subset canonicalization:
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: canon
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.30
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-09-
|
|
11
|
+
date: 2026-09-12 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: diff-lcs
|