leptris 1.9.320.0-ppc64le-linux → 1.9.322.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 +4 -4
- data/CHANGELOG.md +28 -0
- data/Rakefile +1 -1
- data/lib/leptris/version.rb +1 -1
- data/lib/leptris/xml/ffi.rb +15 -0
- data/lib/leptris/xml/xsd.rb +58 -6
- data/lib/libleptris.so +0 -0
- data/vendor-src/README.md +1 -1
- data/vendor-src/libleptris/CHANGELOG.md +35 -0
- data/vendor-src/libleptris/CMakeLists.txt +1 -1
- data/vendor-src/libleptris/cli/commands/validate.c +45 -3
- data/vendor-src/libleptris/src/CMakeLists.txt +2 -0
- data/vendor-src/libleptris/src/include/leptris.h +22 -0
- data/vendor-src/libleptris/src/leptris/xsd/compile.c +309 -1
- data/vendor-src/libleptris/src/leptris/xsd/content_model.c +232 -0
- data/vendor-src/libleptris/src/leptris/xsd/validate.c +287 -0
- data/vendor-src/libleptris/src/leptris/xsd/xsd_internal.h +48 -0
- data/vendor-src/libleptris/test/cli/test_cli.cpp +34 -0
- data/vendor-src/libleptris/test/xsd/test_xsd_compile.cpp +253 -0
- data/vendor-src/libleptris/vcpkg.json +1 -1
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7f838f3aa92b2932ec3b32f7cf4227c70c415a84c5916f115f4f1b6811c2a913
|
|
4
|
+
data.tar.gz: fed0ebac144489410e7737113f5f0210e652113d9921cab7422fdbf182ec91e0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4f65c9924ed95bd9cc2e577982bc99d5508a89c0f5cdaa272224b5ce36973b88d2c5fd4c2e486f70e33a140fc74c57a1fbdb13f764a790044952d889c7f337ef
|
|
7
|
+
data.tar.gz: 27b270be847e3dde7c1806030f654ff0766695437ca1b32b5a5e910728f38aa1a52ecd6d65b85955f3df7aa24d9e6d67243501e5b2294b56845a58fb0e22b5e0
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,31 @@
|
|
|
1
|
+
## [1.9.322.0] - 2026-10-08
|
|
2
|
+
|
|
3
|
+
### Engine sync (libleptris 1.9.322)
|
|
4
|
+
|
|
5
|
+
- `leptris validate --xsd FILE` rides the CLI's validate command
|
|
6
|
+
(compile error detail, every accumulated instance error,
|
|
7
|
+
non-zero exit) — CLI-only, no binding surface; audit 381/380
|
|
8
|
+
unchanged. The inline-anonymous complexType capture fix
|
|
9
|
+
(leptris#1592, engine PR #1596) merged after this tag and ships
|
|
10
|
+
with the engine's next release — the binding pin follows there.
|
|
11
|
+
|
|
12
|
+
## [1.9.321.0] - 2026-10-08
|
|
13
|
+
|
|
14
|
+
### Added — engine sync (libleptris 1.9.321)
|
|
15
|
+
|
|
16
|
+
- **XSD instance validation, slices 3-4 (#1075)**:
|
|
17
|
+
`Schema#valid?` walks the whole document — element declarations,
|
|
18
|
+
attribute rows (required + typed + lenient qualified spellings),
|
|
19
|
+
text lexical checks, child content models through a Thompson NFA
|
|
20
|
+
(linear in children x states, no backtracking blowup);
|
|
21
|
+
`Schema#validate_errors` enumerates every failure (the engine
|
|
22
|
+
replaces the list per run); `Schema#content_valid?` evaluates a
|
|
23
|
+
child sequence directly against a top-level declaration's model.
|
|
24
|
+
The -1 contract raises (unknown declaration never masquerades as
|
|
25
|
+
invalid input). Pins use the named-ref shape — the inline-
|
|
26
|
+
anonymous complexType capture gap is filed upstream
|
|
27
|
+
(leptris#1592).
|
|
28
|
+
|
|
1
29
|
## [1.9.320.0] - 2026-10-08
|
|
2
30
|
|
|
3
31
|
### Fixed — engine sync (libleptris 1.9.320)
|
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.322"
|
|
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/ffi.rb
CHANGED
|
@@ -1304,6 +1304,21 @@ attach_function :leptris_parse_string,
|
|
|
1304
1304
|
[:string, :string], :int
|
|
1305
1305
|
attach_function :leptris_xsd_simple_valid,
|
|
1306
1306
|
[:leptris_xsd_schema, :string, :string], :int
|
|
1307
|
+
# Slices 3-4 (libleptris 1.9.321, #1075): content models via
|
|
1308
|
+
# Thompson NFA (linear in children x states) and whole-
|
|
1309
|
+
# instance validation — element declarations, attribute rows
|
|
1310
|
+
# (required + typed + lenient qualified spellings), text
|
|
1311
|
+
# lexical checks, child content models. Failures enumerate
|
|
1312
|
+
# behind error_count/_at (schema-owned; the next validate
|
|
1313
|
+
# run replaces them).
|
|
1314
|
+
attach_function :leptris_xsd_content_valid,
|
|
1315
|
+
[:leptris_xsd_schema, :string, :pointer, :pointer, :size_t], :int
|
|
1316
|
+
attach_function :leptris_xsd_validate,
|
|
1317
|
+
[:leptris_xsd_schema, :leptris_document], :int
|
|
1318
|
+
attach_function :leptris_xsd_error_count,
|
|
1319
|
+
[:leptris_xsd_schema], :size_t
|
|
1320
|
+
attach_function :leptris_xsd_error_at,
|
|
1321
|
+
[:leptris_xsd_schema, :size_t], UTF8_STRING
|
|
1307
1322
|
|
|
1308
1323
|
attach_function :leptris_rng_parse,
|
|
1309
1324
|
[:string, :size_t, :pointer], :leptris_relaxng
|
data/lib/leptris/xml/xsd.rb
CHANGED
|
@@ -79,14 +79,66 @@ module Leptris::XML::XSD
|
|
|
79
79
|
# name) — restriction chains validate every hop's facets,
|
|
80
80
|
# cycle-guarded. Unknown type names raise (the -1 contract).
|
|
81
81
|
def simple_valid?(type_name, lexical)
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
tri_state(
|
|
83
|
+
Leptris::XML::FFI.leptris_xsd_simple_valid(
|
|
84
|
+
@handle, type_name.to_s, lexical.to_s),
|
|
85
|
+
"#{type_name.inspect} is not a simpleType in this schema")
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Slices 3-4 (libleptris 1.9.321, #1075): whole-instance
|
|
89
|
+
# validation — element declarations, attribute rows (required
|
|
90
|
+
# + typed + lenient qualified spellings), text lexical checks,
|
|
91
|
+
# and child content models through the Thompson NFA. Returns
|
|
92
|
+
# true/false.
|
|
93
|
+
def valid?(document)
|
|
94
|
+
tri_state(
|
|
95
|
+
Leptris::XML::FFI.leptris_xsd_validate(
|
|
96
|
+
@handle, document.c_ptr), "invalid document handle")
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# The enumerated failure list of the last #validate run
|
|
100
|
+
# (empty when valid; the NEXT validate replaces the list).
|
|
101
|
+
def validate_errors(document)
|
|
102
|
+
valid?(document)
|
|
103
|
+
Leptris::XML::FFI.leptris_xsd_error_count(@handle).times.map do |i|
|
|
104
|
+
Leptris::XML::FFI.leptris_xsd_error_at(@handle, i)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Slice 3 direct face: a child SEQUENCE against a top-level
|
|
109
|
+
# element declaration's compiled content model (occurrence
|
|
110
|
+
# bounds, xs:any wildcards). +children+ are child Nodes (name
|
|
111
|
+
# + effective namespace extracted per child). Unknown element
|
|
112
|
+
# declarations raise (the -1 contract).
|
|
113
|
+
def content_valid?(element_name, children)
|
|
114
|
+
kids = children.to_a
|
|
115
|
+
nb, na = Leptris::XML::CStringArray.to_c(
|
|
116
|
+
kids.map { |c| c.name.to_s })
|
|
117
|
+
ub, ua = Leptris::XML::CStringArray.to_c(
|
|
118
|
+
kids.map { |c| child_ns_uri(c) })
|
|
119
|
+
tri_state(
|
|
120
|
+
Leptris::XML::FFI.leptris_xsd_content_valid(
|
|
121
|
+
@handle, element_name.to_s, nb, ub, kids.size),
|
|
122
|
+
"#{element_name.inspect} is not a top-level element declaration")
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
private
|
|
126
|
+
|
|
127
|
+
# A child's effective namespace URI (nil = none) — read
|
|
128
|
+
# through its own c_ptr, so docless wrappers work.
|
|
129
|
+
def child_ns_uri(node)
|
|
130
|
+
uri = Leptris::XML::FFI.leptris_element_namespace(node.c_ptr)
|
|
131
|
+
uri.nil? || uri.empty? ? "" : uri
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# The C faces' 1/0/-1 contract: true/false, with -1 raising —
|
|
135
|
+
# a silent false would mean "no such declaration/type", which
|
|
136
|
+
# callers must never confuse with "invalid input".
|
|
137
|
+
def tri_state(code, unknown_message)
|
|
138
|
+
case code
|
|
85
139
|
when 1 then true
|
|
86
140
|
when 0 then false
|
|
87
|
-
else
|
|
88
|
-
raise ArgumentError,
|
|
89
|
-
"#{type_name.inspect} is not a simpleType in this schema"
|
|
141
|
+
else raise ArgumentError, unknown_message
|
|
90
142
|
end
|
|
91
143
|
end
|
|
92
144
|
end
|
data/lib/libleptris.so
CHANGED
|
Binary file
|
data/vendor-src/README.md
CHANGED
|
@@ -1,5 +1,40 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [1.9.322] - 2026-10-08
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **`leptris validate --xsd FILE` (#1075, PR #1593).** The compiled
|
|
8
|
+
XSD surface rides the same validate command as `--dtd`/`--rng`/
|
|
9
|
+
`--schematron`: compile failures report the schema's own error
|
|
10
|
+
detail (compile returns error-carrying handles — the status keys
|
|
11
|
+
the failure); invalid documents print every accumulated error and
|
|
12
|
+
exit non-zero.
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
## [1.9.321] - 2026-10-08
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- **XSD validation, tier 1, slices 3–4 (#1075, PRs #1589/#1590).**
|
|
21
|
+
Slice 3 — content models: the compiler captures top-level
|
|
22
|
+
`xs:element` declarations and named `xs:complexType` models
|
|
23
|
+
(sequence/choice/all, occurrence bounds incl. unbounded, element
|
|
24
|
+
name/ref particles, `xs:any` wildcards with the full
|
|
25
|
+
namespace-filter grammar); `leptris_xsd_content_valid` evaluates
|
|
26
|
+
a child sequence through a Thompson NFA — linear in children x
|
|
27
|
+
states, no backtracking blowup on nested choices. Slice 4 —
|
|
28
|
+
instance validation: `leptris_xsd_validate(schema, document)`
|
|
29
|
+
walks element declarations, complexType attribute rows
|
|
30
|
+
(required + typed + lenient qualified spellings), child content
|
|
31
|
+
models, and lexical text checks for simple-typed elements
|
|
32
|
+
(particles carry type refs); failures enumerate behind
|
|
33
|
+
`leptris_xsd_error_count/_at`. The libxml2 corpus gate holds at
|
|
34
|
+
163/163; full suite 1911/1911.
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
3
38
|
## [1.9.320] - 2026-10-08
|
|
4
39
|
|
|
5
40
|
### Fixed
|
|
@@ -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
|
};
|
|
@@ -920,6 +920,28 @@ LEPTRIS_API int leptris_xsd_builtin_valid(const char* builtin,
|
|
|
920
920
|
LEPTRIS_API int leptris_xsd_simple_valid(LeptrisXsdSchema schema,
|
|
921
921
|
const char* type_name,
|
|
922
922
|
const char* lexical);
|
|
923
|
+
/* Slice 3 — content models. Validates a child sequence against the
|
|
924
|
+
* compiled content model of a top-level element declaration (its
|
|
925
|
+
* type's sequence/choice/all with occurrence bounds and xs:any
|
|
926
|
+
* wildcards). 1 valid, 0 invalid, -1 unknown element. child_ns may
|
|
927
|
+
* be NULL (all children unqualified). */
|
|
928
|
+
LEPTRIS_API int leptris_xsd_content_valid(
|
|
929
|
+
LeptrisXsdSchema schema, const char* element_name,
|
|
930
|
+
const char* const* child_names, const char* const* child_ns,
|
|
931
|
+
size_t child_count);
|
|
932
|
+
/* Slice 4 — instance validation. Walks the document against the
|
|
933
|
+
* compiled schema: element declarations by name, attribute rows
|
|
934
|
+
* (required use + typed values, lenient qualified spellings),
|
|
935
|
+
* text lexical checks for simple-typed elements, child content
|
|
936
|
+
* models (slice 3). Returns 1 valid, 0 invalid, -1 bad args.
|
|
937
|
+
* Errors accumulate — leptris_xsd_error_count/_at enumerate them
|
|
938
|
+
* (schema-owned; the next validate run replaces them; freed with
|
|
939
|
+
* the schema). */
|
|
940
|
+
LEPTRIS_API int leptris_xsd_validate(LeptrisXsdSchema schema,
|
|
941
|
+
LeptrisDocument doc);
|
|
942
|
+
LEPTRIS_API size_t leptris_xsd_error_count(LeptrisXsdSchema schema);
|
|
943
|
+
LEPTRIS_API const char* leptris_xsd_error_at(LeptrisXsdSchema schema,
|
|
944
|
+
size_t i);
|
|
923
945
|
/* Validate an instance document against the parsed schema
|
|
924
946
|
* (phase-2 core subset: element/attribute/text/data/value/
|
|
925
947
|
* choice/group/interleave/repeats/ref). Returns 1 valid; on 0,
|