leptris 1.9.279.0 → 1.9.280.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b7c4cf503f75b80576e381d33d7cb3d12d045ef4ce098c28d3ddbad7c481dbaa
4
- data.tar.gz: 2edc03a1a2e317da1a0b5b34a3dc30dcc22e6672f9f15096d1ecfdb0821f4238
3
+ metadata.gz: f047f95472eb2eb6a147568db650edcbdcbe77e8411004258ea6ea6df30d52c7
4
+ data.tar.gz: e634e41351c2f5889c70fc378c839342e91737b844ef91bd359e920205a4b5d4
5
5
  SHA512:
6
- metadata.gz: f8f93e4c56b05d03bd94b7c7015da339be88f906642a556f01945cbc9d880cce07d00d92db6f68097c57c190f426cf09179a82d3d25043d637ac83791b71cc48
7
- data.tar.gz: 71cc690611970800fce91064ab05769d69c1d73ff4d11aa0897273ba89be2777b50f44e303523fe049090e4a0fda29f47c070e5053fb9fae95b04941dcf43481
6
+ metadata.gz: b31e125da3457aedab626e6cc7762b2a04c25d68e5f3d8fa63250a7ba979e786686e810525cd39146aaf0a032b8638e42582619e4d5ffd0e1ad6481f9ca0b389
7
+ data.tar.gz: 1cf1e08be3e722f0d29fa4f278dc3513f9b11bf9c43e59c6d2bce5f33ee8dcd853b9e91cb2a92af7103f495884bc9dd6bd8d7bb174ae61812eb4233c67e4f13e
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.279"
11
+ LIBLEPTRIS_VERSION = "1.9.280"
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Leptris
4
- VERSION = "1.9.279.0"
4
+ VERSION = "1.9.280.0"
5
5
  end
data/vendor-src/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  Sources vendored in this gem (recompile rights; the ruby
2
2
  variant builds them at install via extconf.rb):
3
3
 
4
- - libleptris v1.9.279
4
+ - libleptris v1.9.280
5
5
  - utf8proc v2.11.0
6
6
 
7
7
  Rebuild by hand:
@@ -1,5 +1,19 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [1.9.280] - 2026-09-30
4
+
5
+ ### Fixed
6
+
7
+ - the rootmap generation bump links on MSVC x86 — CAS loop over cmpxchg8b (_InterlockedIncrement64 is x64/ARM-only) (dom)
8
+ - regression pins for the two XSLT document-face shapes the 1.9.274 binding ride caught
9
+ (leptris#1448): an `<html>` root must trip the streaming bail and return the restarted
10
+ result-tree document (root present, content intact), and a value-of-only sheet must
11
+ produce the same rootless shape as the result-tree path for the same transform
12
+ (verified byte-identical via an `xsl:output encoding` twin). No behavior change —
13
+ coverage armor so the document face cannot regress silently again (leptris#1457).
14
+
15
+
16
+
3
17
  ## [1.9.279] - 2026-09-30
4
18
 
5
19
  ### Fixed
@@ -3,7 +3,7 @@
3
3
  cmake_minimum_required(VERSION 3.20)
4
4
 
5
5
  project(leptris
6
- VERSION 1.9.279
6
+ VERSION 1.9.280
7
7
  DESCRIPTION "Fast XML parser and XPath evaluator in pure C"
8
8
  LANGUAGES C CXX
9
9
  )
@@ -157,10 +157,27 @@ static LEPTRIS_THREAD_LOCAL uint64_t g_memo_generation;
157
157
  static uint64_t rootmap_generation_load(void) {
158
158
  return _InterlockedCompareExchange64(&g_rootmap_generation, 0, 0);
159
159
  }
160
+ #if defined(_M_X64) || defined(_M_ARM) || defined(_M_ARM64)
160
161
  static uint64_t rootmap_generation_bump(void) {
161
162
  return _InterlockedIncrement64(&g_rootmap_generation) - 1;
162
163
  }
163
164
  #else
165
+ /* _InterlockedIncrement64 has no x86 intrinsic (the symbol does not
166
+ * resolve under MSVC targeting Win32 — LNK2001); cmpxchg8b covers the
167
+ * 64-bit add there. GCC/Clang i686 never reaches this branch. */
168
+ static uint64_t rootmap_generation_bump(void) {
169
+ uint64_t cur = _InterlockedCompareExchange64(&g_rootmap_generation, 0, 0);
170
+ for (;;) {
171
+ uint64_t want = cur + 1;
172
+ uint64_t prev = _InterlockedCompareExchange64(
173
+ &g_rootmap_generation, want, cur);
174
+ if (prev == cur)
175
+ return want;
176
+ cur = prev;
177
+ }
178
+ }
179
+ #endif
180
+ #else
164
181
  static uint64_t rootmap_generation_load(void) {
165
182
  return __atomic_load_n(&g_rootmap_generation, __ATOMIC_ACQUIRE);
166
183
  }
@@ -4304,3 +4304,46 @@ TEST(XsltStreamApplyDoc, DocumentFaceMaterializesStreamedOutput) {
4304
4304
  EXPECT_NE(r.find("summary"), std::string::npos);
4305
4305
  EXPECT_NE(r.find("hello"), std::string::npos);
4306
4306
  }
4307
+
4308
+ /* #1448 regression pins — the shapes the binding ride caught on
4309
+ * 1.9.274 were all on THIS face (leptris_xslt_apply), which the
4310
+ * engine suite had zero specs for. The streaming engine's result
4311
+ * tree is intentionally empty; every consumer of the document face
4312
+ * depends on the materialization + bail-restart behaving. */
4313
+
4314
+ /* Dynamic html method: a fragment-level <html> root trips
4315
+ * stream_bail_html and restarts the transform on the result-tree
4316
+ * path — the doc face must return the RESTARTED tree (root
4317
+ * present, html-method close semantics), not a streamed `<html/>`
4318
+ * and not an empty document. */
4319
+ TEST(XsltStreamApplyDoc, HtmlRootBailsToTreePath) {
4320
+ std::string r = run_apply_doc(
4321
+ "<xsl:template match='/'><html><body><p>x</p></body>"
4322
+ "</html></xsl:template>",
4323
+ "<doc/>");
4324
+ EXPECT_EQ(r.find("(no-root)"), std::string::npos)
4325
+ << "bail-restart lost the root: " << r;
4326
+ EXPECT_NE(r.find("html"), std::string::npos) << r;
4327
+ EXPECT_NE(r.find("<p>x</p>"), std::string::npos) << r;
4328
+ }
4329
+
4330
+ /* Value-of-only sheet: NO element is ever produced, so a rootless
4331
+ * document is the CORRECT shape — and it must be IDENTICAL to the
4332
+ * result-tree path's shape for the same transform (twin: an
4333
+ * xsl:output encoding declaration disqualifies streaming, forcing
4334
+ * the tree path through the #1443 gate). Any divergence between
4335
+ * the two paths for the same sheet is a materialization bug. */
4336
+ TEST(XsltStreamApplyDoc, ValueOfOnlySheetMatchesTreePathTwin) {
4337
+ std::string streamed = run_apply_doc(
4338
+ "<xsl:template match='/'><xsl:value-of select='//t'/></xsl:template>",
4339
+ "<doc><t>plain</t></doc>");
4340
+ std::string tree = run_apply_doc(
4341
+ "<xsl:output encoding='iso-8859-1'/>"
4342
+ "<xsl:template match='/'><xsl:value-of select='//t'/></xsl:template>",
4343
+ "<doc><t>plain</t></doc>");
4344
+ EXPECT_NE(streamed.find("(no-root)"), std::string::npos)
4345
+ << "value-of-only sheet grew a synthetic root: " << streamed;
4346
+ EXPECT_EQ(streamed, tree)
4347
+ << "stream and tree paths diverged for the same sheet: "
4348
+ << "streamed=[" << streamed << "] tree=[" << tree << "]";
4349
+ }
@@ -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.279",
4
+ "version": "1.9.280",
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,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: leptris
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.279.0
4
+ version: 1.9.280.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.