leptris 1.9.43 → 1.9.44
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/CHANGELOG.md +29 -0
- data/Rakefile +1 -1
- data/lib/leptris/version.rb +1 -1
- data/lib/leptris/xml/document.rb +12 -4
- data/lib/leptris/xml/ffi.rb +17 -3
- data/lib/leptris/xml/node.rb +25 -0
- data/lib/leptris/xml/serialization.rb +22 -2
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9895934a1c086857555795905c15ab4f74ef053804e489674192bc7f4cc70bf3
|
|
4
|
+
data.tar.gz: b1bf31ac8c0ef5f718d78d4ae0654218cd3c212adf33e75628326949644032d1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 536c0b5a7ddb425395b077f5a6a0b40ebc893c6037ba71277a1b6eaa70b9769e977b03b9ed0f81ccf6d9a70e11c4f4095b8ab3e473268f2cb38306ea897d28e4
|
|
7
|
+
data.tar.gz: d34c001bf6840c12d3e44a0253166938523f57c0e935a6dfa4560cea575b02af043d25caf0a491a77810726b168c64e556c63b825355eb3ff23ffbbf010848c5
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,35 @@ All notable changes to Leptris will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.9.44] - 2026-08-31
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **libleptris 1.9.19–1.9.22 lockstep** (audit 255/255, three new
|
|
13
|
+
symbols): the #653 hold is lifted — the reported parse
|
|
14
|
+
"regression" was an ill-formed fixture (stray `</y>`) plus a
|
|
15
|
+
stale-build bisect artifact; forced-clean rebuilds show 1.9.18
|
|
16
|
+
and 1.9.21+ identical on every well-formed shape (verified and
|
|
17
|
+
withdrawn on the issue).
|
|
18
|
+
- **`Node#visit`** (upstream #645a, `leptris_node_visit`): one C
|
|
19
|
+
call over the subtree — elements yield `(node, true/false,
|
|
20
|
+
depth)` enter/leave pairs, other kinds once, depth from the
|
|
21
|
+
receiver; the document node walks the document chain. No
|
|
22
|
+
NodeSet, pointer array, or children memo per level — the leanest
|
|
23
|
+
full-subtree iteration the binding offers (#645a's walk lever;
|
|
24
|
+
consumers can now beat the children-recursion allocation floor).
|
|
25
|
+
- **Indent unit with Nokogiri semantics (leptris-ruby#109,
|
|
26
|
+
upstream #633)**: `to_xml(indent: 2, indent_text: "\t")` — the
|
|
27
|
+
unit string replaces the default spaces, repeated `indent`
|
|
28
|
+
times per depth level, standard layout otherwise
|
|
29
|
+
(byte-identical to Nokogiri's output modulo their trailing
|
|
30
|
+
newline, which moxml normalizes). `indent_text: true` keeps the
|
|
31
|
+
display form; `false` the default. Wired through the sized
|
|
32
|
+
ext-serialize entry (PR #107's substance — the audit requires it
|
|
33
|
+
attached with the lockstep, so it rides here; the engine emits
|
|
34
|
+
one unit copy per level and the binding multiplies unit x indent
|
|
35
|
+
to reach Nokogiri's repeat count).
|
|
36
|
+
|
|
8
37
|
## [1.9.43] - 2026-08-31
|
|
9
38
|
|
|
10
39
|
### Fixed
|
data/Rakefile
CHANGED
|
@@ -8,7 +8,7 @@ RSpec::Core::RakeTask.new(:spec)
|
|
|
8
8
|
# Pin for `rake compile` and the platform-gem builds. Keep in lockstep
|
|
9
9
|
# with .github/workflows/build.yml (which calls `rake compile`) and the
|
|
10
10
|
# CHANGELOG when libleptris releases.
|
|
11
|
-
LIBLEPTRIS_VERSION = "1.9.
|
|
11
|
+
LIBLEPTRIS_VERSION = "1.9.22"
|
|
12
12
|
|
|
13
13
|
CMAKE_FLAGS = %w[
|
|
14
14
|
-DCMAKE_BUILD_TYPE=Release
|
data/lib/leptris/version.rb
CHANGED
data/lib/leptris/xml/document.rb
CHANGED
|
@@ -266,13 +266,21 @@ class Leptris::XML::Document
|
|
|
266
266
|
end
|
|
267
267
|
alias_method :internal_subset, :doctype
|
|
268
268
|
|
|
269
|
-
# indent_text
|
|
270
|
-
#
|
|
271
|
-
#
|
|
269
|
+
# indent_text selects the ext-serializer knob (libleptris 1.9.22):
|
|
270
|
+
# a STRING is the indent unit with Nokogiri's semantics — the unit
|
|
271
|
+
# replaces the default spaces, one copy per depth level, standard
|
|
272
|
+
# layout (requires indent > 0); true selects the display form
|
|
273
|
+
# (1.9.9 #129 — text and mixed content indent too; output is
|
|
274
|
+
# display-oriented and not round-trip-guaranteed).
|
|
272
275
|
def to_xml(indent: 0, no_decl: false, encoding: nil, indent_text: false)
|
|
273
276
|
raise Leptris::XML::UseAfterFreeError if @freed.state == :freed
|
|
274
277
|
return "" if @c_ptr.nil?
|
|
275
|
-
|
|
278
|
+
case indent_text
|
|
279
|
+
when String
|
|
280
|
+
return Leptris::XML::Serialization.to_xml_indent_unit(
|
|
281
|
+
@c_ptr, indent_text, indent: indent, no_decl: no_decl,
|
|
282
|
+
encoding: encoding)
|
|
283
|
+
when true
|
|
276
284
|
return Leptris::XML::Serialization.to_xml_display(
|
|
277
285
|
@c_ptr, indent: indent, no_decl: no_decl, encoding: encoding)
|
|
278
286
|
end
|
data/lib/leptris/xml/ffi.rb
CHANGED
|
@@ -72,10 +72,13 @@ module Leptris
|
|
|
72
72
|
:encoding, :pointer
|
|
73
73
|
end
|
|
74
74
|
|
|
75
|
-
# LeptrisSerializeExtOptions (1.9.9
|
|
76
|
-
#
|
|
75
|
+
# LeptrisSerializeExtOptions (1.9.9 #129 display form; 1.9.22
|
|
76
|
+
# #633/#109 indent unit): knobs beyond the ABI-frozen options
|
|
77
|
+
# struct. MAY grow — always pass its size through the sized
|
|
78
|
+
# entry.
|
|
77
79
|
class SerializeExtStruct < ::FFI::Struct
|
|
78
|
-
layout :indent_text, :int
|
|
80
|
+
layout :indent_text, :int,
|
|
81
|
+
:indent_unit, :pointer
|
|
79
82
|
end
|
|
80
83
|
|
|
81
84
|
# Mirrors LeptrisParseOptions (libleptris >= 1.9.0 carries the
|
|
@@ -154,6 +157,12 @@ module Leptris
|
|
|
154
157
|
# 1.9.7, upstream #580; the libxml2 model).
|
|
155
158
|
attach_function :leptris_document_node,
|
|
156
159
|
[:leptris_document], :leptris_node_ref
|
|
160
|
+
# Wrap-free subtree visitation (1.9.20, upstream #645a):
|
|
161
|
+
# enter/leave pairs for elements, depth from the walk's root,
|
|
162
|
+
# one C call — no NodeSet/Array churn per level. The document
|
|
163
|
+
# node walks the document child chain.
|
|
164
|
+
attach_function :leptris_node_visit,
|
|
165
|
+
[:leptris_node_ref, :pointer, :pointer], :void
|
|
157
166
|
# Document-level PIs (v1.6.0): not tree nodes — enumerate via
|
|
158
167
|
# these accessors only.
|
|
159
168
|
attach_function :leptris_document_pi_count,
|
|
@@ -646,6 +655,11 @@ module Leptris
|
|
|
646
655
|
# read_owned_string (the seam frees it).
|
|
647
656
|
attach_function :leptris_document_serialize_ext,
|
|
648
657
|
[:leptris_document, :pointer, :pointer], :pointer
|
|
658
|
+
# Sized variant (1.9.19, upstream #644 — leptris-ruby PR #107):
|
|
659
|
+
# passing our ext-struct size keeps the engine from reading
|
|
660
|
+
# past this binding's allocation (the MSVC segfault).
|
|
661
|
+
attach_function :leptris_document_serialize_ext_sized,
|
|
662
|
+
[:leptris_document, :pointer, :pointer, :size_t], :pointer
|
|
649
663
|
attach_function :leptris_document_serialize_into,
|
|
650
664
|
[:leptris_document, :pointer, :size_t, :pointer, :pointer], :size_t
|
|
651
665
|
attach_function :leptris_document_get_dtd,
|
data/lib/leptris/xml/node.rb
CHANGED
|
@@ -273,6 +273,31 @@ class Leptris::XML::Node
|
|
|
273
273
|
end
|
|
274
274
|
alias_method :remove, :unlink
|
|
275
275
|
|
|
276
|
+
# Visits the subtree with ONE C call (leptris_node_visit,
|
|
277
|
+
# libleptris 1.9.20 — upstream #645a): elements yield twice —
|
|
278
|
+
# (node, true, depth) before their children, (node, false, depth)
|
|
279
|
+
# after the subtree completes — every other kind once with
|
|
280
|
+
# entering=true; depth counts element levels from the receiver.
|
|
281
|
+
# No NodeSet, pointer array, or children memo per level: the
|
|
282
|
+
# leanest full-subtree iteration the binding offers (a document
|
|
283
|
+
# receiver walks the document child chain). The walk is read-only
|
|
284
|
+
# — mutate only between visits.
|
|
285
|
+
#
|
|
286
|
+
# root.visit { |node, entering, depth| ... }
|
|
287
|
+
def visit(&block)
|
|
288
|
+
return enum_for(:visit) unless block
|
|
289
|
+
ensure_alive!
|
|
290
|
+
document = @document
|
|
291
|
+
visitor = ::FFI::Function.new(
|
|
292
|
+
:void, [:pointer, :pointer, :int, :int], blocking: true) do |_, node_ptr, entering, depth|
|
|
293
|
+
block.call(
|
|
294
|
+
Leptris::XML::Node.wrap(node_ptr, document),
|
|
295
|
+
entering == 1, depth)
|
|
296
|
+
end
|
|
297
|
+
Leptris::XML::FFI.leptris_node_visit(@c_ptr, visitor, nil)
|
|
298
|
+
self
|
|
299
|
+
end
|
|
300
|
+
|
|
276
301
|
# Walks the subtree in post-order DFS (matches Nokogiri's
|
|
277
302
|
# semantics): the receiver, its descendants, nothing else.
|
|
278
303
|
#
|
|
@@ -47,8 +47,28 @@ module Leptris::XML::Serialization
|
|
|
47
47
|
def self.to_xml_display(c_ptr, indent: 0, no_decl: false, encoding: nil)
|
|
48
48
|
opts, encoding_anchor = build_options(
|
|
49
49
|
indent: indent, no_decl: no_decl, encoding: encoding)
|
|
50
|
-
str_ptr = Leptris::XML::FFI.
|
|
51
|
-
c_ptr, opts.pointer, INDENT_TEXT_EXT.pointer)
|
|
50
|
+
str_ptr = Leptris::XML::FFI.leptris_document_serialize_ext_sized(
|
|
51
|
+
c_ptr, opts.pointer, INDENT_TEXT_EXT.pointer, INDENT_TEXT_EXT.size)
|
|
52
|
+
Leptris::XML::FFI.read_owned_string(str_ptr)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Indent-unit serialization (libleptris 1.9.22, #633 —
|
|
56
|
+
# leptris-ruby#109): Nokogiri's indent_text semantics — the unit
|
|
57
|
+
# string replaces the default spaces, repeated `indent` times per
|
|
58
|
+
# depth level, standard layout otherwise. The engine emits ONE
|
|
59
|
+
# copy of the unit string per level (options->indent is ignored
|
|
60
|
+
# when a unit is set), so the binding multiplies unit x indent to
|
|
61
|
+
# reach Nokogiri's repeat count.
|
|
62
|
+
def self.to_xml_indent_unit(c_ptr, unit, indent: 0, no_decl: false,
|
|
63
|
+
encoding: nil)
|
|
64
|
+
opts, encoding_anchor = build_options(
|
|
65
|
+
indent: indent, no_decl: no_decl, encoding: encoding)
|
|
66
|
+
ext = Leptris::XML::FFI::SerializeExtStruct.new
|
|
67
|
+
unit_anchor = ::FFI::MemoryPointer.from_string(
|
|
68
|
+
indent.positive? ? unit.to_s * indent : unit.to_s)
|
|
69
|
+
ext[:indent_unit] = unit_anchor
|
|
70
|
+
str_ptr = Leptris::XML::FFI.leptris_document_serialize_ext_sized(
|
|
71
|
+
c_ptr, opts.pointer, ext.pointer, ext.size)
|
|
52
72
|
Leptris::XML::FFI.read_owned_string(str_ptr)
|
|
53
73
|
end
|
|
54
74
|
|