yeptris 0.6.59.1-arm-linux-eabihf → 0.6.60.1-arm-linux-eabihf

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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/ext/yeptris_native/version.h +2 -2
  3. data/lib/yeptris/3.4/native.so +0 -0
  4. data/lib/yeptris/ffi.rb +19 -0
  5. data/lib/yeptris/yaml.rb +61 -0
  6. data/lib/yeptris.rb +1 -1
  7. data/libyeptris.so +0 -0
  8. data/vendor/libyeptris/CMakeLists.txt +1 -1
  9. data/vendor/libyeptris/src/CMakeLists.txt +7 -0
  10. data/vendor/libyeptris/src/include/yeptris/emit.h +30 -2
  11. data/vendor/libyeptris/src/include/yeptris/parse.h +52 -0
  12. data/vendor/libyeptris/src/include/yeptris/resolve.h +8 -0
  13. data/vendor/libyeptris/src/include/yeptris/validate.h +222 -21
  14. data/vendor/libyeptris/src/include/yeptris/values.h +8 -2
  15. data/vendor/libyeptris/src/yeptris/cbor/cbor.h +10 -0
  16. data/vendor/libyeptris/src/yeptris/cbor/decode.c +5 -7
  17. data/vendor/libyeptris/src/yeptris/cbor/encode.c +9 -9
  18. data/vendor/libyeptris/src/yeptris/cbor/from_marshal.c +1 -1
  19. data/vendor/libyeptris/src/yeptris/common/error.h +2 -0
  20. data/vendor/libyeptris/src/yeptris/doc.h +20 -0
  21. data/vendor/libyeptris/src/yeptris/emit/emit.c +85 -13
  22. data/vendor/libyeptris/src/yeptris/emit/writer.c +158 -642
  23. data/vendor/libyeptris/src/yeptris/emit/writer.h +15 -1
  24. data/vendor/libyeptris/src/yeptris/events/push.c +28 -3
  25. data/vendor/libyeptris/src/yeptris/events/values.c +24 -0
  26. data/vendor/libyeptris/src/yeptris/marshal/to_json.c +650 -0
  27. data/vendor/libyeptris/src/yeptris/parse/engine.c +121 -40
  28. data/vendor/libyeptris/src/yeptris/parse/stream_iter.c +326 -0
  29. data/vendor/libyeptris/src/yeptris/parse.c +173 -43
  30. data/vendor/libyeptris/src/yeptris/resolve/compat11.c +1 -1
  31. data/vendor/libyeptris/src/yeptris/resolve/core12.c +11 -3
  32. data/vendor/libyeptris/src/yeptris/resolve/full12.c +201 -0
  33. data/vendor/libyeptris/src/yeptris/resolve/json12.c +12 -6
  34. data/vendor/libyeptris/src/yeptris/resolve/resolver.h +20 -0
  35. data/vendor/libyeptris/src/yeptris/validate/compile.c +39 -3
  36. data/vendor/libyeptris/src/yeptris/validate/internal.h +223 -7
  37. data/vendor/libyeptris/src/yeptris/validate/jsonschema.c +645 -115
  38. data/vendor/libyeptris/src/yeptris/validate/output.c +246 -0
  39. data/vendor/libyeptris/src/yeptris/validate/regexp.c +623 -157
  40. data/vendor/libyeptris/src/yeptris/validate/registry.c +118 -0
  41. data/vendor/libyeptris/src/yeptris/validate/resources.c +601 -0
  42. data/vendor/libyeptris/src/yeptris/validate/stream.c +1155 -0
  43. data/vendor/libyeptris/src/yeptris/validate/validate.c +288 -145
  44. metadata +8 -1
@@ -43,6 +43,7 @@ struct yeptris_schema {
43
43
  const yep_dom* dom; /* borrowed from doc (yep_doc_dom) */
44
44
  uint32_t sroot; /* the schema document's root (docs[0]) */
45
45
  yep_re_cache* cache; /* owned: pattern source -> compiled NFA; immutable after compile */
46
+ js_resources* res; /* owned: $id/$anchor/$dynamicAnchor map + ref-site bases */
46
47
  };
47
48
 
48
49
  /* ---- the pattern collection (compile-time, eager) ----------------------- */
@@ -188,8 +189,22 @@ yeptris_schema* yep_schema_compile_st(const char* bytes, size_t n, YeptrisStatus
188
189
  return NULL;
189
190
  }
190
191
 
192
+ /* the identifier map: $id resources, anchors, ref-site bases —
193
+ * built once by the crawl, read-only afterwards (OOM is loud) */
194
+ js_resources* res = yep_js_resources_crawl(dom, dom->docs[0]);
195
+ if (res == NULL) {
196
+ yep_re_cache_free(cache);
197
+ yeptris_document_free(doc);
198
+ yep_free(sys, copy);
199
+ yep_error_set(yep_error_tls(), YEP_ERR_MEMORY, 0, 0, 0,
200
+ "the schema's identifier map failed to build");
201
+ *st = YEPTRIS_ERROR_MEMORY;
202
+ return NULL;
203
+ }
204
+
191
205
  yeptris_schema* s = yep_alloc(sys, sizeof(*s));
192
206
  if (s == NULL) {
207
+ yep_js_resources_free(res);
193
208
  yep_re_cache_free(cache);
194
209
  yeptris_document_free(doc);
195
210
  yep_free(sys, copy);
@@ -201,6 +216,7 @@ yeptris_schema* yep_schema_compile_st(const char* bytes, size_t n, YeptrisStatus
201
216
  s->dom = dom;
202
217
  s->sroot = dom->docs[0];
203
218
  s->cache = cache;
219
+ s->res = res;
204
220
  return s;
205
221
  }
206
222
 
@@ -211,11 +227,29 @@ YEPTRIS_API yeptris_schema* yeptris_schema_compile(const char* bytes, size_t n)
211
227
  return yep_schema_compile_st(bytes, n, &st); /* the error channel carries the why */
212
228
  }
213
229
 
230
+ /* The tag-driven hook's read-only view (internal.h, #906 slice 4):
231
+ * everything the subtree walk reads, borrowed from the handle — the
232
+ * REGISTRY LAW keeps the handle alive underneath it. */
233
+ void yep_schema_view_of(const yeptris_schema* s, yep_schema_view* out) {
234
+ if (out == NULL) {
235
+ return;
236
+ }
237
+ if (s == NULL) {
238
+ memset(out, 0, sizeof(*out));
239
+ return;
240
+ }
241
+ out->dom = s->dom;
242
+ out->sroot = s->sroot;
243
+ out->cache = s->cache;
244
+ out->res = s->res;
245
+ }
246
+
214
247
  YEPTRIS_API void yeptris_schema_free(yeptris_schema* s) {
215
248
  if (s == NULL) {
216
249
  return;
217
250
  }
218
251
  const yep_allocator* sys = yep_system_allocator();
252
+ yep_js_resources_free(s->res);
219
253
  yep_re_cache_free(s->cache);
220
254
  yeptris_document_free(s->doc); /* the DOM and every pool under it */
221
255
  yep_free(sys, s->bytes); /* the views' home: freed after its readers */
@@ -257,9 +291,11 @@ YEPTRIS_API YeptrisStatus yeptris_schema_validate(yeptris_schema* s, const char*
257
291
  yeptris_document_free(idoc);
258
292
  return YEPTRIS_ERROR_MEMORY;
259
293
  }
260
- /* the handle is a pure reader here (its cache is immutable): the
261
- * same walk, the same report shape, the one-shot's verdicts */
262
- int rc = yep_jsonschema_run(s->dom, s->sroot, idom, idom->docs, idom->dcount, r, s->cache);
294
+ /* the handle is a pure reader here (its cache and identifier map
295
+ * are immutable): the same walk, the same report shape, the
296
+ * one-shot's verdicts */
297
+ int rc =
298
+ yep_jsonschema_run(s->dom, s->sroot, idom, idom->docs, idom->dcount, r, s->cache, s->res);
263
299
  yeptris_document_free(idoc);
264
300
  if (rc != 0) {
265
301
  yeptris_validate_report_free(r);
@@ -45,10 +45,30 @@ typedef struct yep_vctx {
45
45
  size_t path_len, path_cap;
46
46
  int depth; /* the walk's nesting guard (never exceeds the DOM's) */
47
47
  int oom; /* an allocation failed: stop diagnosing */
48
- /* JSON Schema trial suppression (anyOf/oneOf/not probes) */
48
+ /* JSON Schema trial suppression (anyOf/oneOf/not probes): emits
49
+ * inside a probe never reach the report and never touch
50
+ * fail_mark — the probe's own validity is ITS trial_fail delta
51
+ * (zero delta = held), the enclosing application's is its
52
+ * fail_mark delta */
49
53
  int suppress;
50
- int trial_hit;
51
- int ref_depth; /* consecutive $ref expansions */
54
+ /* the walks' invalid-application counters: every emit increments
55
+ * exactly one of them (suppressed -> trial_fail, otherwise
56
+ * fail_mark), so an application's validity is one comparison (the
57
+ * unevaluated* annotation model reads fail_mark) */
58
+ int fail_mark;
59
+ int trial_fail;
60
+ int ref_depth; /* consecutive $ref/$dynamicRef expansions */
61
+ /* the event route's staging hook (#902): when set, composed
62
+ * diagnostics join the OPEN mapping's stage (the flush replays
63
+ * [own tag][duplicates][pair content] so report order stays the
64
+ * DOM walk's); the cap counts the walk position (rep count +
65
+ * staged). NULL on the DOM route — the report path, unchanged. */
66
+ void (*stage_put)(void* stage, const yeptris_diagnostic* d);
67
+ void* stage;
68
+ size_t staged;
69
+ /* the tag-driven registry (#906 slice 4): NULL = no bindings —
70
+ * the DOM route only (the event route keeps its lanes). */
71
+ const yeptris_schema_registry* reg;
52
72
  } yep_vctx;
53
73
 
54
74
  /* Offset of a node's first positioned byte (the value span of the node
@@ -56,22 +76,91 @@ typedef struct yep_vctx {
56
76
  * everything reachable lives in the arena — line/col unknown). */
57
77
  uint32_t yep_validate_node_off(const yep_dom* d, uint32_t id);
58
78
 
79
+ /* ---- the fact cores (shared by the DOM walk and the event route) -------
80
+ *
81
+ * The family checks read five facts per node: kind (yep_dom_kind),
82
+ * explicit-tag presence, the resolved tag id, the plainness law
83
+ * (PLAIN style or the implicit flag), and the value bytes. The DOM
84
+ * walk extracts them from yep_dnode; the event route (#902) extracts
85
+ * the same five from the engine's events — both call THESE cores, so
86
+ * a verdict change lands once and both routes move together. `off` is
87
+ * the caller's position fact (the DOM's node_off law / the event
88
+ * route's borrowed-view law); UINT32_MAX = unpositioned (line/col 0).
89
+ * A zero-length value decodes to {NULL, 0} (the yep_dom_view law). */
90
+
91
+ /* The scalar tag law: explicit tag wins, then the resolver verdict for
92
+ * plain/implicit scalars, then str for quoted/block styles. */
93
+ uint8_t yep_validate_tag_of(uint8_t tag_id, int has_tag, int plainish);
94
+
95
+ /* Explicit-tag consistency (both families). */
96
+ struct yep_resolver;
97
+ void yep_check_tag_facts(yep_vctx* c, int kind, int has_tag, uint8_t tag_id, yep_view value,
98
+ uint32_t off, const struct yep_resolver* fam, int json_family);
99
+
100
+ /* json12: a plain scalar must match a JSON production; explicit
101
+ * non-JSON tags rejected. */
102
+ void yep_check_json_scalar_facts(yep_vctx* c, int has_tag, uint8_t tag_id, int plainish,
103
+ yep_view value, uint32_t off);
104
+
105
+ /* json12: a SCALAR mapping key's checks (the caller resolves aliases
106
+ * and non-scalar kinds first — the DOM wrapper keeps that recursion). */
107
+ void yep_check_json_key_facts(yep_vctx* c, int has_tag, uint8_t tag_id, int plainish,
108
+ yep_view value, uint32_t off);
109
+
110
+ /* ---- the canonical digest law (spec 3.2.1.3) --------------------------- */
111
+
112
+ /* The 64-bit fold primitive behind every canonical fingerprint. */
113
+ uint64_t yep_validate_hash_mix(uint64_t h, uint64_t v);
114
+
115
+ /* Seed constants of the canonical fold (validate.c's DOM hash and the
116
+ * event route's streaming fold must agree bit for bit). */
117
+ #define YEP_VAL_DIGEST_SEQ_SEED 0x5EED51ULL /* sequences: ordered fold */
118
+ #define YEP_VAL_DIGEST_MAP_SEED 0x5EED4A9ULL /* mappings: XOR of pairs */
119
+ #define YEP_VAL_DIGEST_PAIR_SEED 0x51D1ULL /* one (key, value) pair */
120
+ #define YEP_VAL_DIGEST_ALIAS 0xA11AULL /* unbound alias fallback */
121
+ #define YEP_VAL_DIGEST_SCALAR 0x5CA1AULL /* scalar base (tag added) */
122
+
123
+ /* The scalar arm of the canonical hash: base + tag, the numeric VALUE
124
+ * for int/float (the double bits), the raw bytes otherwise. */
125
+ uint64_t yep_validate_scalar_digest(uint8_t tag, yep_view v);
126
+
59
127
  /* Emits one diagnostic at the current path. line/col resolve from
60
128
  * `off` through the lazy line index; 0/0 when unknown. Detail is
61
129
  * printf-composed into the bounded slot. Never fails the caller: the
62
130
  * report cap turns the last slot into the LIMIT sentinel. */
63
131
  void yep_validate_emit(yep_vctx* c, int code, uint32_t off, const char* detail_fmt, ...);
64
132
 
133
+ /* The report-path writer (the cap law's one home): appends a RESOLVED
134
+ * diagnostic, or turns the last slot into the LIMIT sentinel once the
135
+ * report is full. The event route's flush replays its staged
136
+ * diagnostics through this — the compose time (and therefore the path
137
+ * and position) stays the walk's. */
138
+ void yep_validate_report_put(yep_vctx* c, const yeptris_diagnostic* d);
139
+
65
140
  /* JSON-pointer path scratch: push an escaped segment / a decimal
66
141
  * index, pop to a mark. 0 ok, -1 OOM (ctx.oom set; the walk unwinds). */
67
142
  int yep_validate_path_push(yep_vctx* c, const char* seg, size_t seg_len);
68
143
  int yep_validate_path_push_index(yep_vctx* c, uint32_t idx);
69
144
  void yep_validate_path_pop(yep_vctx* c, size_t mark);
70
145
 
146
+ /* The stream face's document attribution (#885 item 4): a validated
147
+ * stream is addressed as an array of documents — when it holds MORE
148
+ * THAN ONE document, every diagnostic path is prefixed with the
149
+ * document's index segment, so diagnostics name their document ("/1/k"
150
+ * is key k of document 1; the line/col stay input-absolute). Streams
151
+ * with a single document keep the bare instance pointers (the
152
+ * JSON-Schema-Test-Suite's paths and every single-doc pin are
153
+ * unchanged). Call before a document's walk and pop the returned mark
154
+ * after it; OOM sets ctx.oom and the walk unwinds. */
155
+ size_t yep_validate_doc_prefix(yep_vctx* c, int qualified, uint32_t index);
156
+
71
157
  /* The bounded ECMA-regex subset behind `pattern` (jsonschema.c):
72
158
  * literals, '.', classes, groups, alternation, the greedy/lazy
73
- * quantifiers, anchors, \d\w\s\D\W\S\b\B and \xHH. Byte-oriented
74
- * (ASCII classes; UTF-8 literals match byte-wise). A Thompson NFA —
159
+ * quantifiers, anchors, \d\w\s\D\W\S\b\B, \xHH, \cX and the
160
+ * \p{Letter}/\p{digit} property escapes. Classes match WHOLE UTF-8
161
+ * code points (the named classes carry range tables: ASCII \d/\w,
162
+ * Unicode \s, code-point complements, generated Unicode properties);
163
+ * literals match byte-wise. A Thompson NFA over per-thread positions —
75
164
  * O(len * m), no backtracking blowup, no recursion over the subject.
76
165
  * Patterns over the program budget are invalid. 1 match, 0 no match,
77
166
  * -1 invalid pattern. */
@@ -103,13 +192,95 @@ uint64_t yep_validate_node_hash(const yep_dom* d, uint32_t id, int depth);
103
192
  int yep_validate_node_equal(const yep_dom* da, uint32_t a, const yep_dom* db, uint32_t b,
104
193
  int depth);
105
194
 
195
+ /* ---- the schema identifier map (resources.c) ----------------------------- */
196
+
197
+ /* Bounded identifier tables: an identifier past a cap (or a URI over
198
+ * the length cap) is not registered — the reference then fails to
199
+ * resolve at validation (DIAG_REF), exactly like any other unknown
200
+ * target. Nothing loops, nothing guesses. */
201
+ #define YEP_JS_MAX_RESOURCES 1024
202
+ #define YEP_JS_MAX_ANCHORS 1024
203
+ #define YEP_JS_MAX_REFSITES 8192
204
+ #define YEP_JS_URI_MAX 512
205
+ #define YEP_JS_MAX_SCOPE 256 /* the runtime dynamic-scope stack */
206
+
207
+ /* One schema RESOURCE: a canonical (fragment-free) URI naming the
208
+ * schema object that established it with "$id" — pointer fragments
209
+ * walk from that node. The document root is resource 0 (the empty
210
+ * base "" when the schema has no "$id"). */
211
+ typedef struct {
212
+ char* uri;
213
+ uint32_t root;
214
+ } js_resource;
215
+
216
+ /* A plain-name fragment: canonical URI + '#' + name -> the node.
217
+ * `dynamic` distinguishes "$dynamicAnchor" (the $dynamicRef
218
+ * extension points) from "$anchor". `res` is the owning resource
219
+ * index (anchors belong to the resource of their nearest "$id"). */
220
+ typedef struct {
221
+ char* key;
222
+ uint32_t node;
223
+ uint32_t res;
224
+ uint8_t dynamic;
225
+ } js_anchor;
226
+
227
+ /* A "$ref"/"$dynamicRef" site: the canonical base URI it resolves
228
+ * against, and that base resource's root (where fragment-only
229
+ * pointers start walking). */
230
+ typedef struct {
231
+ uint32_t site;
232
+ char* base;
233
+ uint32_t base_root;
234
+ } js_refsite;
235
+
236
+ /* The compiled schema's identifier map (built once by the crawl at
237
+ * compile time, read-only afterwards — the document law). Everything
238
+ * it owns dies with yep_js_resources_free. */
239
+ typedef struct {
240
+ js_resource* res;
241
+ uint32_t res_n;
242
+ js_anchor* anc;
243
+ uint32_t anc_n;
244
+ js_refsite* site;
245
+ uint32_t site_n;
246
+ uint32_t* rindex; /* node id -> owning resource index (UINT32_MAX unvisited) */
247
+ uint32_t rindex_n;
248
+ } js_resources;
249
+
250
+ /* The constructor: one bounded DFS over the schema DOM collecting
251
+ * every $id/$anchor/$dynamicAnchor and $ref/$dynamicRef site. NULL on
252
+ * allocation failure. */
253
+ js_resources* yep_js_resources_crawl(const yep_dom* d, uint32_t root);
254
+ void yep_js_resources_free(js_resources* r);
255
+
256
+ /* Lookups (linear over the bounded tables): resource by canonical
257
+ * URI; anchor by key (URI + '#' + name); a resource's DYNAMIC anchor
258
+ * by plain name (the dynamic-scope search's per-resource probe); a
259
+ * ref site's base. Each returns 1 found, 0 absent. */
260
+ int js_res_find(const js_resources* r, const char* uri, uint32_t* idx_out);
261
+ int js_anchor_find(const js_resources* r, const char* key, size_t key_len, uint32_t* node_out,
262
+ uint8_t* dyn_out);
263
+ int js_anchor_dynamic_in_res(const js_resources* r, uint32_t res_idx, const char* name,
264
+ size_t name_len, uint32_t* node_out);
265
+ int js_refsite_find(const js_resources* r, uint32_t site_node, const char** base,
266
+ uint32_t* base_root);
267
+
268
+ /* URI-reference resolution (RFC 3986 section 5.2, the exercised
269
+ * subset: schemes, authorities, path merge with dot-segment removal,
270
+ * query carry). Produces the canonical fragment-free form. 0 ok, -1
271
+ * overlong (out holds ""). */
272
+ int js_uri_resolve(const char* base, const char* ref, size_t ref_len, char* out, size_t cap);
273
+
106
274
  /* jsonschema.c's driver: applies the schema tree (its own DOM) to
107
275
  * every instance document root, emitting into `rep`. `cache` is the
108
276
  * compiled schema's retained pattern programs (NULL: none — the
109
- * one-shot face). Returns 0, -1 on OOM. */
277
+ * one-shot face). `res` is the compiled schema's identifier map (the
278
+ * resources/anchors/ref-site bases the reference machinery resolves
279
+ * through; NULL: none — every reference beyond a bare "#/..." pointer
280
+ * stays unresolvable). Returns 0, -1 on OOM. */
110
281
  int yep_jsonschema_run(const yep_dom* schema_dom, uint32_t schema_root, const yep_dom* instance_dom,
111
282
  const uint32_t* doc_roots, uint32_t doc_count, yeptris_validate_report* rep,
112
- const yep_re_cache* cache);
283
+ const yep_re_cache* cache, const js_resources* res);
113
284
 
114
285
  /* The report constructor (validate.c owns the report machinery): a
115
286
  * fresh empty report, NULL on allocation failure. */
@@ -124,6 +295,51 @@ yeptris_validate_report* yep_validate_report_new(void);
124
295
  struct yeptris_schema;
125
296
  yeptris_schema* yep_schema_compile_st(const char* bytes, size_t n, YeptrisStatus* st);
126
297
 
298
+ /* The validation-family selector shared by both routes (#902): CORE_12
299
+ * and JSON_12 resolve to their resolvers (json_family set for the
300
+ * strict lane); every other schema is a parse-compat resolver, not a
301
+ * family — 0 with the thread error channel set, exactly like the DOM
302
+ * face's ARG rejection. */
303
+ int yep_validate_schema_family(YeptrisSchema schema, const struct yep_resolver** fam,
304
+ int* json_family);
305
+
306
+ /* ---- the tag-driven schema hook (#906 slice 4) --------------------------- */
307
+
308
+ /* The compiled schema's read-only evaluation view: everything the
309
+ * keyword walk reads, borrowed from the handle (the REGISTRY LAW
310
+ * applies — the handle must outlive every view taken from it). */
311
+ typedef struct {
312
+ const yep_dom* dom; /* the schema's retained tree */
313
+ uint32_t sroot; /* its document-0 root */
314
+ const yep_re_cache* cache; /* retained pattern programs */
315
+ const js_resources* res; /* the identifier map */
316
+ } yep_schema_view;
317
+
318
+ /* compile.c: fills *out from the handle. NULL handle fills zeros. */
319
+ void yep_schema_view_of(const yeptris_schema* s, yep_schema_view* out);
320
+
321
+ /* jsonschema.c: applies the bound schema's root to ONE instance
322
+ * subtree. `inst` is the CALLER'S walk context (the DOM route's
323
+ * yep_vctx) — its path prefix (the tag site), report, line index and
324
+ * guards are shared, so the subtree's misses land at the tag site's
325
+ * path + the schema's instance pointers with the offending node's
326
+ * position, and the cap law holds across the whole report. The
327
+ * context's scratch pointers (path buffer, line index) may have been
328
+ * reallocated on return — the caller frees them as before. Returns 0,
329
+ * -1 on OOM (ctx.oom set; the walk unwinds). */
330
+ int yep_jsonschema_apply_subtree(const yep_dom* schema_dom, uint32_t schema_root, yep_vctx* inst,
331
+ uint32_t inst_root, const yep_re_cache* cache,
332
+ const js_resources* res);
333
+
334
+ /* ---- the structured output face (#906 slice 5) ---------------------------
335
+ *
336
+ * output.c: the report -> JSON transform (the published BASIC shape;
337
+ * the byte contract lives on the public header). The keyword names
338
+ * behind the code-derived keywordLocation pointers — the one table
339
+ * (the output SSOT): a code without a keyword row writes the root
340
+ * pointer "". */
341
+ const char* yep_validate_output_keyword(uint32_t code);
342
+
127
343
  #ifdef __cplusplus
128
344
  }
129
345
  #endif