leptris 1.9.362.1-arm-linux → 1.9.363.1-arm-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: d505c20eccb4e2b386fb97b23352696c4cf4a09b65beb33173fe4f56e5acb76e
4
- data.tar.gz: 9065bccde783c51f95fad5d08d4eda84450393e345f1c307b588df7fae99c356
3
+ metadata.gz: 925490d2b1768ed2ab9f27b1182011550c696601b8f36b129bdf427acaa51a76
4
+ data.tar.gz: 967796e1f35ea9636bf43f49ad6f73970df0dc8b161cf75aab57b165f08a8e79
5
5
  SHA512:
6
- metadata.gz: 4e4762693d0c5907d70d15d532ad55681718db89157e743907dd330c6639cb2ed3d4eee91540d5e3e7b5a3e7793bdb00020bce8511335f3b9224af46128e7d4c
7
- data.tar.gz: a9a84e6b9aaba30c5c7b3a232268baf149127207d12e159427d426daf4829d8bc378d20efe97045cc3eda070950aaf5526f23eb389c7686e805d333bedd9c95b
6
+ metadata.gz: 42b43e2760a56807be81cc0c0fa02617b4ade4dbfceab4e0291c1fcf1cd90e7d583ff82ca32c54eabb998f07ec8aad7f5798881cd46225b7f7d9f224a9a5e720
7
+ data.tar.gz: 252d2b9d79379509c5dde2ab5d8eb5e0bb30678838e95b2466c4c4a2b1a1b083f41576244894e6f0e8b7bbd0bda92fc28c9587b217904a0ba2adc05e94939426
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.362"
11
+ LIBLEPTRIS_VERSION = "1.9.363"
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.362.1"
4
+ VERSION = "1.9.363.1"
5
5
  end
data/lib/libleptris.so CHANGED
Binary file
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.362
4
+ - libleptris v1.9.363
5
5
  - utf8proc v2.11.0
6
6
 
7
7
  Rebuild by hand:
@@ -1,5 +1,23 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [1.9.363] - 2026-10-16
4
+
5
+ ### Fixed
6
+
7
+ - **parse: RECOVER folds a bare `<` in text into the run (#1748, PR #1750).**
8
+ `< b` — a `<` that opens no markup construct — had no recovery lane: even
9
+ under `LEPTRIS_PARSE_RECOVER` the parse aborted to the #547 empty-document
10
+ fallback with the diagnostic list EMPTY. Silent total data loss on
11
+ `<script>if (a < b) { c(); }</script>` (the shape HTML-producing tools
12
+ emit), and the missing record kept recovery-record-keyed consumers —
13
+ canon's loud/tolerant HTML fallback — from ever engaging, so the input
14
+ serialized as just the XML declaration. The text scan now folds the byte
15
+ into the run with a `LEPTRIS_DIAG_RECOVER` record under RECOVER (libxml2
16
+ keeps the full tree and reports 5 errors on the reporter's input; ours
17
+ now keeps the tree too); strict parsing still fails. Engine suite
18
+ 2046/2046; canon's battery spec goes 1 failure → 0.
19
+
20
+
3
21
  ## [1.9.362] - 2026-10-16
4
22
 
5
23
  ### Fixed
@@ -3,7 +3,7 @@
3
3
  cmake_minimum_required(VERSION 3.20)
4
4
 
5
5
  project(leptris
6
- VERSION 1.9.362
6
+ VERSION 1.9.363
7
7
  DESCRIPTION "Fast XML parser and XPath evaluator in pure C"
8
8
  LANGUAGES C CXX
9
9
  )
@@ -1729,7 +1729,7 @@ static struct leptris_document* direct_parse_internal(char* buf, size_t len,
1729
1729
  : ((p.end - q > 48) ? q + 48 : p.end);
1730
1730
  while (q < probe_end) {
1731
1731
  char ch = *q;
1732
- if (ch == '<') { lt = (char*)q; goto text_done; }
1732
+ if (ch == '<') { lt = (char*)q; break; }
1733
1733
  has_amp |= (ch == '&');
1734
1734
  has_cr |= (ch == '\r');
1735
1735
  q++;
@@ -1740,6 +1740,33 @@ static struct leptris_document* direct_parse_internal(char* buf, size_t len,
1740
1740
  has_amp |= memchr(q, '&', (size_t)((char*)lt - q)) != NULL;
1741
1741
  has_cr |= memchr(q, '\r', (size_t)((char*)lt - q)) != NULL;
1742
1742
  }
1743
+ /* leptris#1748: a '<' that opens no markup construct
1744
+ * ('!', '?', '/', name-start) is unescaped text. Strict
1745
+ * keeps failing at it; RECOVER records a diagnostic and
1746
+ * folds the byte into the text run (libxml2
1747
+ * XML_PARSE_RECOVER semantics) — previously this class
1748
+ * aborted to the empty-document fallback with NO tree
1749
+ * and NO diagnostic (the silent corruption canon hit). */
1750
+ while (lt && lt + 1 < p.end && p.recover) {
1751
+ char nx = lt[1];
1752
+ if (nx == '!' || nx == '?' || nx == '/' ||
1753
+ IS_NAME_START(nx))
1754
+ break;
1755
+ leptris_diag_emit(
1756
+ &p.doc->parse_diags, &p.doc->parse_diag_count,
1757
+ &p.doc->parse_diag_cap,
1758
+ LEPTRIS_DIAG_RECOVER, NULL,
1759
+ "Unescaped < not allowed in a text node");
1760
+ const char* nq = lt + 1;
1761
+ const char* nlt =
1762
+ memchr(nq, '<', (size_t)(p.end - nq));
1763
+ const char* span_end = nlt ? nlt : p.end;
1764
+ has_amp |= memchr(nq, '&',
1765
+ (size_t)(span_end - nq)) != NULL;
1766
+ has_cr |= memchr(nq, '\r',
1767
+ (size_t)(span_end - nq)) != NULL;
1768
+ lt = (char*)nlt;
1769
+ }
1743
1770
  text_done:
1744
1771
  p.pos = lt ? lt : p.end;
1745
1772
  size_t tlen = p.pos - text_start;
@@ -838,6 +838,68 @@ TEST(ParseRecover, UnclosedAtEofClosesEverything) {
838
838
  leptris_document_free(doc);
839
839
  }
840
840
 
841
+ /* leptris#1748: a bare '<' followed by a non-markup character
842
+ * ('< b') is unescaped text. RECOVER folds the byte into the text
843
+ * run (libxml2 XML_PARSE_RECOVER semantics) and records a
844
+ * diagnostic; the script-with-comparison shape previously aborted
845
+ * to the empty-document fallback SILENTLY — no tree, no diagnostic
846
+ * — which blinded every consumer keyed on the record. */
847
+ TEST(ParseRecover, BareLtInTextKeepsTreeAndRecords) {
848
+ LeptrisStatus st = LEPTRIS_OK;
849
+ const char xml[] =
850
+ "<root><script>if (a < b) { c(); }</script></root>";
851
+ LeptrisDocument doc = leptris_parse_string_flags(
852
+ xml, strlen(xml), LEPTRIS_PARSE_RECOVER, &st);
853
+ ASSERT_NE(doc, nullptr) << "status " << (int)st;
854
+ LeptrisElement root = leptris_document_root(doc);
855
+ ASSERT_NE(root, nullptr);
856
+ EXPECT_STREQ(leptris_element_name(root), "root");
857
+ LeptrisElement script = leptris_element_first_child_any(root);
858
+ ASSERT_NE(script, nullptr);
859
+ EXPECT_STREQ(leptris_element_name(script), "script");
860
+ /* The unescaped byte rides the text verbatim (libxml2 keeps the
861
+ * run as one node; ours may split — content is the contract). */
862
+ const char* text = leptris_element_text(script);
863
+ ASSERT_NE(text, nullptr);
864
+ EXPECT_STREQ(text, "if (a < b) { c(); }");
865
+ EXPECT_EQ(leptris_document_parse_diag_count(doc), 1u);
866
+ LeptrisDiagKind kind = (LeptrisDiagKind)-1;
867
+ char msg[128] = {0};
868
+ ASSERT_EQ(leptris_document_parse_diag(doc, 0, &kind, msg,
869
+ sizeof(msg)), 1);
870
+ EXPECT_EQ(kind, LEPTRIS_DIAG_RECOVER);
871
+ leptris_document_free(doc);
872
+ }
873
+
874
+ TEST(ParseRecover, BareLtInTextStrictStillFails) {
875
+ LeptrisStatus st = LEPTRIS_OK;
876
+ const char xml[] =
877
+ "<root><script>if (a < b) { c(); }</script></root>";
878
+ LeptrisDocument doc = leptris_parse_string_flags(
879
+ xml, strlen(xml), LEPTRIS_PARSE_DEFAULT, &st);
880
+ EXPECT_EQ(doc, nullptr);
881
+ EXPECT_EQ(st, LEPTRIS_ERROR_PARSE);
882
+ }
883
+
884
+ /* The #1748 reporter shape end-to-end: DOCTYPE-prefixed HTML-
885
+ * shaped input through the XML lane keeps the whole tree. */
886
+ TEST(ParseRecover, DoctypePrefixedHtmlShapeKeepsTree) {
887
+ LeptrisStatus st = LEPTRIS_OK;
888
+ const char xml[] =
889
+ "<!DOCTYPE html>\n<html><head><meta charset=\"utf-8\">"
890
+ "<title>t</title></head>\n"
891
+ "<body><p>hello<br>world<img src=\"x.png\"><ul><li>one<li>two</ul>\n"
892
+ "<script>if (a < b) { c(); }</script></body></html>";
893
+ LeptrisDocument doc = leptris_parse_string_flags(
894
+ xml, strlen(xml), LEPTRIS_PARSE_RECOVER, &st);
895
+ ASSERT_NE(doc, nullptr) << "status " << (int)st;
896
+ LeptrisElement root = leptris_document_root(doc);
897
+ ASSERT_NE(root, nullptr);
898
+ EXPECT_STREQ(leptris_element_name(root), "html");
899
+ EXPECT_GT(leptris_document_parse_diag_count(doc), 0u);
900
+ leptris_document_free(doc);
901
+ }
902
+
841
903
  TEST(ParseRecover, WithoutFlagStillFails) {
842
904
  LeptrisStatus st = LEPTRIS_OK;
843
905
  const char xml[] = "<root><a>x</b></root>";
@@ -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.362",
4
+ "version": "1.9.363",
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.362.1
4
+ version: 1.9.363.1
5
5
  platform: arm-linux
6
6
  authors:
7
7
  - Ribose Inc.