leptris 1.9.396.0-ppc64le-linux → 1.9.398.0-ppc64le-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: 948d64de60780abbd35c5eb75ecbb69609396b681b219047ef0ac7775b9383c3
4
- data.tar.gz: 69236732f06743bd08714bbf46697cadd63febc486e324ffeee46798c5182fce
3
+ metadata.gz: ac182cc0317771a9f1487906920c6d50bf545c80315b811654d84b59679c71bc
4
+ data.tar.gz: 0ddcd84f4438034af6a96526542174c15060ae75e6ea6df798c38a38f25a9b15
5
5
  SHA512:
6
- metadata.gz: d3a2ee8d49e508f8d27bbf36610c2d9cd1975c5ec8fdf6f8f752d81c1154f22c630fc5883ab2fd5af5afcafa920eebb8342a7e8777af3dd82fef88d6acf7957b
7
- data.tar.gz: 955dccf5c781bd9e1906bade2ae4182fa50d28c15dc899950f0edb340cb77c8deacc307a9132f9e7ba23348398ddd71e911d1082105c07940576f8fb9600956c
6
+ metadata.gz: 4b1207872fb11a74902eff09dd71d529c2407be2c77962928953a990973c37f329bc976996394b27f2d9414e7823647f8fae9e4ddbb3e70a80bb55638e3541fe
7
+ data.tar.gz: e6452c37d0afffcd4e98f222d4f6fa0854cb1b06e39182149e1c38bee4e160aed816ca5c6322588fc5c2571774f1ed4e6aed4db1027c82e4b1c6cf1d4f0e42b6
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.396"
11
+ LIBLEPTRIS_VERSION = "1.9.398"
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.396.0"
4
+ VERSION = "1.9.398.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.396
4
+ - libleptris v1.9.398
5
5
  - utf8proc v2.11.0
6
6
 
7
7
  Rebuild by hand:
@@ -1,5 +1,42 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [1.9.398] - 2026-10-31
4
+
5
+ ### Fixed
6
+
7
+ - **gMonth accepts both XSD 1.0 spellings (leptris#1936, PR
8
+ #1937).** The first edition defined the lexical as `--MM--` (the
9
+ W3C suite's gMonth002/004 carry `--03--`); the errata added
10
+ `--MM`. Both validate now, each with its optional timezone.
11
+ - **Absent timezone must end the lexical.** `tz_optional`'s absent
12
+ path returned success without reaching end of string, so the
13
+ g-regional/date family accepted trailing garbage (`--03garbage`,
14
+ `2026-10-08x`). Pinned by a 15-row red-first spec; the XSD
15
+ compile suite stays 138/138.
16
+ - **The automaton size cap is inert at instance validation
17
+ (moxml#514, PR #1938).** The #1894 cap is a resource guard, not a
18
+ validity signal: a document whose content model hits the cap
19
+ validates on its merits instead of failing.
20
+
21
+
22
+
23
+ ## [1.9.397] - 2026-10-31
24
+
25
+ ### Performance
26
+
27
+ - **Attribute-value tail fused into one pass (leptris#1842, PR
28
+ #1934).** With the UTF-8 gate on the SIMD validator, the line
29
+ profile moved to `dp_parse_attrs`: values of ~50 bytes just miss
30
+ the 48-byte inline probe, so every attribute paid the quote
31
+ memchr AND a SIMD-contains CALL for `&` AND a second full byte
32
+ loop for literal whitespace — three scans of every value. One
33
+ fused early-exit loop computes both flags: **parse +28%** on the
34
+ 2.2MB dense-UTF-8 fixture (4.11 -> 3.20 ms, 536 -> 686 MB/s with
35
+ frame pointers). Flag semantics unchanged; amp/whitespace hits
36
+ from the inline probe still short-circuit the tail.
37
+
38
+
39
+
3
40
  ## [1.9.396] - 2026-10-31
4
41
 
5
42
  ### Fixed
@@ -3,7 +3,7 @@
3
3
  cmake_minimum_required(VERSION 3.20)
4
4
 
5
5
  project(leptris
6
- VERSION 1.9.396
6
+ VERSION 1.9.398
7
7
  DESCRIPTION "Fast XML parser and XPath evaluator in pure C"
8
8
  LANGUAGES C CXX
9
9
  )
@@ -1114,17 +1114,17 @@ static int dp_parse_attrs(DParser* p, LeptrisElement elem) {
1114
1114
  if (q >= p->end) return -1; /* unterminated */
1115
1115
  val_end = (char*)memchr(q, quote, p->end - q);
1116
1116
  if (!val_end) return -1;
1117
- if (q < val_end) {
1118
- if (!has_amp &&
1119
- leptris_text_contains(q, (size_t)(val_end - q), '&'))
1120
- has_amp = 1;
1121
- if (!has_ws) {
1122
- for (const char* w = q; w < val_end; w++) {
1123
- if (*w == '\t' || *w == '\n' || *w == '\r') {
1124
- has_ws = 1;
1125
- break;
1126
- }
1127
- }
1117
+ if (q < val_end && (!has_amp || !has_ws)) {
1118
+ /* One fused pass for '&' and literal \t/\n/\r: the old
1119
+ * shape paid a SIMD-contains CALL plus a second byte
1120
+ * loop per attribute — 3 scans of every value on the
1121
+ * #1842 profile (50-byte values just miss the 48-byte
1122
+ * inline probe, so this tail ran for all of them). */
1123
+ for (const char* w = q; w < val_end; w++) {
1124
+ unsigned char c = (unsigned char)*w;
1125
+ has_amp |= (c == '&');
1126
+ has_ws |= (c == '\t' || c == '\n' || c == '\r');
1127
+ if (has_amp && has_ws) break;
1128
1128
  }
1129
1129
  }
1130
1130
  }
@@ -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;
@@ -460,6 +460,35 @@ TEST(XsdDatatypes, BuiltinsLexicalMatrix) {
460
460
  }
461
461
  }
462
462
 
463
+ /* leptris#1936: gMonth accepts BOTH XSD 1.0 spellings — the
464
+ * errata's --MM and the first edition's --MM-- — each with the
465
+ * optional timezone; and the g-regional/date family rejects
466
+ * trailing garbage after an absent timezone. */
467
+ TEST(XsdDatatypes, GMonthSpellingsAndStrictTail) {
468
+ const BuiltinCase rows[] = {
469
+ {"xs:gMonth", "--03", 1},
470
+ {"xs:gMonth", "--03--", 1},
471
+ {"xs:gMonth", "--03Z", 1},
472
+ {"xs:gMonth", "--03--Z", 1},
473
+ {"xs:gMonth", "--03--+05:00", 1},
474
+ {"xs:gMonth", "--03-05:00", 1},
475
+ {"xs:gMonth", "--12", 1},
476
+ {"xs:gMonth", "--13", 0},
477
+ {"xs:gMonth", "--00", 0},
478
+ {"xs:gMonth", "--03garbage", 0},
479
+ {"xs:gMonth", "--03-x", 0},
480
+ {"xs:gMonth", "--03--05:00", 0},
481
+ {"xs:date", "2026-10-08garbage", 0},
482
+ {"xs:gDay", "---05garbage", 0},
483
+ {"xs:gYear", "2026x", 0},
484
+ };
485
+ for (const BuiltinCase& c : rows) {
486
+ SCOPED_TRACE(std::string(c.type) + " : " + c.value);
487
+ EXPECT_EQ(leptris_xsd_builtin_valid(c.type, c.value), c.expect)
488
+ << c.type << " : " + std::string(c.value);
489
+ }
490
+ }
491
+
463
492
  /* leptris#1883: the builtin lexical table converges on Datatypes
464
493
  * Part 2 — collapse semantics, unbounded integers, +INF spelling,
465
494
  * 64-bit bounds, calendar/duration/binary grammars, xmlns prefix. */
@@ -3657,6 +3686,33 @@ TEST(XsdContent, PathologicalProductFailsLoudlyNotOom) {
3657
3686
  leptris_xsd_free(s);
3658
3687
  }
3659
3688
 
3689
+ /* lutaml/moxml#514: the cap is a resource guard, not a validity
3690
+ * verdict. A content model whose NFA crosses the cap is engine-INERT
3691
+ * at INSTANCE validation — no structured row flips a suite-valid
3692
+ * document to invalid (the compile-time loud face above is the one
3693
+ * place the guard reports). */
3694
+ TEST(XsdContent, Issue514CapIsInertAtInstanceValidation) {
3695
+ std::string xsd =
3696
+ "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">"
3697
+ "<xs:element name=\"r\"><xs:complexType><xs:sequence"
3698
+ " minOccurs=\"0\" maxOccurs=\"2000\"><xs:element name=\"e\""
3699
+ " minOccurs=\"0\" maxOccurs=\"2000\"/></xs:sequence>"
3700
+ "</xs:complexType></xs:element></xs:schema>";
3701
+ LeptrisStatus st = LEPTRIS_OK;
3702
+ LeptrisXsdSchema s =
3703
+ leptris_xsd_compile(xsd.data(), xsd.size(), &st);
3704
+ ASSERT_EQ(st, LEPTRIS_OK);
3705
+ ASSERT_NE(s, (LeptrisXsdSchema)0);
3706
+ LeptrisDocument d = leptris_parse_string("<r><e/><e/></r>", 15, &st);
3707
+ ASSERT_NE(d, nullptr);
3708
+ /* The instance is suite-valid and stays valid: the capped model
3709
+ * is skipped, not failed. */
3710
+ EXPECT_EQ(leptris_xsd_validate(s, d), 1);
3711
+ EXPECT_EQ(leptris_xsd_error_count(s), 0u);
3712
+ leptris_document_free(d);
3713
+ leptris_xsd_free(s);
3714
+ }
3715
+
3660
3716
  TEST(XsdContent, Issue1894ReproStaysUnderCapAndCorrect) {
3661
3717
  /* The issue's exact shape — seq maxOccurs=100 x element
3662
3718
  * unbounded — lowers to a loop region (not copies) and must stay
@@ -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.396",
4
+ "version": "1.9.398",
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.396.0
4
+ version: 1.9.398.0
5
5
  platform: ppc64le-linux
6
6
  authors:
7
7
  - Ribose Inc.