leptris 1.9.30 → 1.9.31
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 +16 -0
- data/lib/leptris/version.rb +1 -1
- data/lib/leptris/xml/document.rb +2 -1
- data/lib/leptris/xml/ffi.rb +10 -0
- data/lib/leptris/xml/processing_instruction.rb +2 -1
- data/lib/leptris/xml/pull.rb +10 -7
- data/lib/leptris/xml/sax/parser.rb +2 -1
- data/lib/leptris/xml/sax/recorder.rb +3 -1
- 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: 61af1b12021e7a1cf22f04004ea36d27df6f740ff135d039854c51497abf87f3
|
|
4
|
+
data.tar.gz: 0a842331a02a988b8bfce2920f8878b87c5ff5fdbd4c471f2f04694f4a1b3465
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e832da72a4e2fe0ddede057023c1e981705a41f196d85e7d7e5d61051d524bddfc2305065fef940ef60af48b87e978bc46be7e61030d598de83fb916db8bba3e
|
|
7
|
+
data.tar.gz: 7a266c15d5983229591bf414ad0dde95cc93018ba01388bf721f98977c026c164797e1dc805fc9a46625a6b2037c7709a65cb0e0640ca5ed6c46f40614dd37c0
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,22 @@ 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.31] - 2026-08-28
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **PI data consumes the leading whitespace run (leptris-ruby#85,
|
|
13
|
+
libxml2 parity)**: the engine retains the full whitespace run
|
|
14
|
+
after the PI target as data where libxml2 consumes it at parse
|
|
15
|
+
time — every Ruby-facing PI-data read now normalizes through one
|
|
16
|
+
seam helper (`FFI.read_pi_data`): `PI#content`,
|
|
17
|
+
`Document#processing_instructions` pairs, the SAX
|
|
18
|
+
`processing_instruction` callback, pull `:pi` events, and
|
|
19
|
+
recorder `:pi` events. Whitespace-only data reads as `""`, so
|
|
20
|
+
"pi-without-data" PIs report empty consistently; trailing
|
|
21
|
+
whitespace is kept (libxml2 trims only the leading run).
|
|
22
|
+
Read-time only — `PI#data=` still stores verbatim.
|
|
23
|
+
|
|
8
24
|
## [1.9.30] - 2026-08-28
|
|
9
25
|
|
|
10
26
|
### Fixed
|
data/lib/leptris/version.rb
CHANGED
data/lib/leptris/xml/document.rb
CHANGED
|
@@ -295,7 +295,8 @@ class Leptris::XML::Document
|
|
|
295
295
|
count = Leptris::XML::FFI.leptris_document_pi_count(@c_ptr)
|
|
296
296
|
result = count.times.map do |i|
|
|
297
297
|
[Leptris::XML::FFI.leptris_document_pi_target(@c_ptr, i),
|
|
298
|
-
Leptris::XML::FFI.
|
|
298
|
+
Leptris::XML::FFI.read_pi_data(
|
|
299
|
+
Leptris::XML::FFI.leptris_document_pi_data(@c_ptr, i)).to_s]
|
|
299
300
|
end
|
|
300
301
|
@processing_instructions = result
|
|
301
302
|
@pi_version = @version
|
data/lib/leptris/xml/ffi.rb
CHANGED
|
@@ -924,6 +924,16 @@ module Leptris
|
|
|
924
924
|
[raw, status.read_int]
|
|
925
925
|
end
|
|
926
926
|
|
|
927
|
+
# libxml2 consumes the whole whitespace run following the PI
|
|
928
|
+
# target when parsing; the engine retains it as data
|
|
929
|
+
# (leptris-ruby#85). Every Ruby-facing PI-data read normalizes
|
|
930
|
+
# here — whitespace-only data becomes "" so
|
|
931
|
+
# "pi-without-data" PIs report empty consistently. Read-time
|
|
932
|
+
# only: PI#data= stores verbatim.
|
|
933
|
+
def self.read_pi_data(data)
|
|
934
|
+
data&.sub(/\A[ \t\r\n]+/, "")
|
|
935
|
+
end
|
|
936
|
+
|
|
927
937
|
# Thread-local scratch buffers for batch handle fetches (round
|
|
928
938
|
# XX): the per-call MemoryPointer new/free was pure cold-path
|
|
929
939
|
# overhead — two allocations and a GC visit per children() /
|
|
@@ -16,7 +16,8 @@ class Leptris::XML::ProcessingInstruction < Leptris::XML::Node
|
|
|
16
16
|
def content
|
|
17
17
|
return @content if memo_hit?(@content_version)
|
|
18
18
|
ensure_alive!
|
|
19
|
-
result = Leptris::XML::FFI.
|
|
19
|
+
result = Leptris::XML::FFI.read_pi_data(
|
|
20
|
+
Leptris::XML::FFI.leptris_pi_node_get_data(@c_ptr)).to_s
|
|
20
21
|
if @document
|
|
21
22
|
@content = result
|
|
22
23
|
@content_version = @document.version
|
data/lib/leptris/xml/pull.rb
CHANGED
|
@@ -84,13 +84,14 @@ module Leptris::XML::Pull
|
|
|
84
84
|
base = i * stride
|
|
85
85
|
name_ptr = buffer.get_pointer(base + name_off)
|
|
86
86
|
text_ptr = buffer.get_pointer(base + text_off)
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
type = TYPES[buffer.get_int(base + type_off)]
|
|
88
|
+
text = text_ptr.null? ? nil :
|
|
89
|
+
text_ptr.read_string.force_encoding(Encoding::UTF_8)
|
|
90
|
+
text = Leptris::XML::FFI.read_pi_data(text) if type == :pi
|
|
91
|
+
Event.new(type,
|
|
89
92
|
name_ptr.null? ? nil :
|
|
90
93
|
name_ptr.read_string.force_encoding(Encoding::UTF_8),
|
|
91
|
-
|
|
92
|
-
text_ptr.read_string.force_encoding(Encoding::UTF_8),
|
|
93
|
-
nil
|
|
94
|
+
text, nil
|
|
94
95
|
)
|
|
95
96
|
end
|
|
96
97
|
# The attr mirror holds the batch's most recent start.
|
|
@@ -125,11 +126,13 @@ module Leptris::XML::Pull
|
|
|
125
126
|
name_ptr = raw.get_pointer(NAME_OFFSET)
|
|
126
127
|
text_ptr = raw.get_pointer(TEXT_OFFSET)
|
|
127
128
|
attrs = type == :start_element ? capture_attrs : nil
|
|
129
|
+
text = text_ptr.null? ? nil :
|
|
130
|
+
text_ptr.read_string.force_encoding(Encoding::UTF_8)
|
|
131
|
+
text = Leptris::XML::FFI.read_pi_data(text) if type == :pi
|
|
128
132
|
Event.new(
|
|
129
133
|
type,
|
|
130
134
|
name_ptr.null? ? nil : name_ptr.read_string.force_encoding(Encoding::UTF_8),
|
|
131
|
-
|
|
132
|
-
attrs
|
|
135
|
+
text, attrs
|
|
133
136
|
)
|
|
134
137
|
end
|
|
135
138
|
|
|
@@ -149,7 +149,8 @@ class Leptris::XML::SAX::Parser
|
|
|
149
149
|
|
|
150
150
|
if overridden?(:processing_instruction)
|
|
151
151
|
s[:processing_instruction] = callback(:void, [:pointer, :string, :string]) do |_, target, data|
|
|
152
|
-
handler.processing_instruction(
|
|
152
|
+
handler.processing_instruction(
|
|
153
|
+
utf8(target), Leptris::XML::FFI.read_pi_data(utf8(data)))
|
|
153
154
|
end
|
|
154
155
|
end
|
|
155
156
|
|
|
@@ -122,9 +122,11 @@ class Leptris::XML::SAX::Recorder
|
|
|
122
122
|
kind = KIND_BY_CODE[fields[i * 9]]
|
|
123
123
|
if kind && (wanted.nil? || wanted[kind])
|
|
124
124
|
base = i * 9 + 1
|
|
125
|
+
text = slice(arena, fields[base + 2], fields[base + 3])
|
|
126
|
+
text = Leptris::XML::FFI.read_pi_data(text) if kind == :pi
|
|
125
127
|
yield kind,
|
|
126
128
|
slice(arena, fields[base], fields[base + 1]),
|
|
127
|
-
|
|
129
|
+
text,
|
|
128
130
|
attrs_from(arena, fields[base + 4], fields[base + 5]),
|
|
129
131
|
fields[base + 6], fields[base + 7]
|
|
130
132
|
end
|