leptris 1.9.312.1 → 1.9.313.0
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 +14 -0
- data/Rakefile +1 -1
- data/lib/leptris/vendor/aarch64-linux/libleptris.so +0 -0
- data/lib/leptris/vendor/aarch64-linux-musl/libleptris.so +0 -0
- data/lib/leptris/vendor/arm-linux/libleptris.so +0 -0
- data/lib/leptris/vendor/arm-linux-musl/libleptris.so +0 -0
- data/lib/leptris/vendor/arm64-darwin/libleptris.dylib +0 -0
- data/lib/leptris/vendor/ppc64le-linux/libleptris.so +0 -0
- data/lib/leptris/vendor/s390x-linux-musl/libleptris.so +0 -0
- data/lib/leptris/vendor/x86_64-darwin/libleptris.dylib +0 -0
- data/lib/leptris/vendor/x86_64-linux/libleptris.so +0 -0
- data/lib/leptris/vendor/x86_64-linux-musl/libleptris.so +0 -0
- data/lib/leptris/version.rb +1 -1
- data/vendor-src/README.md +1 -1
- data/vendor-src/libleptris/CHANGELOG.md +22 -0
- data/vendor-src/libleptris/CMakeLists.txt +1 -1
- data/vendor-src/libleptris/src/leptris/leptris.c +23 -9
- data/vendor-src/libleptris/src/leptris/leptris_internal.h +5 -0
- data/vendor-src/libleptris/test/abi/test_dom_mutation_bugs.cpp +26 -0
- data/vendor-src/libleptris/vcpkg.json +1 -1
- 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: 716410c15581403307f3b94bd529c21d2bc778478bcfca064b6778f8e1826a9b
|
|
4
|
+
data.tar.gz: c566d9e1828cd1803523b0eb99ffc9b861995aee576ef7fae6d24ac536bea7d0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 66c08d6699d345e0a74c313c9d02bef8b84a6f25e0b310e846a5694dd01e78c45c983f1871bba57e4711564208d90e6710d08d2a499d88582c1ec4cf3ab3f211
|
|
7
|
+
data.tar.gz: ecda89d28b0ad3e7954a93064c6abeaf430159bad758c0dcf88db4c4ad20fe7e6b56a17201142ead36aac05c64a025c759dfff7736e36969dc2635265f302083
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## [1.9.313.0] - 2026-10-07
|
|
2
|
+
|
|
3
|
+
### Fixed — engine sync (libleptris 1.9.313)
|
|
4
|
+
|
|
5
|
+
- **Absorption-aware release at the C ABI (#1557, engine #1566)**:
|
|
6
|
+
the follow-up to the #386 mitigation — `leptris_document_free`
|
|
7
|
+
now consults the absorption state itself. The anchor dying while
|
|
8
|
+
`absorbed_handle > 0` detaches the source and defers its release
|
|
9
|
+
to the outstanding holder's free (`absorbed_deferred`); handles
|
|
10
|
+
released before the anchor keep the #1548 handle-only no-op. C
|
|
11
|
+
consumers no longer need to mirror the absorbed flag at their own
|
|
12
|
+
release sites; the binding's 1.9.311.2 mitigation stays as
|
|
13
|
+
defense-in-depth. Both release orderings spec-pinned.
|
|
14
|
+
|
|
1
15
|
## [1.9.312.1] - 2026-10-07
|
|
2
16
|
|
|
3
17
|
### Added
|
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.313"
|
|
12
12
|
# Vendored alongside libleptris for fn:normalize-unicode (TODO
|
|
13
13
|
# .restructure/20): built per platform with a RELOCATABLE @rpath
|
|
14
14
|
# install name, loaded by ffi.rb before libleptris so the
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/lib/leptris/version.rb
CHANGED
data/vendor-src/README.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [1.9.313] - 2026-10-07
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- **Absorbed sources defer their release to outstanding handles
|
|
8
|
+
(#1557, PR #1566).** Follow-up to #1548's
|
|
9
|
+
`leptris_document_absorb`: the absorber's free cleared the
|
|
10
|
+
absorbed state before recursing, so a source handle that
|
|
11
|
+
OUTLIVED the absorber read the cleared flag and re-released the
|
|
12
|
+
already-destroyed pool — heap corruption (glibc abort /
|
|
13
|
+
`malloc_zone_error`), deterministic under exit-time finalizers
|
|
14
|
+
(leptris-ruby#386, 50-iteration repro). When the anchor dies
|
|
15
|
+
while `absorbed_handle > 0` it now detaches the source and marks
|
|
16
|
+
`absorbed_deferred`: the holder's `leptris_document_free`
|
|
17
|
+
performs the FULL release; handles released before the anchor
|
|
18
|
+
keep the #1548 handle-only no-op. Consumers no longer need to
|
|
19
|
+
mirror the absorbed flag at their own release sites. Gates: the
|
|
20
|
+
repro red under ASAN at leptris.c:937, green after; mutation
|
|
21
|
+
suite 27/27 ASAN + Release; full ctest 1866/1866; leaks 0.
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
3
25
|
## [1.9.312] - 2026-10-06
|
|
4
26
|
|
|
5
27
|
### Added
|
|
@@ -933,9 +933,11 @@ LEPTRIS_API void leptris_document_free(struct leptris_document* doc) {
|
|
|
933
933
|
|
|
934
934
|
/* #1548: an absorbed document's MEMORY belongs to its absorber
|
|
935
935
|
* (it rides the absorber's child_docs chain). A caller free
|
|
936
|
-
* releases only the outstanding handle.
|
|
937
|
-
|
|
938
|
-
|
|
936
|
+
* releases only the outstanding handle. #1557: unless the
|
|
937
|
+
* anchor died first and DEFERRED the release to this holder —
|
|
938
|
+
* then this free is the real one. */
|
|
939
|
+
if (doc->absorbed_by && !doc->absorbed_deferred) {
|
|
940
|
+
if (doc->absorbed_handle > 0) doc->absorbed_handle--;
|
|
939
941
|
return;
|
|
940
942
|
}
|
|
941
943
|
|
|
@@ -1021,12 +1023,24 @@ LEPTRIS_API void leptris_document_free(struct leptris_document* doc) {
|
|
|
1021
1023
|
* doesn't try to walk the
|
|
1022
1024
|
* adopted subtree. */
|
|
1023
1025
|
ch->root = NULL;
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1026
|
+
if (ch->absorbed_by && ch->absorbed_handle > 0) {
|
|
1027
|
+
/* #1557: a caller still holds this absorbed handle.
|
|
1028
|
+
* Freeing here would strand it on freed memory (its
|
|
1029
|
+
* later free read the cleared flag and re-released
|
|
1030
|
+
* the pool — the leptris-ruby#386 double free).
|
|
1031
|
+
* DEFER: detach from our chain and hand the release
|
|
1032
|
+
* to the holder's leptris_document_free, which sees
|
|
1033
|
+
* absorbed_deferred and runs the full release. */
|
|
1034
|
+
ch->absorbed_deferred = 1;
|
|
1035
|
+
ch->next_adopted = NULL;
|
|
1036
|
+
} else {
|
|
1037
|
+
/* #1548: the anchor's free is the REAL one — clear
|
|
1038
|
+
* the absorbed state so the early handle-return
|
|
1039
|
+
* above does not swallow it. */
|
|
1040
|
+
ch->absorbed_by = NULL;
|
|
1041
|
+
ch->absorbed_handle = 0;
|
|
1042
|
+
leptris_document_free(ch);
|
|
1043
|
+
}
|
|
1030
1044
|
ch = next;
|
|
1031
1045
|
}
|
|
1032
1046
|
doc->child_docs = NULL;
|
|
@@ -195,6 +195,11 @@ struct leptris_document {
|
|
|
195
195
|
* (the anchor frees the memory later). */
|
|
196
196
|
struct leptris_document* absorbed_by;
|
|
197
197
|
int absorbed_handle;
|
|
198
|
+
/* #1557: the absorber died while this handle was outstanding —
|
|
199
|
+
* the anchor deferred the pool release to THIS holder's free,
|
|
200
|
+
* so leptris_document_free must run the full release (not the
|
|
201
|
+
* handle-only early return). */
|
|
202
|
+
int absorbed_deferred;
|
|
198
203
|
/* XML Declaration support */
|
|
199
204
|
char* xml_version; /* "1.0", "1.1", etc. or NULL if not present */
|
|
200
205
|
int standalone; /* -1=not set, 0=no, 1=yes */
|
|
@@ -670,6 +670,32 @@ TEST(CrossDocumentLeafAdoption, RootLevelLeafArgumentAdoptsByKind) {
|
|
|
670
670
|
}
|
|
671
671
|
}
|
|
672
672
|
|
|
673
|
+
// #1557: an absorbed source's handle may OUTLIVE the absorber. The
|
|
674
|
+
// anchor's free used to clear the absorbed state, so the holder's
|
|
675
|
+
// later free re-released the same pool — heap corruption. The anchor
|
|
676
|
+
// now defers the release to the outstanding handle.
|
|
677
|
+
TEST(AbsorbAdoption, SourceHandleMayOutliveAnchor) {
|
|
678
|
+
for (int i = 0; i < 50; i++) {
|
|
679
|
+
LeptrisDocument dest = Parse("<main><keep/></main>");
|
|
680
|
+
ASSERT_NE(dest, nullptr);
|
|
681
|
+
LeptrisDocument src = Parse("<scratch><a/></scratch>");
|
|
682
|
+
ASSERT_NE(src, nullptr);
|
|
683
|
+
ASSERT_EQ(leptris_document_absorb(dest, src), LEPTRIS_OK);
|
|
684
|
+
leptris_document_free(dest); /* anchor dies first */
|
|
685
|
+
leptris_document_free(src); /* holder releases after */
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
TEST(AbsorbAdoption, SourceHandleFreedBeforeAnchorStillNoOp) {
|
|
690
|
+
LeptrisDocument dest = Parse("<main><keep/></main>");
|
|
691
|
+
ASSERT_NE(dest, nullptr);
|
|
692
|
+
LeptrisDocument src = Parse("<scratch><a/></scratch>");
|
|
693
|
+
ASSERT_NE(src, nullptr);
|
|
694
|
+
ASSERT_EQ(leptris_document_absorb(dest, src), LEPTRIS_OK);
|
|
695
|
+
leptris_document_free(src); /* handle-only: memory stays with anchor */
|
|
696
|
+
leptris_document_free(dest); /* releases everything incl. the source */
|
|
697
|
+
}
|
|
698
|
+
|
|
673
699
|
TEST(AbsorbAdoption, SpliceAfterAbsorbIsZeroCopy) {
|
|
674
700
|
LeptrisDocument dst = Parse("<main><keep/></main>");
|
|
675
701
|
ASSERT_NE(dst, nullptr);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://raw.githubusercontent.com/microsoft/vcpkg/master/scripts/vcpkg.schema.json",
|
|
3
3
|
"name": "leptris",
|
|
4
|
-
"version": "1.9.
|
|
4
|
+
"version": "1.9.313",
|
|
5
5
|
"description": "High-performance XML parser and XPath 1.0 engine in C (libleptris)",
|
|
6
6
|
"homepage": "https://github.com/leptris/leptris",
|
|
7
7
|
"license": "MIT",
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: leptris
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.9.
|
|
4
|
+
version: 1.9.313.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-10-
|
|
11
|
+
date: 2026-10-07 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: ffi
|