leptris 1.9.397.0-aarch64-linux → 1.9.399.0-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: c65a84ecbd6e96187a169401563798f631e7de15b0638bc8f0d0fbc7d2f43f8d
4
- data.tar.gz: 5267225bffc4d8b4438ffecdcb68def71cf4821827277efd9d7e39269ef5ac53
3
+ metadata.gz: 8ee567480d7436e81ceb4c35baae6974371c1df90df68d8473e7209dc6664e7d
4
+ data.tar.gz: 5ca5752f73dbf2ddcf412b4159de0ebe08e87b88795c30be7da75ba57b7ee65f
5
5
  SHA512:
6
- metadata.gz: 2a6f4e3a13f4b84ab998021800d2233f7d4ffb91f29ec4ef860b8776a15482df23eb61c9b5f91ace55ab5eb64a5174eac68a2ae6ce78d3ecce0f50e6dd60199e
7
- data.tar.gz: 1fbea43a7237f8dad724876fe5b53b6a45260b9595b14b89da3e32a0bf38f378d9fa7785650525c4d59d869fb2c38bef5a6f07bb7a34354a3933ccef467b8a8e
6
+ metadata.gz: 2f25e1ec465dcbb76e9f929880e792ab2267ac8aaf1bb9457f8b5247913236a5681218f1f417ba5eb6331363c1ed116a3ddd9a6f025171d5612efbfcec884aae
7
+ data.tar.gz: ce88957154689ea6227d993cf37e46b5de9b7cbb71a4d5bfb762cd97f2aa82b8d645e70521804c1336d07f3f151153b5617061e3a54bd3ddaf91800f1ff17e7a
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.397"
11
+ LIBLEPTRIS_VERSION = "1.9.399"
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.397.0"
4
+ VERSION = "1.9.399.0"
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.397
4
+ - libleptris v1.9.399
5
5
  - utf8proc v2.11.0
6
6
 
7
7
  Rebuild by hand:
@@ -1,5 +1,43 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [1.9.399] - 2026-10-31
4
+
5
+ ### Fixed
6
+
7
+ - **`\\d` matches the Unicode-3.1 legacy digits (leptris#1936,
8
+ PR #1940).** XSD 1.0 Part 2 cites Unicode 3.1, where
9
+ U+1369–U+1371 (Ethiopic digits one-nine) were Nd — Unicode 4.0.1
10
+ demoted them to No, so the utf8proc-backed Nd mask missed them
11
+ and the suite's reS38 (`\\d` vs `፱`) / reT51 (`\\D`) rows
12
+ failed. The legacy-Nd set now joins the class as a pure-codepoint
13
+ range, outside the utf8proc guard so every build (windows
14
+ included) answers it; `\\D` inherits the exclusion through the
15
+ complement's negation. RED-first spec
16
+ (`XsdDatatypes.DigitClassPinsLegacyNd`), and the shared-fixture
17
+ collision behind an arm-lane flake got unique names.
18
+
19
+
20
+
21
+ ## [1.9.398] - 2026-10-31
22
+
23
+ ### Fixed
24
+
25
+ - **gMonth accepts both XSD 1.0 spellings (leptris#1936, PR
26
+ #1937).** The first edition defined the lexical as `--MM--` (the
27
+ W3C suite's gMonth002/004 carry `--03--`); the errata added
28
+ `--MM`. Both validate now, each with its optional timezone.
29
+ - **Absent timezone must end the lexical.** `tz_optional`'s absent
30
+ path returned success without reaching end of string, so the
31
+ g-regional/date family accepted trailing garbage (`--03garbage`,
32
+ `2026-10-08x`). Pinned by a 15-row red-first spec; the XSD
33
+ compile suite stays 138/138.
34
+ - **The automaton size cap is inert at instance validation
35
+ (moxml#514, PR #1938).** The #1894 cap is a resource guard, not a
36
+ validity signal: a document whose content model hits the cap
37
+ validates on its merits instead of failing.
38
+
39
+
40
+
3
41
  ## [1.9.397] - 2026-10-31
4
42
 
5
43
  ### Performance
@@ -3,7 +3,7 @@
3
3
  cmake_minimum_required(VERSION 3.20)
4
4
 
5
5
  project(leptris
6
- VERSION 1.9.397
6
+ VERSION 1.9.399
7
7
  DESCRIPTION "Fast XML parser and XPath evaluator in pure C"
8
8
  LANGUAGES C CXX
9
9
  )
@@ -112,6 +112,17 @@ static void cls_add_builtin(RreNode* n, char c) {
112
112
  n->cat_set = 1;
113
113
  n->cat_mask |= 1u << UTF8PROC_CATEGORY_ND;
114
114
  #endif
115
+ /* XSD 1.0 cites Unicode 3.1, where U+1369-1371
116
+ * (Ethiopic digits one-nine) were Nd — Unicode 4.0.1
117
+ * demoted them to No, so modern tables miss them
118
+ * (#1936 reS38/reT51). Pin the legacy-Nd set outside
119
+ * the utf8proc guard: the ranges are pure codepoints
120
+ * and \d must answer them on every build. */
121
+ if (n->uni_n < 4) {
122
+ n->uni_lo[n->uni_n] = 0x1369;
123
+ n->uni_hi[n->uni_n] = 0x1371;
124
+ n->uni_n++;
125
+ }
115
126
  break;
116
127
  case 'w':
117
128
  for (int i = '0'; i <= '9'; i++) cls_add(n, (unsigned char)i);
@@ -146,7 +146,9 @@ static int two_digits(const char** p) {
146
146
  return 1;
147
147
  }
148
148
  static int tz_optional(const char** p) {
149
- if (**p != 'Z' && **p != '+' && **p != '-') return 1; /* absent */
149
+ /* #1936: the absent timezone is only absent at END of string —
150
+ * "2000-01-01garbage" used to pass the g-regional family. */
151
+ if (**p != 'Z' && **p != '+' && **p != '-') return **p == 0;
150
152
  if (**p == 'Z') { (*p)++; return **p == 0; }
151
153
  (*p)++;
152
154
  return two_digits(p) && *(*p) == ':' && (*p)++ && two_digits(p) &&
@@ -393,7 +395,15 @@ int xsd_builtin_valid(const char* type, const char* v) {
393
395
  const char* p = v;
394
396
  if (*p++ != '-') return 0;
395
397
  if (*p++ != '-') return 0;
396
- return two_digits_bounded(&p, 1, 12) && tz_optional(&p);
398
+ if (!two_digits_bounded(&p, 1, 12)) return 0;
399
+ /* #1936: XSD 1.0 first edition spelled the lexical --MM--
400
+ * (the errata added --MM) — both are valid 1.0 forms, each
401
+ * carrying the optional timezone. */
402
+ if (p[0] == '-' && p[1] == '-') {
403
+ const char* q = p + 2;
404
+ return tz_optional(&q);
405
+ }
406
+ return tz_optional(&p);
397
407
  }
398
408
  if (strcmp(type, "xs:dateTime") == 0) {
399
409
  const char* p = v;
@@ -392,14 +392,13 @@ static void validate_children(struct xsd_validator* v,
392
392
  int ok = xsd_content_valid(s, model, xsd_target_ns(s), names, uris,
393
393
  n);
394
394
  if (ok == -2) {
395
- /* #1894: pathological occurrence product — the automaton
396
- * exceeds the compile-time size cap. Loud, not a hang. */
397
- const char* l2 = NULL;
398
- leptris_element_expanded_name(elem, &l2, NULL, NULL);
399
- verrf_atk(v, elem, "content-model", l2 ? l2 : "", "element",
400
- l2 ? l2 : "",
401
- "content model exceeds the automaton size cap "
402
- "(pathological occurrence product)");
395
+ /* #1894/#514: pathological occurrence product — the automaton
396
+ * exceeds the compile-time size cap. The cap is a resource
397
+ * guard, not a validity verdict: the content model is
398
+ * engine-INERT for this element (no instance finding — the
399
+ * consuming validator decides), the same posture as the
400
+ * compile-time guard. The element's content check is skipped
401
+ * and the walk continues; under-report, never false-report. */
403
402
  free(names);
404
403
  free(uris);
405
404
  return;
@@ -390,6 +390,32 @@ TEST(XsdDatatypes, LengthFacetCountsOctetsForHexBinary) {
390
390
  // byte world and character-class SUBTRACTION — the OPC
391
391
  // ST_ContentType shape. A pattern that fails to parse rejects
392
392
  // everything, so media types failed wholesale.
393
+ // leptris#1936 (reS38/reT51): XSD 1.0 cites Unicode 3.1, where
394
+ // U+1369-1371 (Ethiopic digits one-nine) were Nd — \\d matches
395
+ // &#x1371; and \\D rejects it even though the host tables (4.0.1+)
396
+ // carry them as No.
397
+ TEST(XsdDatatypes, DigitClassPinsLegacyNd) {
398
+ const char xsd[] =
399
+ "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">"
400
+ "<xs:simpleType name=\"Digs\"><xs:restriction base=\"xs:string\">"
401
+ "<xs:pattern value=\"\\d\"/></xs:restriction></xs:simpleType>"
402
+ "<xs:simpleType name=\"NonDigs\"><xs:restriction base=\"xs:string\">"
403
+ "<xs:pattern value=\"\\D\"/></xs:restriction></xs:simpleType>"
404
+ "</xs:schema>";
405
+ LeptrisStatus st = LEPTRIS_OK;
406
+ LeptrisXsdSchema s = leptris_xsd_compile(xsd, strlen(xsd), &st);
407
+ ASSERT_EQ(st, LEPTRIS_OK);
408
+ ASSERT_NE(s, (LeptrisXsdSchema)0);
409
+ EXPECT_EQ(leptris_xsd_simple_valid(s, "Digs", "\xE1\x8D\xB1"), 1);
410
+ EXPECT_EQ(leptris_xsd_simple_valid(s, "Digs", "\xE1\x8D\xA9"), 1);
411
+ EXPECT_EQ(leptris_xsd_simple_valid(s, "Digs", "5"), 1);
412
+ EXPECT_EQ(leptris_xsd_simple_valid(s, "Digs", "x"), 0);
413
+ EXPECT_EQ(leptris_xsd_simple_valid(s, "NonDigs", "\xE1\x8D\xB1"), 0);
414
+ EXPECT_EQ(leptris_xsd_simple_valid(s, "NonDigs", "5"), 0);
415
+ EXPECT_EQ(leptris_xsd_simple_valid(s, "NonDigs", "x"), 1);
416
+ leptris_xsd_free(s);
417
+ }
418
+
393
419
  TEST(XsdDatatypes, PatternPropertyClassesAndSubtraction) {
394
420
  // The OPC ST_ContentType shape, minus the quoted-string member
395
421
  // (same property-class + subtraction machinery): type/subtype
@@ -460,6 +486,35 @@ TEST(XsdDatatypes, BuiltinsLexicalMatrix) {
460
486
  }
461
487
  }
462
488
 
489
+ /* leptris#1936: gMonth accepts BOTH XSD 1.0 spellings — the
490
+ * errata's --MM and the first edition's --MM-- — each with the
491
+ * optional timezone; and the g-regional/date family rejects
492
+ * trailing garbage after an absent timezone. */
493
+ TEST(XsdDatatypes, GMonthSpellingsAndStrictTail) {
494
+ const BuiltinCase rows[] = {
495
+ {"xs:gMonth", "--03", 1},
496
+ {"xs:gMonth", "--03--", 1},
497
+ {"xs:gMonth", "--03Z", 1},
498
+ {"xs:gMonth", "--03--Z", 1},
499
+ {"xs:gMonth", "--03--+05:00", 1},
500
+ {"xs:gMonth", "--03-05:00", 1},
501
+ {"xs:gMonth", "--12", 1},
502
+ {"xs:gMonth", "--13", 0},
503
+ {"xs:gMonth", "--00", 0},
504
+ {"xs:gMonth", "--03garbage", 0},
505
+ {"xs:gMonth", "--03-x", 0},
506
+ {"xs:gMonth", "--03--05:00", 0},
507
+ {"xs:date", "2026-10-08garbage", 0},
508
+ {"xs:gDay", "---05garbage", 0},
509
+ {"xs:gYear", "2026x", 0},
510
+ };
511
+ for (const BuiltinCase& c : rows) {
512
+ SCOPED_TRACE(std::string(c.type) + " : " + c.value);
513
+ EXPECT_EQ(leptris_xsd_builtin_valid(c.type, c.value), c.expect)
514
+ << c.type << " : " + std::string(c.value);
515
+ }
516
+ }
517
+
463
518
  /* leptris#1883: the builtin lexical table converges on Datatypes
464
519
  * Part 2 — collapse semantics, unbounded integers, +INF spelling,
465
520
  * 64-bit bounds, calendar/duration/binary grammars, xmlns prefix. */
@@ -3657,6 +3712,33 @@ TEST(XsdContent, PathologicalProductFailsLoudlyNotOom) {
3657
3712
  leptris_xsd_free(s);
3658
3713
  }
3659
3714
 
3715
+ /* lutaml/moxml#514: the cap is a resource guard, not a validity
3716
+ * verdict. A content model whose NFA crosses the cap is engine-INERT
3717
+ * at INSTANCE validation — no structured row flips a suite-valid
3718
+ * document to invalid (the compile-time loud face above is the one
3719
+ * place the guard reports). */
3720
+ TEST(XsdContent, Issue514CapIsInertAtInstanceValidation) {
3721
+ std::string xsd =
3722
+ "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">"
3723
+ "<xs:element name=\"r\"><xs:complexType><xs:sequence"
3724
+ " minOccurs=\"0\" maxOccurs=\"2000\"><xs:element name=\"e\""
3725
+ " minOccurs=\"0\" maxOccurs=\"2000\"/></xs:sequence>"
3726
+ "</xs:complexType></xs:element></xs:schema>";
3727
+ LeptrisStatus st = LEPTRIS_OK;
3728
+ LeptrisXsdSchema s =
3729
+ leptris_xsd_compile(xsd.data(), xsd.size(), &st);
3730
+ ASSERT_EQ(st, LEPTRIS_OK);
3731
+ ASSERT_NE(s, (LeptrisXsdSchema)0);
3732
+ LeptrisDocument d = leptris_parse_string("<r><e/><e/></r>", 15, &st);
3733
+ ASSERT_NE(d, nullptr);
3734
+ /* The instance is suite-valid and stays valid: the capped model
3735
+ * is skipped, not failed. */
3736
+ EXPECT_EQ(leptris_xsd_validate(s, d), 1);
3737
+ EXPECT_EQ(leptris_xsd_error_count(s), 0u);
3738
+ leptris_document_free(d);
3739
+ leptris_xsd_free(s);
3740
+ }
3741
+
3660
3742
  TEST(XsdContent, Issue1894ReproStaysUnderCapAndCorrect) {
3661
3743
  /* The issue's exact shape — seq maxOccurs=100 x element
3662
3744
  * unbounded — lowers to a loop region (not copies) and must stay
@@ -3760,7 +3842,7 @@ TEST(XsdCrossNs, SingleDocImportChaseResolves) {
3760
3842
  " xmlns:r=\"urn:r\" xmlns=\"urn:a\" targetNamespace=\"urn:a\""
3761
3843
  " elementFormDefault=\"qualified\">"
3762
3844
  "<xs:import namespace=\"urn:r\""
3763
- " schemaLocation=\"blip_repro_rel.xsd\"/>"
3845
+ " schemaLocation=\"blip_chase_rel.xsd\"/>"
3764
3846
  "<xs:attributeGroup name=\"AG_Blob\">"
3765
3847
  "<xs:attribute ref=\"r:embed\" use=\"optional\"/>"
3766
3848
  "</xs:attributeGroup>"
@@ -3776,8 +3858,8 @@ TEST(XsdCrossNs, SingleDocImportChaseResolves) {
3776
3858
  if (!dir) dir = std::getenv("TEMP"); /* windows runners define TEMP/TMP */
3777
3859
  if (!dir) dir = std::getenv("TMP");
3778
3860
  std::string base = dir ? dir : ".";
3779
- std::string rel_path = base + "/blip_repro_rel.xsd";
3780
- std::string main_path = base + "/blip_repro_main.xsd";
3861
+ std::string rel_path = base + "/blip_chase_rel.xsd";
3862
+ std::string main_path = base + "/blip_chase_main.xsd";
3781
3863
  {
3782
3864
  std::ofstream f(rel_path);
3783
3865
  f << rel;
@@ -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.397",
4
+ "version": "1.9.399",
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.397.0
4
+ version: 1.9.399.0
5
5
  platform: aarch64-linux
6
6
  authors:
7
7
  - Ribose Inc.