leptris 1.9.292.0 → 1.9.304.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.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +44 -0
  3. data/Rakefile +1 -1
  4. data/lib/leptris/vendor/aarch64-linux/libleptris.so +0 -0
  5. data/lib/leptris/vendor/aarch64-linux-musl/libleptris.so +0 -0
  6. data/lib/leptris/vendor/arm-linux/libleptris.so +0 -0
  7. data/lib/leptris/vendor/arm-linux-musl/libleptris.so +0 -0
  8. data/lib/leptris/vendor/arm64-darwin/libleptris.dylib +0 -0
  9. data/lib/leptris/vendor/ppc64le-linux/libleptris.so +0 -0
  10. data/lib/leptris/vendor/s390x-linux-musl/libleptris.so +0 -0
  11. data/lib/leptris/vendor/x86_64-darwin/libleptris.dylib +0 -0
  12. data/lib/leptris/vendor/x86_64-linux/libleptris.so +0 -0
  13. data/lib/leptris/vendor/x86_64-linux-musl/libleptris.so +0 -0
  14. data/lib/leptris/version.rb +1 -1
  15. data/lib/leptris/xml/element.rb +112 -4
  16. data/vendor-src/README.md +1 -1
  17. data/vendor-src/libleptris/CHANGELOG.md +398 -0
  18. data/vendor-src/libleptris/CMakeLists.txt +6 -1
  19. data/vendor-src/libleptris/benchmarks/modification/bench_append_attr_pugixml.cpp +36 -0
  20. data/vendor-src/libleptris/bindings/rust/Cargo.lock +1 -1
  21. data/vendor-src/libleptris/bindings/rust/Cargo.toml +3 -1
  22. data/vendor-src/libleptris/cli/CLI_ARCHITECTURE.md +1 -1
  23. data/vendor-src/libleptris/cli/CMakeLists.txt +1 -0
  24. data/vendor-src/libleptris/cli/cli.c +36 -1
  25. data/vendor-src/libleptris/cli/cli.h +39 -2
  26. data/vendor-src/libleptris/cli/commands/xquery.c +1 -31
  27. data/vendor-src/libleptris/cli/commands/xslt.c +118 -0
  28. data/vendor-src/libleptris/cli/main.c +24 -22
  29. data/vendor-src/libleptris/cli/man/leptris-diff.1.adoc +40 -0
  30. data/vendor-src/libleptris/cli/man/leptris-validate.1.adoc +43 -0
  31. data/vendor-src/libleptris/cli/man/leptris-xquery.1.adoc +44 -0
  32. data/vendor-src/libleptris/cli/man/leptris-xslt.1.adoc +49 -0
  33. data/vendor-src/libleptris/src/CMakeLists.txt +26 -0
  34. data/vendor-src/libleptris/src/leptris/dom/compact.c +4 -0
  35. data/vendor-src/libleptris/src/leptris/dom/element_modify.c +83 -18
  36. data/vendor-src/libleptris/src/leptris/dom/mut_recycle.c +112 -0
  37. data/vendor-src/libleptris/src/leptris/dom/mut_recycle.h +50 -0
  38. data/vendor-src/libleptris/src/leptris/leptris.c +10 -4
  39. data/vendor-src/libleptris/src/leptris/leptris_internal.h +7 -0
  40. data/vendor-src/libleptris/src/leptris/xpath/collation.c +494 -0
  41. data/vendor-src/libleptris/src/leptris/xpath/collation.h +66 -0
  42. data/vendor-src/libleptris/src/leptris/xpath/ducet_table.h +21994 -0
  43. data/vendor-src/libleptris/src/leptris/xpath/evaluator_internal.h +6 -0
  44. data/vendor-src/libleptris/src/leptris/xpath/evaluator_operators.c +82 -5
  45. data/vendor-src/libleptris/src/leptris/xpath/evaluator_types.c +53 -8
  46. data/vendor-src/libleptris/src/leptris/xpath/functions.c +605 -68
  47. data/vendor-src/libleptris/src/leptris/xpath/functions_ext31.c +636 -65
  48. data/vendor-src/libleptris/src/leptris/xpath/vm.c +20 -4
  49. data/vendor-src/libleptris/src/leptris/xpath/xpath_public.c +3 -1
  50. data/vendor-src/libleptris/src/leptris/xquery/xquery.c +23 -1
  51. data/vendor-src/libleptris/test/CMakeLists.txt +14 -0
  52. data/vendor-src/libleptris/test/abi/test_dom_mutation_bugs.cpp +127 -0
  53. data/vendor-src/libleptris/test/cli/test_cli.cpp +61 -0
  54. data/vendor-src/libleptris/test/memory/test_mut_recycle.cpp +64 -0
  55. data/vendor-src/libleptris/test/xpath/test_collation.cpp +147 -0
  56. data/vendor-src/libleptris/test/xpath/test_xslt.cpp +114 -0
  57. data/vendor-src/libleptris/test/xquery/qt3/fn/abs.xml +2085 -0
  58. data/vendor-src/libleptris/test/xquery/qt3/fn/apply.xml +214 -0
  59. data/vendor-src/libleptris/test/xquery/qt3/fn/avg.xml +2199 -0
  60. data/vendor-src/libleptris/test/xquery/qt3/fn/ceiling.xml +961 -0
  61. data/vendor-src/libleptris/test/xquery/qt3/fn/collation-key.xml +331 -0
  62. data/vendor-src/libleptris/test/xquery/qt3/fn/filter.xml +387 -0
  63. data/vendor-src/libleptris/test/xquery/qt3/fn/floor.xml +968 -0
  64. data/vendor-src/libleptris/test/xquery/qt3/fn/fold-left.xml +426 -0
  65. data/vendor-src/libleptris/test/xquery/qt3/fn/fold-right.xml +363 -0
  66. data/vendor-src/libleptris/test/xquery/qt3/fn/for-each-pair.xml +585 -0
  67. data/vendor-src/libleptris/test/xquery/qt3/fn/for-each.xml +170 -0
  68. data/vendor-src/libleptris/test/xquery/qt3/fn/max.xml +2018 -0
  69. data/vendor-src/libleptris/test/xquery/qt3/fn/min.xml +1973 -0
  70. data/vendor-src/libleptris/test/xquery/qt3/fn/round-half-to-even.xml +1336 -0
  71. data/vendor-src/libleptris/test/xquery/qt3/fn/round.xml +2539 -0
  72. data/vendor-src/libleptris/test/xquery/qt3/fn/sum.xml +2043 -0
  73. data/vendor-src/libleptris/test/xquery/qt3/misc/UCACollation.xml +1120 -0
  74. data/vendor-src/libleptris/test/xquery/test_qt3.cpp +196 -14
  75. data/vendor-src/libleptris/test/xquery/test_xquery.cpp +293 -0
  76. data/vendor-src/libleptris/tools/gen_ducet_table.py +110 -0
  77. data/vendor-src/libleptris/vcpkg.json +1 -1
  78. data/vendor-src/libleptris/vendor/ducet/allkeys.txt +39435 -0
  79. metadata +33 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 687057b25a71a61ec33a2509b6f06ad70401f291ad2b4602237eaeb29a4da18c
4
- data.tar.gz: 4ed664823ef36d94d873746d28683373f0a85015ec03a4027d7d5a6e32bfd969
3
+ metadata.gz: 1b942f5f5ee3ff31761b8fe6c5ddaac9245da364e2d32431760d297dcac8fd26
4
+ data.tar.gz: e0a6184e06d4557b5a4d4752305625e329d06104814158cd7d300bf26c0400bd
5
5
  SHA512:
6
- metadata.gz: fb236b1f32ec4dd678671d5f3ab088470176c2295b1247d09fc36a944b759e48f18b203a656204794cfae08b9dc736148a788de9d87e19fb95ebfa29cfb010fb
7
- data.tar.gz: 53ed2a58285d1380832f442d505dae6c54eb0cf46c251af77c3a906282c348c7d1e74a1910dead2bcb0d20ef7cb41069f8dccc5e070f3fd998623c9559af4b4b
6
+ metadata.gz: 36d2a9d04968b587d6656452490ca1d53fbf3d83fc25779d688f069c25ec3de2512b82af1f14c70407ec50327a267560aae1d0992f62e9fcf89fe6c506c872fc
7
+ data.tar.gz: 573eb433de3d251fb0fa2227a4f921651a45e5bc4160674077f6fc499844566364e55f0f49e4b74740d8f7893e0f577ee33c1cb7a999333f9ef37c2ab6d03f42
data/CHANGELOG.md CHANGED
@@ -1,3 +1,47 @@
1
+ ## [1.9.304.0] - 2026-10-05
2
+
3
+ ### Fixed
4
+
5
+ - **Cross-document appends adopt by copy — the xpath.rb:39 crash
6
+ class (engine #1528, libleptris 1.9.304)**: the engine's four
7
+ splice seams (append/prepend/insert_before/insert_after) no
8
+ longer splice foreign-document pointers raw — a scratch-doc
9
+ node appended into a live tree then freed with its document
10
+ dangled every adopted node and detonated the next compiled-XPath
11
+ eval (the metanorma sectioned-cleanup crash). The binding now
12
+ completes the contract: cross-document appends return the
13
+ INSTALLED in-tree wrapper (add_child, append_children, children=,
14
+ prepend_child, add_previous_sibling, add_next_sibling, wrap),
15
+ the #178 namespace lift runs before the splice, and the source
16
+ original is removed after (the historical move semantics —
17
+ source loses the node). Same-document appends stay
18
+ pointer-identical on the native fast path. The wrap face moves
19
+ self into the INSTALLED wrapper. Adoption specs include the
20
+ scratch-free + compiled-XPath crash shape.
21
+
22
+ ## [1.9.302.0] - 2026-10-05
23
+
24
+ ### Engine sync (libleptris 1.9.293-1.9.302)
25
+
26
+ Ten upstream releases ride in this pin — internal fixes and
27
+ performance with NO binding-surface changes (zero header deltas
28
+ 292..302; the audit gate confirms 363/362 unchanged). Highlights:
29
+
30
+ - **XQuery correctness**: a false() bound anywhere read as truthy;
31
+ fn:not uses the effective boolean value; fn:abs(()) is empty;
32
+ string lt/gt are codepoint comparisons; fn:avg edge shapes;
33
+ aggregates atomize array arguments; `instance of xs:integer`
34
+ demands integrality; xs:byte/unsignedByte/unsignedInt
35
+ constructors; fn:sum#2's zero argument.
36
+ - **Collation**: UCA over the vendored DUCET table (slices 1-4) —
37
+ fn:normalize-unicode F&O conformance, collation-aware string
38
+ functions, 71+1078 QT3 cases adopted, implicit weights and
39
+ alternate=blanked.
40
+ - **Performance**: per-thread recycle of mutation blocks (DOM
41
+ create/build/free).
42
+ - **Rust bindings**: first tokenless crates.io release (leptris
43
+ v1.4.1) from CI.
44
+
1
45
  ## [1.9.292.0] - 2026-10-03
2
46
 
3
47
  ### 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.292"
11
+ LIBLEPTRIS_VERSION = "1.9.304"
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.292.0"
4
+ VERSION = "1.9.304.0"
5
5
  end
@@ -419,6 +419,21 @@ class Leptris::XML::Element < Leptris::XML::Node
419
419
  # C-bound insert (TODO.perf/14): gates + predicate + version
420
420
  # bump + engine insert in one dispatch; Qnil = the child needs
421
421
  # the namespace lift — the full path below handles it.
422
+ # Cross-document nodes skip the fast path entirely (1.9.304,
423
+ # #1528): the engine deep-copies them at the splice, so the
424
+ # full path's lift must run FIRST and the source original is
425
+ # removed after (move semantics).
426
+ if node.document && !node.document.equal?(@document)
427
+ ensure_writable!
428
+ unless Leptris::XML::Element.skip_adoption_lift?(node)
429
+ Leptris::XML::Element.lift_namespaces_for_adoption(node, namespaces)
430
+ end
431
+ Leptris::XML::FFI.check_status(
432
+ Leptris::XML::FFI.leptris_element_prepend_child(c_ptr, node.c_ptr))
433
+ Leptris::XML::Node.invalidate_cross_document!(node, @document)
434
+ node.parent&.remove_child(node)
435
+ return children.to_a.first
436
+ end
422
437
  if native_fast_children?
423
438
  unless Leptris::XML::Native.insert_binding_child(
424
439
  @document, @c_address, node.c_ptr.address, 1).nil?
@@ -440,6 +455,20 @@ class Leptris::XML::Element < Leptris::XML::Node
440
455
  # C-bound insert (TODO.perf/14): gates + predicate + version
441
456
  # bump + engine insert in one dispatch; Qnil = the child needs
442
457
  # the namespace lift — the full path below handles it.
458
+ # Cross-document: full path first (lift + engine copy), then
459
+ # the source original is removed; returns the installed copy
460
+ # (self's new next sibling).
461
+ if node.document && !node.document.equal?(@document)
462
+ ensure_writable!
463
+ unless Leptris::XML::Element.skip_adoption_lift?(node)
464
+ Leptris::XML::Element.lift_namespaces_for_adoption(node, namespaces)
465
+ end
466
+ Leptris::XML::FFI.check_status(
467
+ Leptris::XML::FFI.leptris_element_insert_after(c_ptr, node.c_ptr))
468
+ Leptris::XML::Node.invalidate_cross_document!(node, @document)
469
+ node.parent&.remove_child(node)
470
+ return self.next_sibling
471
+ end
443
472
  if native_fast_children?
444
473
  unless Leptris::XML::Native.insert_binding_child(
445
474
  @document, @c_address, node.c_ptr.address, 2).nil?
@@ -461,6 +490,20 @@ class Leptris::XML::Element < Leptris::XML::Node
461
490
  # C-bound insert (TODO.perf/14): gates + predicate + version
462
491
  # bump + engine insert in one dispatch; Qnil = the child needs
463
492
  # the namespace lift — the full path below handles it.
493
+ # Cross-document: full path first (lift + engine copy), then
494
+ # the source original is removed; returns the installed copy
495
+ # (self's new previous sibling).
496
+ if node.document && !node.document.equal?(@document)
497
+ ensure_writable!
498
+ unless Leptris::XML::Element.skip_adoption_lift?(node)
499
+ Leptris::XML::Element.lift_namespaces_for_adoption(node, namespaces)
500
+ end
501
+ Leptris::XML::FFI.check_status(
502
+ Leptris::XML::FFI.leptris_element_insert_before(c_ptr, node.c_ptr))
503
+ Leptris::XML::Node.invalidate_cross_document!(node, @document)
504
+ node.parent&.remove_child(node)
505
+ return self.previous_sibling
506
+ end
464
507
  if native_fast_children?
465
508
  unless Leptris::XML::Native.insert_binding_child(
466
509
  @document, @c_address, node.c_ptr.address, 3).nil?
@@ -508,6 +551,9 @@ class Leptris::XML::Element < Leptris::XML::Node
508
551
  nodes.each { |n| add_child(n) }
509
552
  return
510
553
  end
554
+ cross = nodes.any? do |n|
555
+ n.document && !n.document.equal?(@document)
556
+ end
511
557
  if native_fast_children?
512
558
  addrs = nodes.map { |n| n.c_ptr.address }
513
559
  done = Leptris::XML::Native.append_binding_children(
@@ -516,14 +562,25 @@ class Leptris::XML::Element < Leptris::XML::Node
516
562
  if done >= nodes.size
517
563
  nodes.each do |n|
518
564
  Leptris::XML::Node.invalidate_cross_document!(n, @document)
565
+ remove_from_source_original(n) if cross
519
566
  end
520
- return nodes
567
+ # 1.9.304 (#1528): foreign children were adopted by COPY —
568
+ # hand back the installed in-tree wrappers.
569
+ return cross ? children.to_a.last(nodes.size) : nodes
521
570
  end
522
571
  nodes[0, done].each do |n|
523
572
  Leptris::XML::Node.invalidate_cross_document!(n, @document)
573
+ remove_from_source_original(n) if cross
524
574
  end
525
575
  nodes = nodes[done..]
526
576
  end
577
+ if cross
578
+ nodes.each do |n|
579
+ append_installed(n)
580
+ remove_from_source_original(n)
581
+ end
582
+ return children.to_a.last(nodes.size)
583
+ end
527
584
  nodes.each { |n| add_child(n) }
528
585
  nodes
529
586
  end
@@ -565,9 +622,12 @@ class Leptris::XML::Element < Leptris::XML::Node
565
622
  # add_child moves self (unlinks from old parent first), so no explicit
566
623
  # remove_child needed — and trying to remove after the move corrupts
567
624
  # the C tree (libleptris silently handles non-child args badly).
568
- add_next_sibling(wrapper)
569
- wrapper.add_child(self)
570
- self
625
+ # The wrapper may be cross-document (parsed into a scratch doc,
626
+ # 1.9.304 #1528) — add_next_sibling returns the INSTALLED copy;
627
+ # move self into THAT.
628
+ installed = add_next_sibling(wrapper)
629
+ installed.add_child(self)
630
+ installed
571
631
  end
572
632
 
573
633
  # Deep copy in a NEW document via Document.copy_of (the single
@@ -608,6 +668,13 @@ class Leptris::XML::Element < Leptris::XML::Node
608
668
  ensure_writable!
609
669
  case node_or_markup
610
670
  when Leptris::XML::Node
671
+ # Cross-document adoption (1.9.304, #1528): the engine
672
+ # deep-copies foreign nodes at the splice — the returned
673
+ # wrapper must be the INSTALLED copy, not the detached
674
+ # source. Route those through the re-resolving path.
675
+ cross = node_or_markup.document &&
676
+ !node_or_markup.document.equal?(@document)
677
+ return append_installed(node_or_markup) if cross
611
678
  # C-bound append (TODO.perf/08-09): one dispatch runs the
612
679
  # readonly/liveness gates, the provable no-op lift
613
680
  # predicate, the version bump, and the engine append. Qnil
@@ -659,6 +726,47 @@ class Leptris::XML::Element < Leptris::XML::Node
659
726
  raise ArgumentError, "add_child expects a Node or String, got #{node_or_markup.class}"
660
727
  end
661
728
  end
729
+ # Cross-document append (1.9.304, #1528): the engine deep-copies
730
+ # the foreign node at the splice, so the installed node is this
731
+ # element's LAST child — re-wrap it and return that. The binding
732
+ # keeps its historical MOVE semantics on top: namespaces are
733
+ # lifted BEFORE the copy (declarations survive), and the source
734
+ # original is removed after (the source loses the node, as
735
+ # every pre-304 caller observed).
736
+ def append_installed(node)
737
+ unless Leptris::XML::Element.skip_adoption_lift?(node)
738
+ Leptris::XML::Element.lift_namespaces_for_adoption(node, namespaces)
739
+ end
740
+ Leptris::XML::FFI.check_status(
741
+ Leptris::XML::FFI.leptris_element_append_child(c_ptr, node.c_ptr))
742
+ Leptris::XML::Node.invalidate_cross_document!(node, @document)
743
+ remove_from_source_original(node)
744
+ last_installed
745
+ end
746
+ private :append_installed
747
+
748
+ # 1.9.304 (#1528): a foreign child appended to this document was
749
+ # adopted by COPY — remove the ORIGINAL from its source document
750
+ # (the binding's move semantics). The wrapper's @parent may be
751
+ # unset for lazily minted wrappers, so ask the ENGINE for the
752
+ # source parent and remove through a wrapped handle.
753
+ def remove_from_source_original(node)
754
+ return unless node.document && !node.document.equal?(@document)
755
+
756
+ srcp = Leptris::XML::FFI.leptris_node_parent(node.c_ptr)
757
+ return if srcp.nil? || srcp.null?
758
+
759
+ Leptris::XML::Node.wrap(srcp, node.document).remove_child(node)
760
+ end
761
+ private :remove_from_source_original
762
+
763
+ # The last child, wrapped fresh through the document's identity
764
+ # cache (bypasses any stale self-side wrapper of the same node).
765
+ def last_installed kids = children.to_a
766
+ kids.last
767
+ end
768
+ private :last_installed
769
+
662
770
  # The markup-append face appends in fragment order; the added
663
771
  # nodes are this element's last +count+ children.
664
772
  def last_added(count)
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.292
4
+ - libleptris v1.9.304
5
5
  - utf8proc v2.11.0
6
6
 
7
7
  Rebuild by hand: