leptris 1.9.391.0-arm-linux → 1.9.394.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/Rakefile +1 -1
- data/lib/leptris/version.rb +1 -1
- data/lib/libleptris.so +0 -0
- data/vendor-src/README.md +1 -1
- data/vendor-src/libleptris/CHANGELOG.md +77 -0
- data/vendor-src/libleptris/CMakeLists.txt +1 -1
- data/vendor-src/libleptris/README.adoc +37 -0
- data/vendor-src/libleptris/src/include/leptris/types.h +52 -0
- data/vendor-src/libleptris/src/include/leptris.h +6 -0
- data/vendor-src/libleptris/src/leptris/core.c +31 -0
- data/vendor-src/libleptris/src/leptris/xpath/parser.c +11 -29
- data/vendor-src/libleptris/src/leptris/xsd/compile.c +50 -6
- data/vendor-src/libleptris/test/CMakeLists.txt +17 -0
- data/vendor-src/libleptris/test/abi/test_capabilities.cpp +112 -0
- data/vendor-src/libleptris/test/dom/test_entity_refs.cpp +111 -0
- data/vendor-src/libleptris/test/xsd/test_xsd_compile.cpp +116 -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: 7d54a035a2117bdcf391aadc439d6abaae328513de9caa797272c9f0c8acd8d4
|
|
4
|
+
data.tar.gz: c2b64f137218af348ff014653d67378f43440ed567a5339b1b1416e034e50b9e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 38e714a4e0b0390991ede4bb39ebc2c1a9ecffadd9531f3dfcea56ef702618c7c0e0a68b7b546e49abe3a280f82c35b799ee718be28b3086c04e00a10d2174ca
|
|
7
|
+
data.tar.gz: c48a24d36612528bf8c855cc4841c1a56085ba293b12c7cfaa1a1a6807622dae0ec6a24e1ad9d12e0dfef33598ac0e4380afe01fa188c02b082d2c724c83cb63
|
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.394"
|
|
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/libleptris.so
CHANGED
|
Binary file
|
data/vendor-src/README.md
CHANGED
|
@@ -1,5 +1,82 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [1.9.394] - 2026-10-30
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- **xs:override loads its base and replaces the overridden components
|
|
8
|
+
(leptris#1913, PR #1917).** `override` was absent from the
|
|
9
|
+
declaration gate and the include-family chase, so the base document
|
|
10
|
+
never loaded and the override body's nested declarations were never
|
|
11
|
+
captured — the compiled schema had an empty symbol space (decls=0,
|
|
12
|
+
every instance element "not declared"). Override now chases its
|
|
13
|
+
schemaLocation like include (same targetNamespace), then captures
|
|
14
|
+
its own declaration children as a pseudo-root AFTER the base so the
|
|
15
|
+
head-first lookup ladder sees the replacements; the attributeGroup
|
|
16
|
+
pre-pass honors a capture-force flag in that body, and the ref-check
|
|
17
|
+
declaration collector walks the override body too. Witness: base
|
|
18
|
+
`Doc` replaced by the override's `Doc` — `<doc><b>1</b></doc>`
|
|
19
|
+
validates, `<doc><a>x</a></doc>` is rejected.
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
## [1.9.393] - 2026-10-30
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
- **Capability bit for entity-reference nodes (leptris#1904, PR #1915).**
|
|
28
|
+
`LEPTRIS_PARSE_KEEP_ENTITY_REFS` already parses references as
|
|
29
|
+
first-class `LEPTRIS_NODE_TYPE_ENTITY_REF` nodes — text segments
|
|
30
|
+
split around the five built-ins and custom named references
|
|
31
|
+
(numeric character references stay text, XML 1.0 §4.1) — but
|
|
32
|
+
nothing advertised it. `LEPTRIS_CAP_ENTITY_REF_NODES` lets a
|
|
33
|
+
binding probe once and parse with the flag instead of re-scanning
|
|
34
|
+
expanded text; a spec pins the DOM shape and the
|
|
35
|
+
string-value / serialization / XPath agreement.
|
|
36
|
+
|
|
37
|
+
### Fixed
|
|
38
|
+
|
|
39
|
+
- **XSD 1.1 was inert for every `vc:minVersion`-marked schema
|
|
40
|
+
(leptris#1910, leptris#1911, PR #1914).** The version detector
|
|
41
|
+
read only the root's plain `version` attribute; the W3C suite and
|
|
42
|
+
the binding ecosystem mark 1.1 with `vc:minVersion` in the
|
|
43
|
+
versioning namespace. With the capture gates off,
|
|
44
|
+
`xs:alternative` and `xs:assert` compiled to nothing —
|
|
45
|
+
conditional type assignment applied the declared base type's
|
|
46
|
+
model in both directions (false rejects and false accepts), and
|
|
47
|
+
asserts never attached to their types. The detector now honors
|
|
48
|
+
`version`, `vc:minVersion`, and a `vc:maxVersion="1.0"` pin, and
|
|
49
|
+
`xs:openContent` interleave/suffix semantics engage with it
|
|
50
|
+
(leptris#1912's repro validates clean).
|
|
51
|
+
- **Value-comparison keywords accept name-test operands
|
|
52
|
+
(`w le h`).** The XPath `eq/ne/lt/le/gt/ge` operators only read
|
|
53
|
+
as operators when the right operand opened with a scalar, paren,
|
|
54
|
+
variable, or function call — an `xs:assert test="w le h"` failed
|
|
55
|
+
to compile. Adjacent name tokens are never a valid path
|
|
56
|
+
continuation, so a bare name-test follower is unambiguously an
|
|
57
|
+
operand; every path start is now admitted.
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
## [1.9.392] - 2026-10-30
|
|
62
|
+
|
|
63
|
+
### Added
|
|
64
|
+
|
|
65
|
+
- **Capability descriptor face (leptris#1905, PR #1908).**
|
|
66
|
+
`leptris_capabilities()` returns a versioned bitset of every face
|
|
67
|
+
this installed engine serves — the engine-side half of the
|
|
68
|
+
moxml#504 capability report. Bindings OR it with their own wrapper
|
|
69
|
+
knowledge instead of maintaining scattered version-gate
|
|
70
|
+
constants; build-conditional faces (DUCET collation, utf8proc,
|
|
71
|
+
iconv, AVX2) follow the same `LEPTRIS_HAS_*` macros that gate the
|
|
72
|
+
sources, so the descriptor cannot drift from the binary it ships
|
|
73
|
+
in. Contract: bits append, never reorder; the descriptor version
|
|
74
|
+
gates shape changes. The spec anchors every unconditional bit to
|
|
75
|
+
its real face symbol — a bit without a linked face fails the
|
|
76
|
+
build, not the assertion.
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
|
|
3
80
|
## [1.9.391] - 2026-10-30
|
|
4
81
|
|
|
5
82
|
### Fixed
|
|
@@ -744,6 +744,43 @@ To pin enum values (bindings hard-code these):
|
|
|
744
744
|
ctest --test-dir build -R HeaderHygiene
|
|
745
745
|
----
|
|
746
746
|
|
|
747
|
+
=== Capability descriptor (one call: what does this engine serve?)
|
|
748
|
+
|
|
749
|
+
Bindings and embedders stop maintaining scattered version-gate
|
|
750
|
+
constants: one call returns a versioned bitset of every face this
|
|
751
|
+
installed engine serves. Build-conditional faces (Unicode
|
|
752
|
+
normalization, iconv, DUCET collation, AVX2) answer honestly for the
|
|
753
|
+
exact library you linked. New capabilities APPEND bits — the
|
|
754
|
+
descriptor version gates shape changes.
|
|
755
|
+
|
|
756
|
+
[source,c]
|
|
757
|
+
----
|
|
758
|
+
LeptrisCapabilities c = leptris_capabilities();
|
|
759
|
+
if (c.descriptor_version >= 1 && (c.caps & LEPTRIS_CAP_XSD)) {
|
|
760
|
+
/* xsd compile/validate faces are present */
|
|
761
|
+
}
|
|
762
|
+
----
|
|
763
|
+
|
|
764
|
+
Entity references: parsing with `LEPTRIS_PARSE_KEEP_ENTITY_REFS`
|
|
765
|
+
yields `LEPTRIS_NODE_TYPE_ENTITY_REF` nodes instead of pre-expanded
|
|
766
|
+
text — segments split around the five built-ins and custom named
|
|
767
|
+
references (numeric character references stay text, per XML 1.0
|
|
768
|
+
§4.1). String-value, serialization, and XPath all see the expanded
|
|
769
|
+
value. Probe `LEPTRIS_CAP_ENTITY_REF_NODES` before relying on the
|
|
770
|
+
mode.
|
|
771
|
+
|
|
772
|
+
The bits: `LEPTRIS_CAP_PARSE`, `LEPTRIS_CAP_DOM`, `LEPTRIS_CAP_XPATH`,
|
|
773
|
+
`LEPTRIS_CAP_XQUERY`, `LEPTRIS_CAP_DTD`, `LEPTRIS_CAP_SAX`,
|
|
774
|
+
`LEPTRIS_CAP_HTML`, `LEPTRIS_CAP_XINCLUDE`, `LEPTRIS_CAP_DIFF`,
|
|
775
|
+
`LEPTRIS_CAP_DIGEST`, `LEPTRIS_CAP_XSD`, `LEPTRIS_CAP_XSD_SET`,
|
|
776
|
+
`LEPTRIS_CAP_RELAXNG`, `LEPTRIS_CAP_SCHEMATRON`, `LEPTRIS_CAP_XSLT`,
|
|
777
|
+
`LEPTRIS_CAP_DESCRIPTOR`, `LEPTRIS_CAP_NS_SNAPSHOT_BULK`,
|
|
778
|
+
`LEPTRIS_CAP_CHILDREN_BATCH`, `LEPTRIS_CAP_NAME_COMPARE`,
|
|
779
|
+
`LEPTRIS_CAP_VERSION`, and the build-conditional
|
|
780
|
+
`LEPTRIS_CAP_COLLATION_DUCET`, `LEPTRIS_CAP_UNICODE_UTF8PROC`,
|
|
781
|
+
`LEPTRIS_CAP_ENCODING_ICONV`, `LEPTRIS_CAP_SIMD_AVX2`,
|
|
782
|
+
`LEPTRIS_CAP_ENTITY_REF_NODES`.
|
|
783
|
+
|
|
747
784
|
[#FFI]
|
|
748
785
|
== FFI design
|
|
749
786
|
|
|
@@ -447,6 +447,58 @@ typedef struct leptris_xpath_compiled* LeptrisXPathCompiled;
|
|
|
447
447
|
* compiled — apply it to any number of documents, from any threads. */
|
|
448
448
|
typedef struct leptris_xslt* LeptrisXslt;
|
|
449
449
|
|
|
450
|
+
/* ============================================================================
|
|
451
|
+
* Capability Descriptor (leptris#1905)
|
|
452
|
+
* ============================================================================ */
|
|
453
|
+
|
|
454
|
+
/* What this INSTALLED engine serves — one call, one versioned
|
|
455
|
+
* bitset. Contract: new capabilities APPEND bits; a bit is never
|
|
456
|
+
* removed, repurposed, or reordered — that is a descriptor-version
|
|
457
|
+
* bump. Build-conditional faces (utf8proc/iconv/DUCET/AVX2) answer
|
|
458
|
+
* honestly for the exact library a consumer linked. Bindings OR
|
|
459
|
+
* this with their own wrapper knowledge; consumers stop maintaining
|
|
460
|
+
* scattered version-gate constants. */
|
|
461
|
+
enum {
|
|
462
|
+
LEPTRIS_CAP_PARSE = 1ULL << 0,
|
|
463
|
+
LEPTRIS_CAP_DOM = 1ULL << 1,
|
|
464
|
+
LEPTRIS_CAP_XPATH = 1ULL << 2,
|
|
465
|
+
LEPTRIS_CAP_XQUERY = 1ULL << 3,
|
|
466
|
+
LEPTRIS_CAP_DTD = 1ULL << 4,
|
|
467
|
+
LEPTRIS_CAP_SAX = 1ULL << 5,
|
|
468
|
+
LEPTRIS_CAP_HTML = 1ULL << 6,
|
|
469
|
+
LEPTRIS_CAP_XINCLUDE = 1ULL << 7,
|
|
470
|
+
LEPTRIS_CAP_DIFF = 1ULL << 8,
|
|
471
|
+
LEPTRIS_CAP_DIGEST = 1ULL << 9,
|
|
472
|
+
LEPTRIS_CAP_XSD = 1ULL << 10,
|
|
473
|
+
LEPTRIS_CAP_XSD_SET = 1ULL << 11,
|
|
474
|
+
LEPTRIS_CAP_RELAXNG = 1ULL << 12,
|
|
475
|
+
LEPTRIS_CAP_SCHEMATRON = 1ULL << 13,
|
|
476
|
+
LEPTRIS_CAP_XSLT = 1ULL << 14,
|
|
477
|
+
LEPTRIS_CAP_DESCRIPTOR = 1ULL << 15,
|
|
478
|
+
LEPTRIS_CAP_NS_SNAPSHOT_BULK = 1ULL << 16,
|
|
479
|
+
LEPTRIS_CAP_CHILDREN_BATCH = 1ULL << 17,
|
|
480
|
+
LEPTRIS_CAP_NAME_COMPARE = 1ULL << 18,
|
|
481
|
+
LEPTRIS_CAP_VERSION = 1ULL << 19,
|
|
482
|
+
/* build-conditional */
|
|
483
|
+
LEPTRIS_CAP_COLLATION_DUCET = 1ULL << 20,
|
|
484
|
+
LEPTRIS_CAP_UNICODE_UTF8PROC = 1ULL << 21,
|
|
485
|
+
LEPTRIS_CAP_ENCODING_ICONV = 1ULL << 22,
|
|
486
|
+
LEPTRIS_CAP_SIMD_AVX2 = 1ULL << 23,
|
|
487
|
+
/* LEPTRIS_PARSE_KEEP_ENTITY_REFS yields entity references as
|
|
488
|
+
* first-class ENTITY_REF nodes (segments split around the five
|
|
489
|
+
* built-ins and custom named references; leptris#1904). */
|
|
490
|
+
LEPTRIS_CAP_ENTITY_REF_NODES = 1ULL << 24
|
|
491
|
+
};
|
|
492
|
+
|
|
493
|
+
/* Descriptor shape version: 1. Bump when the STRUCT changes or a
|
|
494
|
+
* bit is retired (never expected — bits append). */
|
|
495
|
+
#define LEPTRIS_CAPS_DESCRIPTOR_VERSION 1u
|
|
496
|
+
|
|
497
|
+
typedef struct leptris_capabilities {
|
|
498
|
+
unsigned long long caps;
|
|
499
|
+
unsigned descriptor_version;
|
|
500
|
+
} LeptrisCapabilities;
|
|
501
|
+
|
|
450
502
|
/* ============================================================================
|
|
451
503
|
* Memory Allocation Function Types
|
|
452
504
|
* ============================================================================ */
|
|
@@ -4230,6 +4230,12 @@ LEPTRIS_API const char* leptris_version(void);
|
|
|
4230
4230
|
*/
|
|
4231
4231
|
LEPTRIS_API void leptris_version_components(int* major, int* minor, int* patch);
|
|
4232
4232
|
|
|
4233
|
+
/* leptris#1905: the capability descriptor — what this installed
|
|
4234
|
+
* engine serves, as a versioned bitset (LEPTRIS_CAP_*). Query once
|
|
4235
|
+
* at attach; new capabilities append bits (the descriptor version
|
|
4236
|
+
* gates shape changes). Thread-safe: pure, allocation-free. */
|
|
4237
|
+
LEPTRIS_API LeptrisCapabilities leptris_capabilities(void);
|
|
4238
|
+
|
|
4233
4239
|
/**
|
|
4234
4240
|
* Release this thread's libleptris caches
|
|
4235
4241
|
*
|
|
@@ -72,6 +72,37 @@ LEPTRIS_API void leptris_version_components(int* major, int* minor, int* patch)
|
|
|
72
72
|
if (patch) *patch = LEPTRIS_VERSION_PATCH;
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
+
/* leptris#1905: the capability descriptor. Unconditional faces are
|
|
76
|
+
* always compiled into this library; the build-conditional bits
|
|
77
|
+
* follow the same macros the build system defines for the sources
|
|
78
|
+
* — the descriptor cannot drift from the binary it ships in. */
|
|
79
|
+
LEPTRIS_API LeptrisCapabilities leptris_capabilities(void) {
|
|
80
|
+
LeptrisCapabilities c;
|
|
81
|
+
c.caps = LEPTRIS_CAP_PARSE | LEPTRIS_CAP_DOM | LEPTRIS_CAP_XPATH |
|
|
82
|
+
LEPTRIS_CAP_XQUERY | LEPTRIS_CAP_DTD | LEPTRIS_CAP_SAX |
|
|
83
|
+
LEPTRIS_CAP_HTML | LEPTRIS_CAP_XINCLUDE | LEPTRIS_CAP_DIFF |
|
|
84
|
+
LEPTRIS_CAP_DIGEST | LEPTRIS_CAP_XSD | LEPTRIS_CAP_XSD_SET |
|
|
85
|
+
LEPTRIS_CAP_RELAXNG | LEPTRIS_CAP_SCHEMATRON |
|
|
86
|
+
LEPTRIS_CAP_XSLT | LEPTRIS_CAP_DESCRIPTOR |
|
|
87
|
+
LEPTRIS_CAP_NS_SNAPSHOT_BULK | LEPTRIS_CAP_CHILDREN_BATCH |
|
|
88
|
+
LEPTRIS_CAP_NAME_COMPARE | LEPTRIS_CAP_VERSION |
|
|
89
|
+
LEPTRIS_CAP_ENTITY_REF_NODES;
|
|
90
|
+
#if defined(LEPTRIS_HAS_DUCET)
|
|
91
|
+
c.caps |= LEPTRIS_CAP_COLLATION_DUCET;
|
|
92
|
+
#endif
|
|
93
|
+
#if defined(LEPTRIS_HAS_UTF8PROC)
|
|
94
|
+
c.caps |= LEPTRIS_CAP_UNICODE_UTF8PROC;
|
|
95
|
+
#endif
|
|
96
|
+
#if defined(LEPTRIS_HAS_ICONV)
|
|
97
|
+
c.caps |= LEPTRIS_CAP_ENCODING_ICONV;
|
|
98
|
+
#endif
|
|
99
|
+
#if defined(LEPTRIS_HAS_AVX2_BUILD)
|
|
100
|
+
c.caps |= LEPTRIS_CAP_SIMD_AVX2;
|
|
101
|
+
#endif
|
|
102
|
+
c.descriptor_version = LEPTRIS_CAPS_DESCRIPTOR_VERSION;
|
|
103
|
+
return c;
|
|
104
|
+
}
|
|
105
|
+
|
|
75
106
|
LEPTRIS_API void leptris_thread_cleanup(void) {
|
|
76
107
|
leptris_xpath_drain_thread_caches();
|
|
77
108
|
leptris_root_doc_drain_thread_caches();
|
|
@@ -643,44 +643,26 @@ static XPathASTNode* parse_string_concat_expr(XPathParser* parser) {
|
|
|
643
643
|
}
|
|
644
644
|
|
|
645
645
|
/* True when the token AFTER a bare value-comparison keyword may
|
|
646
|
-
* START an operand.
|
|
647
|
-
*
|
|
648
|
-
*
|
|
646
|
+
* START an operand. Scalars, parens, variables, and (leptris#1910)
|
|
647
|
+
* every path start: a bare NCName/QName is an element name test in
|
|
648
|
+
* operand position, and adjacent name tokens are never a valid
|
|
649
|
+
* path continuation, so the keyword reading is unambiguous
|
|
650
|
+
* (`w le h` in xs:assert/xs:alternative tests). */
|
|
649
651
|
static int kw_operand_boundary(XPathParser* parser, XPathToken* nx) {
|
|
652
|
+
(void)parser;
|
|
650
653
|
if (!nx) return 1;
|
|
651
654
|
switch (nx->type) {
|
|
652
655
|
case TOK_EOF: case TOK_RPAREN: case TOK_COMMA:
|
|
653
656
|
case TOK_RBRACE: case TOK_LBRACE: case TOK_NUMBER:
|
|
654
657
|
case TOK_STRING: case TOK_DOLLAR: case TOK_LPAREN:
|
|
655
658
|
case TOK_MINUS: case TOK_PLUS:
|
|
659
|
+
case TOK_SLASH: case TOK_DOUBLE_SLASH: case TOK_AT:
|
|
660
|
+
case TOK_DOT: case TOK_DOUBLE_DOT: case TOK_STAR:
|
|
656
661
|
return 1;
|
|
657
662
|
case TOK_QNAME:
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
/* unprefixed call: name '(' ... prefixed call:
|
|
662
|
-
* name ':' name '(' (the QT3 corpus writes fn:year-...). */
|
|
663
|
-
XPathToken* nnx =
|
|
664
|
-
parser->token_pos + 2 < parser->token_count
|
|
665
|
-
? &parser->tokens[parser->token_pos + 2]
|
|
666
|
-
: NULL;
|
|
667
|
-
if (nnx && nnx->type == TOK_LPAREN) return 1;
|
|
668
|
-
XPathToken* t3 =
|
|
669
|
-
parser->token_pos + 3 < parser->token_count
|
|
670
|
-
? &parser->tokens[parser->token_pos + 3]
|
|
671
|
-
: NULL;
|
|
672
|
-
XPathToken* t4 =
|
|
673
|
-
parser->token_pos + 4 < parser->token_count
|
|
674
|
-
? &parser->tokens[parser->token_pos + 4]
|
|
675
|
-
: NULL;
|
|
676
|
-
XPathToken* t5 =
|
|
677
|
-
parser->token_pos + 5 < parser->token_count
|
|
678
|
-
? &parser->tokens[parser->token_pos + 5]
|
|
679
|
-
: NULL;
|
|
680
|
-
return nnx && nnx->type == TOK_COLON && t3 &&
|
|
681
|
-
t3->type == TOK_NCNAME && t4 &&
|
|
682
|
-
t4->type == TOK_LPAREN && t5;
|
|
683
|
-
}
|
|
663
|
+
case TOK_NCNAME:
|
|
664
|
+
/* name test, function call, or prefixed call */
|
|
665
|
+
return 1;
|
|
684
666
|
default:
|
|
685
667
|
return 0;
|
|
686
668
|
}
|
|
@@ -51,7 +51,11 @@ struct leptris_xsd_schema {
|
|
|
51
51
|
char* target_ns;
|
|
52
52
|
int version_11; /* xs:schema @version = "1.1" */
|
|
53
53
|
char* base_dir; /* schemaLocation resolution (file compile) */
|
|
54
|
-
int include_depth;
|
|
54
|
+
int include_depth;
|
|
55
|
+
/* xs:override body capture replaces same-named components: the
|
|
56
|
+
* attributeGroup pre-pass must re-register defs the base
|
|
57
|
+
* already captured (leptris#1913). */
|
|
58
|
+
int capture_force; /* include/import recursion guard */
|
|
55
59
|
/* leptris#1644: already-captured schema units (canonical
|
|
56
60
|
* location per entry) — the include/import DAG is dense and
|
|
57
61
|
* cyclic; without this set every DAG path re-parses and
|
|
@@ -679,7 +683,7 @@ static int xsd_is_declaration(const char* local, const char* uri) {
|
|
|
679
683
|
"element", "attribute", "simpleType", "complexType",
|
|
680
684
|
"group", "attributeGroup", "notation", "include",
|
|
681
685
|
"defaultOpenContent",
|
|
682
|
-
"import", "redefine", NULL
|
|
686
|
+
"import", "redefine", "override", NULL
|
|
683
687
|
};
|
|
684
688
|
for (int i = 0; names[i]; i++)
|
|
685
689
|
if (strcmp(local, names[i]) == 0) return 1;
|
|
@@ -1810,7 +1814,8 @@ static void xsd_collect_decls_doc(LeptrisElement root, const char* eff_tns,
|
|
|
1810
1814
|
if (!l || !u || strcmp(u, XSD_NS) != 0)
|
|
1811
1815
|
continue;
|
|
1812
1816
|
int is_inc = (strcmp(l, "include") == 0 ||
|
|
1813
|
-
strcmp(l, "redefine") == 0
|
|
1817
|
+
strcmp(l, "redefine") == 0 ||
|
|
1818
|
+
strcmp(l, "override") == 0);
|
|
1814
1819
|
int is_imp = (strcmp(l, "import") == 0);
|
|
1815
1820
|
if (!is_inc && !is_imp) continue;
|
|
1816
1821
|
const char* loc = leptris_element_attribute(c, "schemaLocation");
|
|
@@ -1853,6 +1858,13 @@ static void xsd_collect_decls_doc(LeptrisElement root, const char* eff_tns,
|
|
|
1853
1858
|
xsd_collect_decls_doc(subroot, eff, sub_base, decls, n, max,
|
|
1854
1859
|
claimed, nclaimed, cmax, depth + 1);
|
|
1855
1860
|
}
|
|
1861
|
+
/* leptris#1913: an xs:override body's declarations belong
|
|
1862
|
+
* to the symbol space too — walk the override element as a
|
|
1863
|
+
* pseudo-root (it has no include/import children of its
|
|
1864
|
+
* own). */
|
|
1865
|
+
if (strcmp(l, "override") == 0)
|
|
1866
|
+
xsd_collect_decls_doc(c, eff_tns, base_dir, decls, n, max,
|
|
1867
|
+
claimed, nclaimed, cmax, depth + 1);
|
|
1856
1868
|
leptris_document_free(sub);
|
|
1857
1869
|
}
|
|
1858
1870
|
}
|
|
@@ -1960,8 +1972,24 @@ static LeptrisXsdSchema xsd_compile_impl(const char* xsd_text,
|
|
|
1960
1972
|
s->target_ns = xsd_strdup(
|
|
1961
1973
|
leptris_element_attribute(root, "targetNamespace"));
|
|
1962
1974
|
{
|
|
1975
|
+
/* XSD 1.1 §4.3 schema versioning: the W3C suite and the
|
|
1976
|
+
* binding ecosystem mark 1.1 with vc:minVersion (the
|
|
1977
|
+
* versioning namespace); the plain version attribute is
|
|
1978
|
+
* the other legal spelling. vc:maxVersion below 1.1 pins
|
|
1979
|
+
* a 1.0 processor target regardless. leptris#1910/#1911:
|
|
1980
|
+
* reading only @version silently compiled asserts and
|
|
1981
|
+
* alternatives away for every vc-marked schema. */
|
|
1963
1982
|
const char* ver = leptris_element_attribute(root, "version");
|
|
1964
|
-
|
|
1983
|
+
const char* vmin = leptris_element_attribute_ns(
|
|
1984
|
+
root, "http://www.w3.org/2001/XMLSchema-versioning",
|
|
1985
|
+
"minVersion");
|
|
1986
|
+
const char* vmax = leptris_element_attribute_ns(
|
|
1987
|
+
root, "http://www.w3.org/2001/XMLSchema-versioning",
|
|
1988
|
+
"maxVersion");
|
|
1989
|
+
int is11 = (ver && strcmp(ver, "1.1") == 0) ||
|
|
1990
|
+
(vmin && strcmp(vmin, "1.1") == 0);
|
|
1991
|
+
if (vmax && strcmp(vmax, "1.0") == 0) is11 = 0;
|
|
1992
|
+
s->version_11 = is11;
|
|
1965
1993
|
}
|
|
1966
1994
|
|
|
1967
1995
|
const char* local = NULL;
|
|
@@ -2247,7 +2275,8 @@ static void xsd_capture_root(struct leptris_xsd_schema* s,
|
|
|
2247
2275
|
|
|
2248
2276
|
if (strcmp(local, "include") == 0 ||
|
|
2249
2277
|
strcmp(local, "import") == 0 ||
|
|
2250
|
-
strcmp(local, "redefine") == 0
|
|
2278
|
+
strcmp(local, "redefine") == 0 ||
|
|
2279
|
+
strcmp(local, "override") == 0) {
|
|
2251
2280
|
const char* loc = leptris_element_attribute(
|
|
2252
2281
|
(LeptrisElement)n, "schemaLocation");
|
|
2253
2282
|
if (loc && s->base_dir && s->include_depth < 16) {
|
|
@@ -2314,6 +2343,20 @@ static void xsd_capture_root(struct leptris_xsd_schema* s,
|
|
|
2314
2343
|
if (sub_ns) free(sub_ns);
|
|
2315
2344
|
s->target_ns = saved_ns;
|
|
2316
2345
|
}
|
|
2346
|
+
/* leptris#1913 (XSD 1.1 §I.4): the override
|
|
2347
|
+
* element's OWN declaration children
|
|
2348
|
+
* replace same-named components of the base
|
|
2349
|
+
* just captured — capture them AFTER the
|
|
2350
|
+
* base so the lookup ladder (head-first)
|
|
2351
|
+
* sees the replacements. */
|
|
2352
|
+
if (subroot && same_ns &&
|
|
2353
|
+
strcmp(local, "override") == 0) {
|
|
2354
|
+
s->include_depth++;
|
|
2355
|
+
s->capture_force = 1;
|
|
2356
|
+
xsd_capture_root(s, (LeptrisElement)n);
|
|
2357
|
+
s->capture_force = 0;
|
|
2358
|
+
s->include_depth--;
|
|
2359
|
+
}
|
|
2317
2360
|
leptris_document_free(sub);
|
|
2318
2361
|
}
|
|
2319
2362
|
free(text);
|
|
@@ -2448,7 +2491,8 @@ static void xsd_capture_root(struct leptris_xsd_schema* s,
|
|
|
2448
2491
|
XsdAttrGroupDef* seen = s->attr_groups;
|
|
2449
2492
|
for (; seen; seen = seen->next)
|
|
2450
2493
|
if (strcmp(seen->name, nm) == 0) break;
|
|
2451
|
-
if (!seen
|
|
2494
|
+
if (!seen || s->capture_force)
|
|
2495
|
+
xsd_capture_attr_group_def(s, (LeptrisElement)n, nm);
|
|
2452
2496
|
}
|
|
2453
2497
|
} else if (strcmp(local, "group") == 0 && uri && !strcmp(uri, XSD_NS)) {
|
|
2454
2498
|
const char* nm =
|
|
@@ -120,11 +120,28 @@ leptris_add_test(test_large_docs parser/test_large_documents.cpp)
|
|
|
120
120
|
leptris_add_test(test_encoding parser/test_encoding.cpp)
|
|
121
121
|
leptris_add_test(test_dom dom/test_dom.cpp)
|
|
122
122
|
leptris_add_test(test_element_children dom/test_element_children.cpp)
|
|
123
|
+
leptris_add_test(test_entity_refs dom/test_entity_refs.cpp)
|
|
123
124
|
leptris_add_test(test_namespace_cache dom/test_namespace_cache.cpp)
|
|
124
125
|
leptris_add_test(test_map_lifecycle dom/test_map_lifecycle.cpp)
|
|
125
126
|
leptris_add_test(test_simd_count parser/test_simd_count.cpp)
|
|
126
127
|
leptris_add_test(test_ws_shape parser/test_whitespace_shape.cpp)
|
|
127
128
|
leptris_add_test(test_descriptor abi/test_descriptor.cpp)
|
|
129
|
+
leptris_add_test(test_capabilities abi/test_capabilities.cpp)
|
|
130
|
+
# The capability descriptor's build-conditional bits follow the
|
|
131
|
+
# engine's PUBLIC macros, which do not flow through the object
|
|
132
|
+
# aggregation (same mirror as test_qt3 below).
|
|
133
|
+
if(LEPTRIS_ENABLE_DUCET)
|
|
134
|
+
target_compile_definitions(test_capabilities PRIVATE LEPTRIS_HAS_DUCET=1)
|
|
135
|
+
endif()
|
|
136
|
+
if(LEPTRIS_ENABLE_UTF8PROC)
|
|
137
|
+
target_compile_definitions(test_capabilities PRIVATE LEPTRIS_HAS_UTF8PROC=1)
|
|
138
|
+
endif()
|
|
139
|
+
if(LEPTRIS_ENABLE_ICONV)
|
|
140
|
+
target_compile_definitions(test_capabilities PRIVATE LEPTRIS_HAS_ICONV=1)
|
|
141
|
+
endif()
|
|
142
|
+
if(CMAKE_SYSTEM_PROCESSOR MATCHES "(x86_64|AMD64|i[3-6]86)")
|
|
143
|
+
target_compile_definitions(test_capabilities PRIVATE LEPTRIS_HAS_AVX2_BUILD=1)
|
|
144
|
+
endif()
|
|
128
145
|
leptris_add_test(test_document_children dom/test_document_children.cpp)
|
|
129
146
|
leptris_add_test(test_vtable dom/test_vtable.cpp)
|
|
130
147
|
leptris_add_test(test_node_surface_parity dom/test_node_surface_parity.cpp)
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
// leptris#1905: one call answering what this installed engine
|
|
2
|
+
// serves. The descriptor is a versioned bitset — new capabilities
|
|
3
|
+
// APPEND bits, never reorder or repack (a reorder bumps
|
|
4
|
+
// LEPTRIS_CAPS_DESCRIPTOR_VERSION).
|
|
5
|
+
#include <leptris.h>
|
|
6
|
+
#include <leptris/descriptor.h>
|
|
7
|
+
#include <leptris/dtd.h>
|
|
8
|
+
#include <leptris/html.h>
|
|
9
|
+
#include <leptris/sax/sax.h>
|
|
10
|
+
#include <leptris/xpath/xpath.h>
|
|
11
|
+
#include <leptris/xquery/xquery.h>
|
|
12
|
+
|
|
13
|
+
#include <gtest/gtest.h>
|
|
14
|
+
|
|
15
|
+
// Anchor law: each unconditional bit's face symbol is REFERENCED
|
|
16
|
+
// here — a descriptor bit without a real, linked face fails the
|
|
17
|
+
// BUILD of this test, not just the assertion.
|
|
18
|
+
namespace caps_anchors {
|
|
19
|
+
void* const kParse = (void*)&leptris_parse_string;
|
|
20
|
+
void* const kDom = (void*)&leptris_document_root;
|
|
21
|
+
void* const kXpath = (void*)&leptris_xpath_eval;
|
|
22
|
+
void* const kXquery = (void*)&leptris_xquery_eval;
|
|
23
|
+
void* const kDtd = (void*)&leptris_dtd_parse;
|
|
24
|
+
void* const kSax = (void*)&leptris_sax_parse;
|
|
25
|
+
void* const kHtml = (void*)&leptris_parse_html_string;
|
|
26
|
+
void* const kXinclude = (void*)&leptris_xinclude_process;
|
|
27
|
+
void* const kDiff = (void*)&leptris_diff;
|
|
28
|
+
void* const kDigest = (void*)&leptris_node_digest;
|
|
29
|
+
void* const kXsd = (void*)&leptris_xsd_compile;
|
|
30
|
+
void* const kXsdSet = (void*)&leptris_xsd_compile_set;
|
|
31
|
+
void* const kRelaxng = (void*)&leptris_rng_parse;
|
|
32
|
+
void* const kSchematron = (void*)&leptris_schematron_parse;
|
|
33
|
+
void* const kXslt = (void*)&leptris_xslt_parse;
|
|
34
|
+
void* const kDescriptor = (void*)&leptris_plan_result_build_packed;
|
|
35
|
+
void* const kNsSnapshot = (void*)&leptris_element_namespace_declarations_snapshot;
|
|
36
|
+
void* const kChildrenBatch = (void*)&leptris_element_children_batch;
|
|
37
|
+
void* const kNameCompare = (void*)&leptris_node_name_compare;
|
|
38
|
+
void* const kVersion = (void*)&leptris_version;
|
|
39
|
+
void* const kEntityRefs = (void*)&leptris_entity_ref_node_name;
|
|
40
|
+
} // namespace caps_anchors
|
|
41
|
+
|
|
42
|
+
TEST(LeptrisCapabilities, DescriptorVersionIsCurrent) {
|
|
43
|
+
LeptrisCapabilities c = leptris_capabilities();
|
|
44
|
+
EXPECT_EQ(c.descriptor_version, LEPTRIS_CAPS_DESCRIPTOR_VERSION);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
TEST(LeptrisCapabilities, UnconditionalFacesAreSet) {
|
|
48
|
+
LeptrisCapabilities c = leptris_capabilities();
|
|
49
|
+
EXPECT_NE(c.caps & LEPTRIS_CAP_PARSE, 0ULL);
|
|
50
|
+
EXPECT_NE(c.caps & LEPTRIS_CAP_DOM, 0ULL);
|
|
51
|
+
EXPECT_NE(c.caps & LEPTRIS_CAP_XPATH, 0ULL);
|
|
52
|
+
EXPECT_NE(c.caps & LEPTRIS_CAP_XQUERY, 0ULL);
|
|
53
|
+
EXPECT_NE(c.caps & LEPTRIS_CAP_DTD, 0ULL);
|
|
54
|
+
EXPECT_NE(c.caps & LEPTRIS_CAP_SAX, 0ULL);
|
|
55
|
+
EXPECT_NE(c.caps & LEPTRIS_CAP_HTML, 0ULL);
|
|
56
|
+
EXPECT_NE(c.caps & LEPTRIS_CAP_XINCLUDE, 0ULL);
|
|
57
|
+
EXPECT_NE(c.caps & LEPTRIS_CAP_DIFF, 0ULL);
|
|
58
|
+
EXPECT_NE(c.caps & LEPTRIS_CAP_DIGEST, 0ULL);
|
|
59
|
+
EXPECT_NE(c.caps & LEPTRIS_CAP_XSD, 0ULL);
|
|
60
|
+
EXPECT_NE(c.caps & LEPTRIS_CAP_XSD_SET, 0ULL);
|
|
61
|
+
EXPECT_NE(c.caps & LEPTRIS_CAP_RELAXNG, 0ULL);
|
|
62
|
+
EXPECT_NE(c.caps & LEPTRIS_CAP_SCHEMATRON, 0ULL);
|
|
63
|
+
EXPECT_NE(c.caps & LEPTRIS_CAP_XSLT, 0ULL);
|
|
64
|
+
EXPECT_NE(c.caps & LEPTRIS_CAP_DESCRIPTOR, 0ULL);
|
|
65
|
+
EXPECT_NE(c.caps & LEPTRIS_CAP_NS_SNAPSHOT_BULK, 0ULL);
|
|
66
|
+
EXPECT_NE(c.caps & LEPTRIS_CAP_CHILDREN_BATCH, 0ULL);
|
|
67
|
+
EXPECT_NE(c.caps & LEPTRIS_CAP_NAME_COMPARE, 0ULL);
|
|
68
|
+
EXPECT_NE(c.caps & LEPTRIS_CAP_VERSION, 0ULL);
|
|
69
|
+
EXPECT_NE(c.caps & LEPTRIS_CAP_ENTITY_REF_NODES, 0ULL);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
TEST(LeptrisCapabilities, BuildConditionalBitsMatchTheBuild) {
|
|
73
|
+
LeptrisCapabilities c = leptris_capabilities();
|
|
74
|
+
#if defined(LEPTRIS_HAS_DUCET)
|
|
75
|
+
EXPECT_NE(c.caps & LEPTRIS_CAP_COLLATION_DUCET, 0ULL);
|
|
76
|
+
#else
|
|
77
|
+
EXPECT_EQ(c.caps & LEPTRIS_CAP_COLLATION_DUCET, 0ULL);
|
|
78
|
+
#endif
|
|
79
|
+
#if defined(LEPTRIS_HAS_UTF8PROC)
|
|
80
|
+
EXPECT_NE(c.caps & LEPTRIS_CAP_UNICODE_UTF8PROC, 0ULL);
|
|
81
|
+
#else
|
|
82
|
+
EXPECT_EQ(c.caps & LEPTRIS_CAP_UNICODE_UTF8PROC, 0ULL);
|
|
83
|
+
#endif
|
|
84
|
+
#if defined(LEPTRIS_HAS_ICONV)
|
|
85
|
+
EXPECT_NE(c.caps & LEPTRIS_CAP_ENCODING_ICONV, 0ULL);
|
|
86
|
+
#else
|
|
87
|
+
EXPECT_EQ(c.caps & LEPTRIS_CAP_ENCODING_ICONV, 0ULL);
|
|
88
|
+
#endif
|
|
89
|
+
#if defined(LEPTRIS_HAS_AVX2_BUILD)
|
|
90
|
+
EXPECT_NE(c.caps & LEPTRIS_CAP_SIMD_AVX2, 0ULL);
|
|
91
|
+
#else
|
|
92
|
+
EXPECT_EQ(c.caps & LEPTRIS_CAP_SIMD_AVX2, 0ULL);
|
|
93
|
+
#endif
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
TEST(LeptrisCapabilities, NoUnknownBits) {
|
|
97
|
+
LeptrisCapabilities c = leptris_capabilities();
|
|
98
|
+
constexpr unsigned long long kKnown =
|
|
99
|
+
LEPTRIS_CAP_PARSE | LEPTRIS_CAP_DOM | LEPTRIS_CAP_XPATH |
|
|
100
|
+
LEPTRIS_CAP_XQUERY | LEPTRIS_CAP_DTD | LEPTRIS_CAP_SAX |
|
|
101
|
+
LEPTRIS_CAP_HTML | LEPTRIS_CAP_XINCLUDE | LEPTRIS_CAP_DIFF |
|
|
102
|
+
LEPTRIS_CAP_DIGEST | LEPTRIS_CAP_XSD | LEPTRIS_CAP_XSD_SET |
|
|
103
|
+
LEPTRIS_CAP_RELAXNG | LEPTRIS_CAP_SCHEMATRON | LEPTRIS_CAP_XSLT |
|
|
104
|
+
LEPTRIS_CAP_DESCRIPTOR | LEPTRIS_CAP_NS_SNAPSHOT_BULK |
|
|
105
|
+
LEPTRIS_CAP_CHILDREN_BATCH | LEPTRIS_CAP_NAME_COMPARE |
|
|
106
|
+
LEPTRIS_CAP_VERSION | LEPTRIS_CAP_COLLATION_DUCET |
|
|
107
|
+
LEPTRIS_CAP_UNICODE_UTF8PROC | LEPTRIS_CAP_ENCODING_ICONV |
|
|
108
|
+
LEPTRIS_CAP_SIMD_AVX2 | LEPTRIS_CAP_ENTITY_REF_NODES;
|
|
109
|
+
EXPECT_EQ(c.caps & ~kKnown, 0ULL)
|
|
110
|
+
<< "an unknown bit is set — the descriptor grew without "
|
|
111
|
+
"bumping LEPTRIS_CAPS_DESCRIPTOR_VERSION";
|
|
112
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// leptris#1904: LEPTRIS_PARSE_KEEP_ENTITY_REFS yields entity
|
|
2
|
+
// references as FIRST-CLASS nodes — segments split around the five
|
|
3
|
+
// built-ins and custom named references, numeric character
|
|
4
|
+
// references folded into text (they are character references, not
|
|
5
|
+
// entity references, per XML 1.0 §4.1). The DOM the binding
|
|
6
|
+
// consumes: text / entity-ref / text / ... with string-value,
|
|
7
|
+
// serialization, and XPath walking the expanded value.
|
|
8
|
+
#include <gtest/gtest.h>
|
|
9
|
+
#include <leptris.h>
|
|
10
|
+
#include <cstring>
|
|
11
|
+
#include <string>
|
|
12
|
+
#include <vector>
|
|
13
|
+
|
|
14
|
+
namespace {
|
|
15
|
+
|
|
16
|
+
struct ChildInfo {
|
|
17
|
+
int type;
|
|
18
|
+
std::string text;
|
|
19
|
+
std::string name;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
std::vector<ChildInfo> children_of(LeptrisElement e) {
|
|
23
|
+
std::vector<ChildInfo> rows;
|
|
24
|
+
for (LeptrisNodeRef c = leptris_node_first_child(
|
|
25
|
+
leptris_element_as_node(e));
|
|
26
|
+
c; c = leptris_node_next_sibling(c)) {
|
|
27
|
+
ChildInfo row;
|
|
28
|
+
row.type = (int)leptris_node_get_type(c);
|
|
29
|
+
if (row.type == LEPTRIS_NODE_TYPE_TEXT)
|
|
30
|
+
row.text = leptris_text_node_get_content(c);
|
|
31
|
+
if (row.type == LEPTRIS_NODE_TYPE_ENTITY_REF)
|
|
32
|
+
row.name = leptris_entity_ref_node_name(c);
|
|
33
|
+
rows.push_back(row);
|
|
34
|
+
}
|
|
35
|
+
return rows;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
} // namespace
|
|
39
|
+
|
|
40
|
+
TEST(EntityRefNodes, BuiltinsBecomeNodes) {
|
|
41
|
+
const char* xml = "<a>x&y<z>w</a>";
|
|
42
|
+
LeptrisStatus st = LEPTRIS_OK;
|
|
43
|
+
LeptrisDocument doc = leptris_parse_string_flags(
|
|
44
|
+
xml, strlen(xml), LEPTRIS_PARSE_KEEP_ENTITY_REFS, &st);
|
|
45
|
+
ASSERT_NE(doc, (LeptrisDocument)0);
|
|
46
|
+
LeptrisElement a = leptris_document_root(doc);
|
|
47
|
+
std::vector<ChildInfo> kids = children_of(a);
|
|
48
|
+
ASSERT_EQ(kids.size(), 7u);
|
|
49
|
+
EXPECT_EQ(kids[0].type, (int)LEPTRIS_NODE_TYPE_TEXT);
|
|
50
|
+
EXPECT_EQ(kids[0].text, "x");
|
|
51
|
+
EXPECT_EQ(kids[1].type, (int)LEPTRIS_NODE_TYPE_ENTITY_REF);
|
|
52
|
+
EXPECT_EQ(kids[1].name, "amp");
|
|
53
|
+
EXPECT_EQ(kids[2].text, "y");
|
|
54
|
+
EXPECT_EQ(kids[3].name, "lt");
|
|
55
|
+
EXPECT_EQ(kids[4].text, "z");
|
|
56
|
+
EXPECT_EQ(kids[5].name, "gt");
|
|
57
|
+
EXPECT_EQ(kids[6].text, "w");
|
|
58
|
+
leptris_document_free(doc);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
TEST(EntityRefNodes, NumericCharacterRefsStayText) {
|
|
62
|
+
/* XML 1.0 §4.1: character references are NOT entity references. */
|
|
63
|
+
const char* xml = "<a>AB</a>";
|
|
64
|
+
LeptrisStatus st = LEPTRIS_OK;
|
|
65
|
+
LeptrisDocument doc = leptris_parse_string_flags(
|
|
66
|
+
xml, strlen(xml), LEPTRIS_PARSE_KEEP_ENTITY_REFS, &st);
|
|
67
|
+
ASSERT_NE(doc, (LeptrisDocument)0);
|
|
68
|
+
LeptrisElement a = leptris_document_root(doc);
|
|
69
|
+
std::vector<ChildInfo> kids = children_of(a);
|
|
70
|
+
ASSERT_EQ(kids.size(), 1u);
|
|
71
|
+
EXPECT_EQ(kids[0].type, (int)LEPTRIS_NODE_TYPE_TEXT);
|
|
72
|
+
EXPECT_EQ(kids[0].text, "AB");
|
|
73
|
+
leptris_document_free(doc);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
TEST(EntityRefNodes, StringValueSerializationAndXPathAgree) {
|
|
77
|
+
const char* xml = "<a>x&y<z</a>";
|
|
78
|
+
LeptrisStatus st = LEPTRIS_OK;
|
|
79
|
+
LeptrisDocument doc = leptris_parse_string_flags(
|
|
80
|
+
xml, strlen(xml), LEPTRIS_PARSE_KEEP_ENTITY_REFS, &st);
|
|
81
|
+
ASSERT_NE(doc, (LeptrisDocument)0);
|
|
82
|
+
LeptrisElement a = leptris_document_root(doc);
|
|
83
|
+
EXPECT_STREQ(leptris_element_text(a), "x&y<z");
|
|
84
|
+
char* ser = leptris_document_serialize(doc, NULL);
|
|
85
|
+
ASSERT_NE(ser, nullptr);
|
|
86
|
+
EXPECT_STREQ(ser, "<a>x&y<z</a>");
|
|
87
|
+
leptris_free_string(ser);
|
|
88
|
+
LeptrisXPathResult r = leptris_xpath_eval(doc, NULL, "string(/a)");
|
|
89
|
+
ASSERT_NE(r, nullptr);
|
|
90
|
+
char* sv = leptris_xpath_result_string(r);
|
|
91
|
+
EXPECT_STREQ(sv, "x&y<z");
|
|
92
|
+
leptris_free_string(sv);
|
|
93
|
+
leptris_xpath_result_free(r);
|
|
94
|
+
leptris_document_free(doc);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
TEST(EntityRefNodes, CustomNamedRefsAreNodes) {
|
|
98
|
+
const char* xml =
|
|
99
|
+
"<!DOCTYPE r [<!ENTITY foo \"x\">]><r>a&foo;b</r>";
|
|
100
|
+
LeptrisStatus st = LEPTRIS_OK;
|
|
101
|
+
LeptrisDocument doc = leptris_parse_string_flags(
|
|
102
|
+
xml, strlen(xml), LEPTRIS_PARSE_KEEP_ENTITY_REFS, &st);
|
|
103
|
+
ASSERT_NE(doc, (LeptrisDocument)0);
|
|
104
|
+
LeptrisElement r = leptris_document_root(doc);
|
|
105
|
+
std::vector<ChildInfo> kids = children_of(r);
|
|
106
|
+
ASSERT_EQ(kids.size(), 3u);
|
|
107
|
+
EXPECT_EQ(kids[1].type, (int)LEPTRIS_NODE_TYPE_ENTITY_REF);
|
|
108
|
+
EXPECT_EQ(kids[1].name, "foo");
|
|
109
|
+
EXPECT_STREQ(leptris_element_text(r), "axb");
|
|
110
|
+
leptris_document_free(doc);
|
|
111
|
+
}
|
|
@@ -3887,3 +3887,119 @@ TEST(XsdCrossNs, RealWmlChainCompilesDeclarations) {
|
|
|
3887
3887
|
<< " err=" << (err ? err : "(clean)");
|
|
3888
3888
|
leptris_xsd_free(s);
|
|
3889
3889
|
}
|
|
3890
|
+
|
|
3891
|
+
/* leptris#1911: vc:minVersion="1.1" marks the schema as XSD 1.1
|
|
3892
|
+
* (the W3C suite and moxml both use the versioning namespace; the
|
|
3893
|
+
* plain version attribute is the other legal spelling). The
|
|
3894
|
+
* alternative's test selects the type — validation must run the
|
|
3895
|
+
* SELECTED type's content model, in both directions. */
|
|
3896
|
+
TEST(Xsd11Gate, CtaSelectsAlternativeType) {
|
|
3897
|
+
const char xsd[] =
|
|
3898
|
+
"<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\""
|
|
3899
|
+
" vc:minVersion=\"1.1\""
|
|
3900
|
+
" xmlns:vc=\"http://www.w3.org/2001/XMLSchema-versioning\">"
|
|
3901
|
+
"<xs:element name=\"shape\" type=\"Shape\">"
|
|
3902
|
+
"<xs:alternative test=\"@kind='circle'\" type=\"Circle\"/>"
|
|
3903
|
+
"</xs:element>"
|
|
3904
|
+
"<xs:complexType name=\"Shape\" abstract=\"true\">"
|
|
3905
|
+
"<xs:attribute name=\"kind\" type=\"xs:string\"/>"
|
|
3906
|
+
"</xs:complexType>"
|
|
3907
|
+
"<xs:complexType name=\"Circle\">"
|
|
3908
|
+
"<xs:complexContent><xs:extension base=\"Shape\">"
|
|
3909
|
+
"<xs:sequence><xs:element name=\"r\" type=\"xs:integer\"/>"
|
|
3910
|
+
"</xs:sequence></xs:extension></xs:complexContent>"
|
|
3911
|
+
"</xs:complexType></xs:schema>";
|
|
3912
|
+
LeptrisStatus st = LEPTRIS_OK;
|
|
3913
|
+
LeptrisXsdSchema s = leptris_xsd_compile(xsd, strlen(xsd), &st);
|
|
3914
|
+
ASSERT_NE(s, (LeptrisXsdSchema)0);
|
|
3915
|
+
ASSERT_EQ(st, LEPTRIS_OK) << leptris_xsd_error(s);
|
|
3916
|
+
EXPECT_STREQ(leptris_xsd_version(s), "1.1")
|
|
3917
|
+
<< "vc:minVersion must gate the 1.1 feature set";
|
|
3918
|
+
EXPECT_EQ(validate_compiled(s,
|
|
3919
|
+
"<shape kind=\"circle\"><r>4</r></shape>"),
|
|
3920
|
+
1)
|
|
3921
|
+
<< "the selected Circle type admits <r>: "
|
|
3922
|
+
<< leptris_xsd_error(s);
|
|
3923
|
+
EXPECT_EQ(validate_compiled(s, "<shape kind=\"circle\"/>"), 0)
|
|
3924
|
+
<< "the selected Circle type REQUIRES <r>";
|
|
3925
|
+
leptris_xsd_free(s);
|
|
3926
|
+
}
|
|
3927
|
+
|
|
3928
|
+
/* leptris#1910: an xs:assert in a vc:minVersion="1.1" schema must
|
|
3929
|
+
* be evaluated — a violating instance produces an assertion row. */
|
|
3930
|
+
TEST(Xsd11Gate, AssertIsEvaluated) {
|
|
3931
|
+
const char xsd[] =
|
|
3932
|
+
"<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\""
|
|
3933
|
+
" vc:minVersion=\"1.1\""
|
|
3934
|
+
" xmlns:vc=\"http://www.w3.org/2001/XMLSchema-versioning\">"
|
|
3935
|
+
"<xs:element name=\"size\">"
|
|
3936
|
+
"<xs:complexType><xs:sequence>"
|
|
3937
|
+
"<xs:element name=\"w\" type=\"xs:integer\"/>"
|
|
3938
|
+
"<xs:element name=\"h\" type=\"xs:integer\"/>"
|
|
3939
|
+
"</xs:sequence><xs:assert test=\"w le h\"/></xs:complexType>"
|
|
3940
|
+
"</xs:element></xs:schema>";
|
|
3941
|
+
LeptrisStatus st = LEPTRIS_OK;
|
|
3942
|
+
LeptrisXsdSchema s = leptris_xsd_compile(xsd, strlen(xsd), &st);
|
|
3943
|
+
ASSERT_NE(s, (LeptrisXsdSchema)0);
|
|
3944
|
+
ASSERT_EQ(st, LEPTRIS_OK) << leptris_xsd_error(s);
|
|
3945
|
+
EXPECT_EQ(validate_compiled(s, "<size><w>3</w><h>5</h></size>"), 1)
|
|
3946
|
+
<< "satisfying assert must stay valid: "
|
|
3947
|
+
<< leptris_xsd_error(s);
|
|
3948
|
+
EXPECT_EQ(validate_compiled(s, "<size><w>9</w><h>5</h></size>"), 0)
|
|
3949
|
+
<< "violating assert must produce a finding";
|
|
3950
|
+
leptris_xsd_free(s);
|
|
3951
|
+
}
|
|
3952
|
+
|
|
3953
|
+
/* leptris#1913: xs:override (XSD 1.1 Structures §I.4) — the base
|
|
3954
|
+
* document's declarations load (xs:override is an include-family
|
|
3955
|
+
* chase), then the override body's same-named declarations REPLACE
|
|
3956
|
+
* them. Previously override was absent from the chase condition:
|
|
3957
|
+
* the base never loaded and the body's nested declarations were
|
|
3958
|
+
* never captured — an empty symbol space (decls=0). */
|
|
3959
|
+
TEST(Xsd11Gate, OverrideLoadsBaseAndReplacesComponents) {
|
|
3960
|
+
const char* base =
|
|
3961
|
+
"<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\""
|
|
3962
|
+
" targetNamespace=\"urn:b\" xmlns=\"urn:b\""
|
|
3963
|
+
" elementFormDefault=\"qualified\">"
|
|
3964
|
+
"<xs:element name=\"doc\" type=\"Doc\"/>"
|
|
3965
|
+
"<xs:complexType name=\"Doc\">"
|
|
3966
|
+
"<xs:sequence><xs:element name=\"a\" type=\"xs:string\"/>"
|
|
3967
|
+
"</xs:sequence></xs:complexType></xs:schema>";
|
|
3968
|
+
const char* ovr =
|
|
3969
|
+
"<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\""
|
|
3970
|
+
" targetNamespace=\"urn:b\" xmlns=\"urn:b\""
|
|
3971
|
+
" elementFormDefault=\"qualified\" vc:minVersion=\"1.1\""
|
|
3972
|
+
" xmlns:vc=\"http://www.w3.org/2001/XMLSchema-versioning\">"
|
|
3973
|
+
"<xs:override schemaLocation=\"ovr1913_base.xsd\">"
|
|
3974
|
+
"<xs:complexType name=\"Doc\">"
|
|
3975
|
+
"<xs:sequence><xs:element name=\"b\" type=\"xs:integer\"/>"
|
|
3976
|
+
"</xs:sequence></xs:complexType>"
|
|
3977
|
+
"</xs:override></xs:schema>";
|
|
3978
|
+
const char* dir = std::getenv("TMPDIR");
|
|
3979
|
+
std::string tmp = dir ? dir : "/tmp";
|
|
3980
|
+
std::string base_path = tmp + "/ovr1913_base.xsd";
|
|
3981
|
+
std::string ovr_path = tmp + "/ovr1913_ovr.xsd";
|
|
3982
|
+
{
|
|
3983
|
+
std::ofstream f(base_path);
|
|
3984
|
+
f << base;
|
|
3985
|
+
}
|
|
3986
|
+
{
|
|
3987
|
+
std::ofstream f(ovr_path);
|
|
3988
|
+
f << ovr;
|
|
3989
|
+
}
|
|
3990
|
+
LeptrisStatus st = LEPTRIS_OK;
|
|
3991
|
+
LeptrisXsdSchema s = leptris_xsd_compile_file(ovr_path.c_str(), &st);
|
|
3992
|
+
ASSERT_NE(s, (LeptrisXsdSchema)0);
|
|
3993
|
+
ASSERT_EQ(st, LEPTRIS_OK) << leptris_xsd_error(s);
|
|
3994
|
+
EXPECT_GT(leptris_xsd_declaration_count(s), 0u)
|
|
3995
|
+
<< "override must not produce an empty symbol space";
|
|
3996
|
+
EXPECT_EQ(validate_compiled(s, "<doc xmlns=\"urn:b\"><b>1</b></doc>"),
|
|
3997
|
+
1)
|
|
3998
|
+
<< "the overridden Doc admits <b>: " << leptris_xsd_error(s);
|
|
3999
|
+
EXPECT_EQ(validate_compiled(s, "<doc xmlns=\"urn:b\"><a>x</a></doc>"),
|
|
4000
|
+
0)
|
|
4001
|
+
<< "the overridden Doc no longer admits <a>";
|
|
4002
|
+
std::remove(base_path.c_str());
|
|
4003
|
+
std::remove(ovr_path.c_str());
|
|
4004
|
+
leptris_xsd_free(s);
|
|
4005
|
+
}
|
|
@@ -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.394",
|
|
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.
|
|
4
|
+
version: 1.9.394.0
|
|
5
5
|
platform: arm-linux
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
@@ -744,6 +744,7 @@ files:
|
|
|
744
744
|
- vendor-src/libleptris/src/man/libleptris.5.adoc
|
|
745
745
|
- vendor-src/libleptris/test/CMakeLists.txt
|
|
746
746
|
- vendor-src/libleptris/test/README.md
|
|
747
|
+
- vendor-src/libleptris/test/abi/test_capabilities.cpp
|
|
747
748
|
- vendor-src/libleptris/test/abi/test_descriptor.cpp
|
|
748
749
|
- vendor-src/libleptris/test/abi/test_doctype_api.cpp
|
|
749
750
|
- vendor-src/libleptris/test/abi/test_dom_deep_copy.cpp
|
|
@@ -782,6 +783,7 @@ files:
|
|
|
782
783
|
- vendor-src/libleptris/test/dom/test_document_children.cpp
|
|
783
784
|
- vendor-src/libleptris/test/dom/test_dom.cpp
|
|
784
785
|
- vendor-src/libleptris/test/dom/test_element_children.cpp
|
|
786
|
+
- vendor-src/libleptris/test/dom/test_entity_refs.cpp
|
|
785
787
|
- vendor-src/libleptris/test/dom/test_map_lifecycle.cpp
|
|
786
788
|
- vendor-src/libleptris/test/dom/test_namespace_cache.cpp
|
|
787
789
|
- vendor-src/libleptris/test/dom/test_node_surface_parity.cpp
|