leptris 1.9.321.0-arm-linux → 1.9.323.0-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 +4 -4
- data/CHANGELOG.md +25 -0
- data/Rakefile +1 -1
- data/lib/leptris/version.rb +1 -1
- data/lib/leptris/xml/document.rb +5 -0
- data/lib/leptris/xml/element.rb +8 -0
- data/lib/libleptris.so +0 -0
- data/vendor-src/README.md +1 -1
- data/vendor-src/libleptris/CHANGELOG.md +30 -0
- data/vendor-src/libleptris/CMakeLists.txt +1 -1
- data/vendor-src/libleptris/cli/commands/validate.c +45 -3
- data/vendor-src/libleptris/src/leptris/xsd/compile.c +85 -6
- data/vendor-src/libleptris/test/cli/test_cli.cpp +34 -0
- data/vendor-src/libleptris/test/xsd/test_xsd_compile.cpp +88 -0
- data/vendor-src/libleptris/vcpkg.json +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: aec88add4bec210848479baab87f427800225cf3a8ae53bfe1bc78fa1156f48b
|
|
4
|
+
data.tar.gz: 8cca45b53702a981798c18a430b605444f96ecc976a59cf857b39868ef188615
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 901cb861c4aa4b6bce67397ce950042b07aa9f31b96e3929ed35869d61d39a6fc1d0ceab90ea550c37de35505cc8d63b243ac49593a770fa5f089e1f59735e4d
|
|
7
|
+
data.tar.gz: 70929559a5da15afc24e4770097c5fb8bdc765b11d7c0dfb6840b645a89062dd25b4b66366fa0fdf50d72d813b1454f3e9ecb9345d915c5df919c58450ffac19
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,28 @@
|
|
|
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
|
+
|
|
15
|
+
## [1.9.322.0] - 2026-10-08
|
|
16
|
+
|
|
17
|
+
### Engine sync (libleptris 1.9.322)
|
|
18
|
+
|
|
19
|
+
- `leptris validate --xsd FILE` rides the CLI's validate command
|
|
20
|
+
(compile error detail, every accumulated instance error,
|
|
21
|
+
non-zero exit) — CLI-only, no binding surface; audit 381/380
|
|
22
|
+
unchanged. The inline-anonymous complexType capture fix
|
|
23
|
+
(leptris#1592, engine PR #1596) merged after this tag and ships
|
|
24
|
+
with the engine's next release — the binding pin follows there.
|
|
25
|
+
|
|
1
26
|
## [1.9.321.0] - 2026-10-08
|
|
2
27
|
|
|
3
28
|
### Added — engine sync (libleptris 1.9.321)
|
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.
|
|
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
|
data/lib/leptris/version.rb
CHANGED
data/lib/leptris/xml/document.rb
CHANGED
|
@@ -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
|
|
data/lib/leptris/xml/element.rb
CHANGED
|
@@ -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,5 +1,35 @@
|
|
|
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
|
+
|
|
20
|
+
## [1.9.322] - 2026-10-08
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
- **`leptris validate --xsd FILE` (#1075, PR #1593).** The compiled
|
|
25
|
+
XSD surface rides the same validate command as `--dtd`/`--rng`/
|
|
26
|
+
`--schematron`: compile failures report the schema's own error
|
|
27
|
+
detail (compile returns error-carrying handles — the status keys
|
|
28
|
+
the failure); invalid documents print every accumulated error and
|
|
29
|
+
exit non-zero.
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
3
33
|
## [1.9.321] - 2026-10-08
|
|
4
34
|
|
|
5
35
|
### Added
|
|
@@ -156,6 +156,7 @@ static int run_schematron(const char* path, const char* phase,
|
|
|
156
156
|
|
|
157
157
|
static cli_result_t validate_execute(int argc, char** argv) {
|
|
158
158
|
const char* rng_path = NULL;
|
|
159
|
+
const char* xsd_path = NULL;
|
|
159
160
|
const char* sch_path = NULL;
|
|
160
161
|
const char* dtd_path = NULL;
|
|
161
162
|
const char* phase = NULL;
|
|
@@ -164,6 +165,8 @@ static cli_result_t validate_execute(int argc, char** argv) {
|
|
|
164
165
|
for (int i = 1; i < argc; i++) {
|
|
165
166
|
if (strcmp(argv[i], "--rng") == 0 && i + 1 < argc) {
|
|
166
167
|
rng_path = argv[++i];
|
|
168
|
+
} else if (strcmp(argv[i], "--xsd") == 0 && i + 1 < argc) {
|
|
169
|
+
xsd_path = argv[++i];
|
|
167
170
|
} else if ((strcmp(argv[i], "--schematron") == 0 ||
|
|
168
171
|
strcmp(argv[i], "-s") == 0) &&
|
|
169
172
|
i + 1 < argc) {
|
|
@@ -184,6 +187,7 @@ static cli_result_t validate_execute(int argc, char** argv) {
|
|
|
184
187
|
printf("Options:\n");
|
|
185
188
|
printf(" --dtd FILE External DTD\n");
|
|
186
189
|
printf(" --rng FILE RELAX NG schema\n");
|
|
190
|
+
printf(" --xsd FILE W3C XML Schema (XSD)\n");
|
|
187
191
|
printf(" --schematron FILE ISO Schematron schema\n");
|
|
188
192
|
printf(" --phase ID Schematron phase to");
|
|
189
193
|
printf(" select\n");
|
|
@@ -205,8 +209,8 @@ static cli_result_t validate_execute(int argc, char** argv) {
|
|
|
205
209
|
cli_error("validate requires an XML document");
|
|
206
210
|
return CLI_ERROR_ARGS;
|
|
207
211
|
}
|
|
208
|
-
if (!rng_path && !sch_path && !dtd_path) {
|
|
209
|
-
cli_error("validate needs --dtd
|
|
212
|
+
if (!rng_path && !sch_path && !dtd_path && !xsd_path) {
|
|
213
|
+
cli_error("validate needs --dtd/--rng/--schematron/--xsd");
|
|
210
214
|
return CLI_ERROR_ARGS;
|
|
211
215
|
}
|
|
212
216
|
LeptrisDocument doc = read_doc(xml_path);
|
|
@@ -261,6 +265,43 @@ static cli_result_t validate_execute(int argc, char** argv) {
|
|
|
261
265
|
}
|
|
262
266
|
leptris_rng_free(rng);
|
|
263
267
|
}
|
|
268
|
+
if (xsd_path) {
|
|
269
|
+
size_t xsd_len = 0;
|
|
270
|
+
char* xsd_content = read_file(xsd_path, &xsd_len);
|
|
271
|
+
if (!xsd_content) {
|
|
272
|
+
cli_error("cannot read XSD: %s", xsd_path);
|
|
273
|
+
leptris_document_free(doc);
|
|
274
|
+
return CLI_ERROR_IO;
|
|
275
|
+
}
|
|
276
|
+
LeptrisStatus st = LEPTRIS_OK;
|
|
277
|
+
LeptrisXsdSchema xsd =
|
|
278
|
+
leptris_xsd_compile(xsd_content, xsd_len, &st);
|
|
279
|
+
free(xsd_content);
|
|
280
|
+
/* compile returns an error-carrying handle on failure — the
|
|
281
|
+
* status, not the pointer, says whether it succeeded. */
|
|
282
|
+
if (st != LEPTRIS_OK) {
|
|
283
|
+
const char* detail =
|
|
284
|
+
xsd ? leptris_xsd_error(xsd)
|
|
285
|
+
: leptris_status_string(st);
|
|
286
|
+
cli_error("XSD compile failed: %s",
|
|
287
|
+
detail ? detail : leptris_status_string(st));
|
|
288
|
+
if (xsd) leptris_xsd_free(xsd);
|
|
289
|
+
leptris_document_free(doc);
|
|
290
|
+
return CLI_ERROR_IO;
|
|
291
|
+
}
|
|
292
|
+
if (leptris_xsd_validate(xsd, doc)) {
|
|
293
|
+
printf("xsd: valid\n");
|
|
294
|
+
} else {
|
|
295
|
+
printf("xsd: invalid\n");
|
|
296
|
+
size_t n = leptris_xsd_error_count(xsd);
|
|
297
|
+
for (size_t i = 0; i < n; i++) {
|
|
298
|
+
const char* e = leptris_xsd_error_at(xsd, i);
|
|
299
|
+
if (e) printf(" %s\n", e);
|
|
300
|
+
}
|
|
301
|
+
invalid = 1;
|
|
302
|
+
}
|
|
303
|
+
leptris_xsd_free(xsd);
|
|
304
|
+
}
|
|
264
305
|
if (sch_path) {
|
|
265
306
|
cli_result_t r = run_schematron(
|
|
266
307
|
sch_path, phase, want_svrl, doc, &invalid);
|
|
@@ -276,7 +317,8 @@ static cli_result_t validate_execute(int argc, char** argv) {
|
|
|
276
317
|
|
|
277
318
|
static cli_command_t validate_command = {
|
|
278
319
|
.name = "validate",
|
|
279
|
-
.description =
|
|
320
|
+
.description =
|
|
321
|
+
"Validate XML against RELAX NG / Schematron / XSD",
|
|
280
322
|
.execute = validate_execute,
|
|
281
323
|
.print_help = NULL
|
|
282
324
|
};
|
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
}
|
|
@@ -552,3 +552,37 @@ TEST(CliValidate, MissingDtdIsIoError) {
|
|
|
552
552
|
}
|
|
553
553
|
|
|
554
554
|
#endif /* !_WIN32 */
|
|
555
|
+
|
|
556
|
+
// ---- validate --xsd (#1075 slice 5) ---------------------------------
|
|
557
|
+
// The compiled XSD surface rides the same validate command as
|
|
558
|
+
// dtd/rng/schematron. Windows runners: same harness limitation as
|
|
559
|
+
// CliDiff (path + tmp semantics).
|
|
560
|
+
#ifndef _WIN32
|
|
561
|
+
TEST(CliValidateXsd, ValidDocumentExitsZero) {
|
|
562
|
+
write_file("leptris_cli_xsd.tmp",
|
|
563
|
+
"<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">"
|
|
564
|
+
"<xs:element name=\"r\" type=\"xs:integer\"/></xs:schema>");
|
|
565
|
+
auto r = run_cli({"validate", "--xsd", "leptris_cli_xsd.tmp",
|
|
566
|
+
"-"}, "<r>7</r>");
|
|
567
|
+
EXPECT_EQ(r.exit_code, 0) << "stderr: " << r.err;
|
|
568
|
+
EXPECT_NE(r.out.find("xsd: valid"), std::string::npos);
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
TEST(CliValidateXsd, InvalidDocumentReportsAndExitsNonzero) {
|
|
572
|
+
write_file("leptris_cli_xsd2.tmp",
|
|
573
|
+
"<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">"
|
|
574
|
+
"<xs:element name=\"r\" type=\"xs:integer\"/></xs:schema>");
|
|
575
|
+
auto r = run_cli({"validate", "--xsd", "leptris_cli_xsd2.tmp",
|
|
576
|
+
"-"}, "<r>nope</r>");
|
|
577
|
+
EXPECT_NE(r.exit_code, 0);
|
|
578
|
+
EXPECT_NE(r.out.find("xsd: invalid"), std::string::npos);
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
TEST(CliValidateXsd, CompileFailureIsReported) {
|
|
582
|
+
write_file("leptris_cli_xsd3.tmp", "<not-a-schema/>");
|
|
583
|
+
auto r = run_cli({"validate", "--xsd", "leptris_cli_xsd3.tmp",
|
|
584
|
+
"-"}, "<r>7</r>");
|
|
585
|
+
EXPECT_NE(r.exit_code, 0);
|
|
586
|
+
EXPECT_NE(r.err.find("XSD compile failed"), std::string::npos);
|
|
587
|
+
}
|
|
588
|
+
#endif
|
|
@@ -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.
|
|
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",
|