leptris 1.9.322.0-aarch64-linux → 1.9.323.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: 7cff747c994e40643b0cc1a8ac9eed34824664b6e88888195ec4a2f4191dca78
4
- data.tar.gz: bbd9e7ed63e8e24d383368399d0da9fc401e664b9377411ffaecb646486e70a3
3
+ metadata.gz: 2952b2796c8abade02c179d5fc354286188f58cb883f6e3c6589af9bf9636730
4
+ data.tar.gz: 33f7096e37bf17398b841aa580c37b9f2d92c9bfac61e3a5e12690681714a741
5
5
  SHA512:
6
- metadata.gz: dfd0aa551baa98ecdd243f7bf8ba3d88583ebb1ae1b880fad72e9337963971cd46898550b0aea73da6c6f4299d350a04f2a92f8d835f068624a3ca234c344e65
7
- data.tar.gz: 6bf7ecfe8511c5567a17643220f651fb2c560f5d8f178e1fd3af370e40f52d1bad67ad7eb102175525f9192a810872ad8a85a0f9cec0a92a8c995765e3528849
6
+ metadata.gz: c9d05126e8bb3d6c3e686fcfb1867603db31b3b90ee634d52ff6543d02f03df92bc235c5bd0663c003e8880e650042be164c15dc4964ab832963f52a03a7b060
7
+ data.tar.gz: 4bc862cce974f3e2dc8d09e8e2b5d03aa7751344f154c6f42d8bfe34d8d31759f7376ac0f6bce829545fa2a5b100e553f8cdf7a7edc377b4d3c06edb49bc9481
data/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## [1.9.323.0] - 2026-10-08
2
+
3
+ ### Fixed — engine sync (libleptris 1.9.323)
4
+
5
+ - **Inline anonymous complexType/simpleType capture (#1592,
6
+ engine PR #1596)**: elements carrying an inline anonymous type —
7
+ the most common XSD spelling — previously got no content model
8
+ (instance validation silently skipped their content check;
9
+ content_valid? answered -1). Inline types capture under a
10
+ synthesized element:NAME slot now; particle text types through
11
+ the slot too. Pinned: content-model enforcement with enumerated
12
+ errors, content_valid? answering, anonymous simpleType
13
+ patterns binding.
14
+
1
15
  ## [1.9.322.0] - 2026-10-08
2
16
 
3
17
  ### Engine sync (libleptris 1.9.322)
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.322"
11
+ LIBLEPTRIS_VERSION = "1.9.323"
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.322.0"
4
+ VERSION = "1.9.323.0"
5
5
  end
@@ -533,6 +533,11 @@ class Leptris::XML::Document
533
533
  Leptris::XML::Serialization::DOCUMENT_SERIALIZE_INTO, c_ptr,
534
534
  indent: indent, no_decl: no_decl, encoding: encoding)
535
535
  end
536
+
537
+ # Nokogiri parity (leptris#1595): to_s serializes the document.
538
+ def to_s
539
+ to_xml
540
+ end
536
541
  alias_method :to_s, :to_xml
537
542
  alias_method :serialize, :to_xml
538
543
 
@@ -943,6 +943,14 @@ class Leptris::XML::Element < Leptris::XML::Node
943
943
  indent: indent, no_decl: no_decl, encoding: encoding)
944
944
  end
945
945
 
946
+ # Nokogiri parity (leptris#1595): to_s serializes the node —
947
+ # the default Object#to_s object dump leaked into migrated
948
+ # consumers (coradoc math stems). Serialization options ride
949
+ # to_xml; to_s is the no-options convenience form.
950
+ def to_s
951
+ to_xml
952
+ end
953
+
946
954
  # HTML5 serialization of this element subtree (#309 — see
947
955
  # Document#to_html for the semantics).
948
956
  def to_html
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.322
4
+ - libleptris v1.9.323
5
5
  - utf8proc v2.11.0
6
6
 
7
7
  Rebuild by hand:
@@ -1,5 +1,22 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [1.9.323] - 2026-10-08
4
+
5
+ ### Fixed
6
+
7
+ - **XSD: inline anonymous complexType/simpleType capture
8
+ (#1592, PR #1596).** Elements carrying an inline anonymous type —
9
+ arguably the most common XSD spelling — got no content model:
10
+ instance validation silently skipped their content check and
11
+ `leptris_xsd_content_valid` answered −1. Inline types now capture
12
+ under a synthesized `element:NAME` slot (collision-free — `:`
13
+ cannot appear in xs: NCName type names): top-level elements and
14
+ every particle fall back to the inline capture when the type
15
+ attribute is absent, and local simpleType particles type their
16
+ text through the slot.
17
+
18
+
19
+
3
20
  ## [1.9.322] - 2026-10-08
4
21
 
5
22
  ### Added
@@ -3,7 +3,7 @@
3
3
  cmake_minimum_required(VERSION 3.20)
4
4
 
5
5
  project(leptris
6
- VERSION 1.9.322
6
+ VERSION 1.9.323
7
7
  DESCRIPTION "Fast XML parser and XPath evaluator in pure C"
8
8
  LANGUAGES C CXX
9
9
  )
@@ -4,6 +4,7 @@
4
4
  * grow the model (datatypes, facets, content models, identity
5
5
  * constraints) — this slice's contract is the API shape, the
6
6
  * xs:schema identity check, and the declaration enumeration. */
7
+ #include <stdio.h>
7
8
  #include <stdlib.h>
8
9
  #include <string.h>
9
10
 
@@ -41,6 +42,20 @@ struct leptris_xsd_schema {
41
42
 
42
43
  static char* xsd_strdup(const char* s);
43
44
 
45
+ /* #1592: capture an INLINE anonymous xs:complexType / xs:simpleType
46
+ * under a synthesized name ("element:NAME" — ':' cannot appear in
47
+ * xs: NCName type names, so the slot is collision-free). Returns 1
48
+ * when a capture happened. Forward decls below; definitions later
49
+ * in this file. */
50
+ static int xsd_capture_inline(struct leptris_xsd_schema* s,
51
+ LeptrisElement elem, const char* synth);
52
+ static XsdCm* xsd_cm_new(XsdCmKind kind);
53
+ static void xsd_cm_occurrence(XsdCm* cm, LeptrisElement e);
54
+ static XsdCm* xsd_cm_parse(struct leptris_xsd_schema* s,
55
+ LeptrisElement group, XsdCm** tail_out);
56
+ static XsdSimple* xsd_capture_simple(LeptrisElement st);
57
+
58
+
44
59
  static XsdCm* xsd_cm_new(XsdCmKind kind) {
45
60
  XsdCm* cm = (XsdCm*)calloc(1, sizeof(*cm));
46
61
  if (!cm) return NULL;
@@ -73,7 +88,45 @@ static void xsd_cm_occurrence(XsdCm* cm, LeptrisElement e) {
73
88
  /* Recursive model build over sequence | choice | all | element |
74
89
  * any children. Returns the child list head; *tail_out receives
75
90
  * the list tail for sibling chaining. */
76
- static XsdCm* xsd_cm_parse(LeptrisElement group, XsdCm** tail_out) {
91
+ /* #1592: capture an INLINE anonymous xs:complexType / xs:simpleType
92
+ * under a synthesized name ("element:NAME" — ':' cannot appear in
93
+ * xs: NCName type names, so the slot is collision-free). Returns 1
94
+ * when a capture happened. */
95
+ static int xsd_capture_inline(struct leptris_xsd_schema* s,
96
+ LeptrisElement elem, const char* synth) {
97
+ for (LeptrisNodeRef n =
98
+ leptris_node_first_child(leptris_element_as_node(elem));
99
+ n; n = leptris_node_next_sibling(n)) {
100
+ if (leptris_node_get_type(n) != LEPTRIS_NODE_TYPE_ELEMENT)
101
+ continue;
102
+ LeptrisElement e = (LeptrisElement)n;
103
+ const char* local = NULL, *prefix = NULL, *uri = NULL;
104
+ leptris_element_expanded_name(e, &local, &prefix, &uri);
105
+ if (!local || !uri || strcmp(uri, XSD_NS) != 0) continue;
106
+ if (strcmp(local, "complexType") == 0) {
107
+ XsdCm* root = xsd_cm_new(XSD_CM_SEQ);
108
+ if (!root) return 0;
109
+ root->name = xsd_strdup(synth);
110
+ root->first_child = xsd_cm_parse(s, e, NULL);
111
+ root->next = s->complex_types;
112
+ s->complex_types = root;
113
+ return 1;
114
+ }
115
+ if (strcmp(local, "simpleType") == 0) {
116
+ XsdSimple* captured = xsd_capture_simple(e);
117
+ if (!captured) return 0;
118
+ free(captured->name);
119
+ captured->name = xsd_strdup(synth);
120
+ captured->next = s->simple_types;
121
+ s->simple_types = captured;
122
+ return 1;
123
+ }
124
+ }
125
+ return 0;
126
+ }
127
+
128
+ static XsdCm* xsd_cm_parse(struct leptris_xsd_schema* s,
129
+ LeptrisElement group, XsdCm** tail_out) {
77
130
  XsdCm* head = NULL;
78
131
  XsdCm* tail = NULL;
79
132
  for (LeptrisNodeRef n =
@@ -92,7 +145,7 @@ static XsdCm* xsd_cm_parse(LeptrisElement group, XsdCm** tail_out) {
92
145
  cm = xsd_cm_new(strcmp(local, "sequence") == 0 ? XSD_CM_SEQ
93
146
  : strcmp(local, "choice") == 0 ? XSD_CM_CHOICE
94
147
  : XSD_CM_ALL);
95
- if (cm) cm->first_child = xsd_cm_parse(e, NULL);
148
+ if (cm) cm->first_child = xsd_cm_parse(s, e, NULL);
96
149
  } else if (strcmp(local, "element") == 0) {
97
150
  cm = xsd_cm_new(XSD_CM_ELEMENT);
98
151
  if (cm) {
@@ -100,8 +153,17 @@ static XsdCm* xsd_cm_parse(LeptrisElement group, XsdCm** tail_out) {
100
153
  leptris_element_attribute(e, "name");
101
154
  if (!nm) nm = leptris_element_attribute(e, "ref");
102
155
  cm->name = xsd_strdup(nm);
103
- cm->type = xsd_strdup(
104
- leptris_element_attribute(e, "type"));
156
+ const char* pty =
157
+ leptris_element_attribute(e, "type");
158
+ if (pty) {
159
+ cm->type = xsd_strdup(pty);
160
+ } else if (s && nm) {
161
+ /* #1592: inline anonymous type on the particle */
162
+ char synth[512];
163
+ snprintf(synth, sizeof(synth), "element:%s", nm);
164
+ if (xsd_capture_inline(s, e, synth))
165
+ cm->type = xsd_strdup(synth);
166
+ }
105
167
  }
106
168
  } else if (strcmp(local, "any") == 0) {
107
169
  cm = xsd_cm_new(XSD_CM_ANY);
@@ -140,7 +202,9 @@ static char* xsd_strdup(const char* s) {
140
202
  /* Capture one xs:simpleType's restriction model (slice 2). */
141
203
  static XsdSimple* xsd_capture_simple(LeptrisElement st) {
142
204
  const char* name = leptris_element_attribute(st, "name");
143
- if (!name) return NULL; /* anonymous types ride their element */
205
+ /* Anonymous types ride their element — allowed: the caller
206
+ * renames the captured entry into its synthesized slot
207
+ * (#1592). */
144
208
 
145
209
  XsdSimple* simple = (XsdSimple*)calloc(1, sizeof(*simple));
146
210
  if (!simple) return NULL;
@@ -323,6 +387,21 @@ LEPTRIS_API LeptrisXsdSchema leptris_xsd_compile(const char* xsd_text,
323
387
  d->next = s->elements;
324
388
  s->elements = d;
325
389
  }
390
+ } else if (nm) {
391
+ /* #1592: inline anonymous type — capture under the
392
+ * synthesized slot and point the declaration at it. */
393
+ char synth[512];
394
+ snprintf(synth, sizeof(synth), "element:%s", nm);
395
+ if (xsd_capture_inline(s, (LeptrisElement)n, synth)) {
396
+ XsdElementDecl* d =
397
+ (XsdElementDecl*)calloc(1, sizeof(*d));
398
+ if (d) {
399
+ d->name = xsd_strdup(nm);
400
+ d->type = xsd_strdup(synth);
401
+ d->next = s->elements;
402
+ s->elements = d;
403
+ }
404
+ }
326
405
  }
327
406
  } else if (strcmp(local, "complexType") == 0 && uri &&
328
407
  !strcmp(uri, XSD_NS)) {
@@ -334,7 +413,7 @@ LEPTRIS_API LeptrisXsdSchema leptris_xsd_compile(const char* xsd_text,
334
413
  if (root) {
335
414
  root->name = xsd_strdup(nm);
336
415
  root->first_child =
337
- xsd_cm_parse((LeptrisElement)n, NULL);
416
+ xsd_cm_parse(s, (LeptrisElement)n, NULL);
338
417
  root->next = s->complex_types;
339
418
  s->complex_types = root;
340
419
  }
@@ -517,3 +517,91 @@ TEST(XsdValidate, NullTolerant) {
517
517
  }
518
518
 
519
519
  } // namespace
520
+
521
+ // ---- #1592: inline anonymous types ---------------------------------
522
+ namespace {
523
+
524
+ const char* k_anon_schema =
525
+ "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">"
526
+ "<xs:element name=\"book\">"
527
+ "<xs:complexType>"
528
+ "<xs:sequence>"
529
+ "<xs:element name=\"title\" type=\"xs:token\"/>"
530
+ "<xs:element name=\"author\" type=\"xs:token\"/>"
531
+ "</xs:sequence>"
532
+ "</xs:complexType>"
533
+ "</xs:element>"
534
+ "</xs:schema>";
535
+
536
+ TEST(XsdContent, AnonymousInlineComplexTypeCaptured) {
537
+ LeptrisStatus st = LEPTRIS_OK;
538
+ LeptrisXsdSchema s =
539
+ leptris_xsd_compile(k_anon_schema, strlen(k_anon_schema), &st);
540
+ ASSERT_NE(s, (LeptrisXsdSchema)0);
541
+ /* the issue's exact symptom: content_valid answered -1 */
542
+ const char* good[] = {"title", "author"};
543
+ EXPECT_EQ(leptris_xsd_content_valid(s, "book", good, NULL, 2), 1);
544
+ const char* bad[] = {"author", "author", "isbn"};
545
+ EXPECT_EQ(leptris_xsd_content_valid(s, "book", bad, NULL, 3), 0);
546
+ const char* miss[] = {"author"};
547
+ EXPECT_EQ(leptris_xsd_content_valid(s, "book", miss, NULL, 1), 0);
548
+ leptris_xsd_free(s);
549
+ }
550
+
551
+ TEST(XsdValidate, AnonymousInlineValidatesEndToEnd) {
552
+ LeptrisStatus st = LEPTRIS_OK;
553
+ LeptrisXsdSchema s =
554
+ leptris_xsd_compile(k_anon_schema, strlen(k_anon_schema), &st);
555
+ ASSERT_NE(s, (LeptrisXsdSchema)0);
556
+ const char* good_x = "<book><title>t</title><author>a</author></book>";
557
+ LeptrisDocument good =
558
+ leptris_parse_string(good_x, strlen(good_x), &st);
559
+ ASSERT_NE(good, nullptr);
560
+ EXPECT_EQ(leptris_xsd_validate(s, good), 1);
561
+ leptris_document_free(good);
562
+ /* the issue's instance: missing title, out-of-model isbn */
563
+ const char* bad_x =
564
+ "<book><author/><author/><isbn>9</isbn></book>";
565
+ LeptrisDocument bad = leptris_parse_string(bad_x, strlen(bad_x), &st);
566
+ ASSERT_NE(bad, nullptr);
567
+ EXPECT_EQ(leptris_xsd_validate(s, bad), 0);
568
+ EXPECT_GE(leptris_xsd_error_count(s), 1u);
569
+ leptris_document_free(bad);
570
+ leptris_xsd_free(s);
571
+ }
572
+
573
+ TEST(XsdDatatypes, AnonymousInlineSimpleTypeOnParticle) {
574
+ LeptrisStatus st = LEPTRIS_OK;
575
+ const char* xsd =
576
+ "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">"
577
+ "<xs:complexType name=\"t\">"
578
+ "<xs:sequence>"
579
+ "<xs:element name=\"score\">"
580
+ "<xs:simpleType>"
581
+ "<xs:restriction base=\"xs:integer\">"
582
+ "<xs:minInclusive value=\"1\"/>"
583
+ "</xs:restriction>"
584
+ "</xs:simpleType>"
585
+ "</xs:element>"
586
+ "</xs:sequence></xs:complexType>"
587
+ "<xs:element name=\"game\" type=\"t\"/>"
588
+ "</xs:schema>";
589
+ LeptrisXsdSchema s = leptris_xsd_compile(xsd, strlen(xsd), &st);
590
+ ASSERT_NE(s, (LeptrisXsdSchema)0);
591
+ const char* good_x = "<game><score>9</score></game>";
592
+ LeptrisDocument good = leptris_parse_string(good_x, strlen(good_x), &st);
593
+ ASSERT_NE(good, nullptr);
594
+ EXPECT_EQ(leptris_xsd_validate(s, good), 1);
595
+ leptris_document_free(good);
596
+ const char* bad_x = "<game><score>0</score></game>";
597
+ LeptrisDocument bad = leptris_parse_string(bad_x, strlen(bad_x), &st);
598
+ ASSERT_NE(bad, nullptr);
599
+ EXPECT_EQ(leptris_xsd_validate(s, bad), 0);
600
+ leptris_document_free(bad);
601
+ /* the synthesized slot resolves directly too */
602
+ EXPECT_EQ(leptris_xsd_simple_valid(s, "element:score", "9"), 1);
603
+ EXPECT_EQ(leptris_xsd_simple_valid(s, "element:score", "0"), 0);
604
+ leptris_xsd_free(s);
605
+ }
606
+
607
+ } // namespace
@@ -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.322",
4
+ "version": "1.9.323",
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.322.0
4
+ version: 1.9.323.0
5
5
  platform: aarch64-linux
6
6
  authors:
7
7
  - Ribose Inc.