leptris 1.9.40-aarch64-linux → 1.9.42-aarch64-linux

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1753f68ffbc65299a2742ad1645a74e8feb3c054cf25a44ab01b8571aaa78e1f
4
- data.tar.gz: 9a4076ab46da988a84261485317b153f33220878851bc95e586aaebc9df2a524
3
+ metadata.gz: 7b71e69e85187739869f3d897256675673d450e21534061329aa6f1ccb86005d
4
+ data.tar.gz: 2511132c3fb1bb8640b4419f528f83769aaced64e37ed3f7ff7a4892716476de
5
5
  SHA512:
6
- metadata.gz: 3ff2d04232695b730e659859a68d974c9d4f52fc87e7b41b0ba2290d8e0e99a04d62933cacd060b53c086f38497ed2224680e5cd224751fdef48d3ef9f90d0b6
7
- data.tar.gz: 53112f18a2ba2ce418433d4bdb18bb435f60a701be8d02d44736e0da9ef956aa2965c594a533bec5f72bbd09fef4dc393722afa4454067c5b97829716ae01066
6
+ metadata.gz: a74c1bd76a6697f6e3a65084b7a94120f7dff07460065e80c26540b03e06133df3b78d399325a939a1b80bcfdd4cb3bf4b4b26ff642ee45586bca2bdd88a79bb
7
+ data.tar.gz: 23d7e78e096d3c68b5e3c7c726faaf14d817f8b3f5eb81c56ee3094d962e463d719cb54847b38e24bdf8c4155b030ca29beeb2c48abafed3b894abc200c83bc0
data/CHANGELOG.md CHANGED
@@ -5,6 +5,37 @@ 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.42] - 2026-08-30
9
+
10
+ ### Fixed
11
+
12
+ - **Pull batch staging corruption: fail loudly, never deliver
13
+ garbage (leptris/leptris#646)**: `leptris_pull_next_batch`'s
14
+ staging arena misplaces record strings once staged content
15
+ crosses its block boundary (~185 bytes of attribute value under
16
+ nested attr-carrying ancestors — the #625 fix family did not
17
+ reach the batch staging). `Parser#each_batch` now validates each
18
+ staged record — unknown type codes, empty/control-byte/invalid-
19
+ encoding names cannot be legal XML events — and raises a
20
+ descriptive error pointing at `#each` (the cursor path reads the
21
+ same documents correctly; SAX default, recorder drain, and DOM
22
+ are unaffected). Bisection attached upstream: ok at 180 staged
23
+ bytes, corrupt at 190, in the minimized shape.
24
+
25
+ ## [1.9.41] - 2026-08-30
26
+
27
+ ### Changed
28
+
29
+ - **One thread-local access per children batch**: fetch_children
30
+ re-looked up the scratch hash inside the ints helper on every
31
+ call; both buffers now resolve through a single access (and the
32
+ kinds buffer sizes from the pointers capacity directly). Cold
33
+ full-tree walk: 254 -> 247 ms per big.xml walk (the gap vs
34
+ Nokogiri narrows 1.66x -> 1.56x — the remainder is the binding's
35
+ per-node allocation floor, re-measured and filed upstream as
36
+ leptris/leptris#645 together with the unchanged 1.64x scalar
37
+ XPath gap from #617's other half).
38
+
8
39
  ## [1.9.40] - 2026-08-30
9
40
 
10
41
  ### Changed
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Leptris
4
- VERSION = "1.9.40"
4
+ VERSION = "1.9.42"
5
5
  end
@@ -911,17 +911,22 @@ module Leptris
911
911
  # (leptris_node_children_ex, 1.9.18 #617) so wrappers skip
912
912
  # the per-child get_type dispatch.
913
913
  def self.fetch_children(c_ptr)
914
+ # One thread-local access serves both buffers (the helper
915
+ # re-looked it up); the kinds buffer sizes from the POINTERS
916
+ # buffer's capacity — it may have grown past FETCH_INITIAL on
917
+ # earlier use, and C writes one kind per copied child.
914
918
  scratch = (Thread.current[:leptris_scratch] ||= {})
915
919
  buffer = scratch[:pointers]
916
920
  if buffer.nil?
917
921
  buffer = scratch[:pointers] =
918
922
  ::FFI::MemoryPointer.new(:pointer, FETCH_INITIAL)
919
923
  end
920
- # size the kinds buffer from the POINTERS buffer's capacity —
921
- # it may have grown past FETCH_INITIAL on earlier use, and C
922
- # writes one kind per copied child
923
924
  cap = buffer.size / PTR_BYTES
924
- kinds = scratch_ints(cap)
925
+ kinds = scratch[:ints]
926
+ if kinds.nil? || kinds.size / INT_BYTES < cap
927
+ kinds&.free
928
+ kinds = scratch[:ints] = ::FFI::MemoryPointer.new(:int, cap)
929
+ end
925
930
  copied = leptris_node_children_ex(c_ptr, buffer, kinds, cap)
926
931
  if copied == cap
927
932
  total = leptris_node_children_ex(c_ptr, nil, nil, 0)
@@ -929,7 +934,9 @@ module Leptris
929
934
  buffer.free
930
935
  buffer = scratch[:pointers] =
931
936
  ::FFI::MemoryPointer.new(:pointer, total)
932
- kinds = scratch_ints(total)
937
+ kinds.free
938
+ kinds = scratch[:ints] =
939
+ ::FFI::MemoryPointer.new(:int, total)
933
940
  copied = leptris_node_children_ex(c_ptr, buffer, kinds, total)
934
941
  end
935
942
  end
@@ -85,14 +85,28 @@ module Leptris::XML::Pull
85
85
  name_ptr = buffer.get_pointer(base + name_off)
86
86
  text_ptr = buffer.get_pointer(base + text_off)
87
87
  type = TYPES[buffer.get_int(base + type_off)]
88
+ name = name_ptr.null? ? nil :
89
+ name_ptr.read_string.force_encoding(Encoding::UTF_8)
90
+ # Staging-corruption guard (leptris/leptris#646): the C
91
+ # batch's staging arena misplaces record strings once the
92
+ # staged content crosses its block boundary (~185 bytes of
93
+ # attribute value under nested attr-carrying ancestors) —
94
+ # names come back empty, control-byte-laced, or
95
+ # invalid-encoding, and unknown type codes surface as nil.
96
+ # Element names can never look like that: fail loudly
97
+ # instead of delivering garbage, and point at the cursor
98
+ # path, which reads the same documents correctly.
99
+ if type.nil? ||
100
+ (name && (name.empty? || !name.valid_encoding? ||
101
+ name.match?(/[\x00-\x08\x0e-\x1f]/)))
102
+ raise Leptris::XML::Error,
103
+ "pull batch staging corruption (leptris/leptris#646) — " \
104
+ "use Parser#each (cursor) for this document"
105
+ end
88
106
  text = text_ptr.null? ? nil :
89
107
  text_ptr.read_string.force_encoding(Encoding::UTF_8)
90
108
  text = Leptris::XML::FFI.read_pi_data(text) if type == :pi
91
- Event.new(type,
92
- name_ptr.null? ? nil :
93
- name_ptr.read_string.force_encoding(Encoding::UTF_8),
94
- text, nil
95
- )
109
+ Event.new(type, name, text, nil)
96
110
  end
97
111
  # The attr mirror holds the batch's most recent start.
98
112
  last_start = nil
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: leptris
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.40
4
+ version: 1.9.42
5
5
  platform: aarch64-linux
6
6
  authors:
7
7
  - Ribose Inc.