yeptris 0.6.53.0-powerpc64le-linux → 0.6.55.1-powerpc64le-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f652f42d46c1ea6642ce221feec2ed9d0e1838e09454ca8c97cb9f17d2e1b05a
4
- data.tar.gz: 2d22ac11686b416e0f910673b50be0549455ab3faf2f9f4228963ee121202011
3
+ metadata.gz: fe145d6313f44dbc27dea1123d2c2d22c0aedd1412e05a28ec0a4c122fb5f3fe
4
+ data.tar.gz: 01dbaf018c8b23fc223e20c62bae3e3fc3ae22696a3bcf96fccf78c13008f746
5
5
  SHA512:
6
- metadata.gz: 753c7221e3e6d99d237e9e67008369426843040f8bfe2861936b35692e44b1749fe6af3cb1385ccbd4e8f08686ad16c45ed7f077a06693b0458042042926358f
7
- data.tar.gz: 19bd51b1bb1edd73d17a053cbfdddcbd8a18c9ed055a6b191f328cef51e49ca656b9f0c1d49c62ad78f8274a0143b139301c232537c61c1766a0d3bce4642b7d
6
+ metadata.gz: 7297b661facad32bb5b26a3f26a25b3e98bbda7a490fad9114f325be56a6dc3f4cdf8bf4e399f7948c071f47ce4bfcb33c5c84602c686369de3bf6730b9c8493
7
+ data.tar.gz: c77ceaa8e7f7075162818d4af5ba183e842fd8ef3f047effea5fa97373e6c32f7c202faf1859b30529e33f11c0ab86e757c03d3b840d898a515e1416a2fd23e9
@@ -11,8 +11,8 @@
11
11
 
12
12
  #define YEPTRIS_VERSION_MAJOR 0
13
13
  #define YEPTRIS_VERSION_MINOR 6
14
- #define YEPTRIS_VERSION_PATCH 53
15
- #define YEPTRIS_VERSION_STRING "0.6.53"
14
+ #define YEPTRIS_VERSION_PATCH 55
15
+ #define YEPTRIS_VERSION_STRING "0.6.55"
16
16
 
17
17
  #ifdef __cplusplus
18
18
  extern "C" {
@@ -320,6 +320,10 @@ module Yeptris
320
320
  target = merge_target.pop
321
321
  merge_into(target, done) if target
322
322
  when DOCUMENT_START
323
+ # anchors are per-document (the engine memo law; PyYAML's
324
+ # composer resets per document): a later document's alias
325
+ # must not resolve into an earlier one's name
326
+ anchors.clear
323
327
  docs.push(nil)
324
328
  end
325
329
  i += FIELDS
data/lib/yeptris.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  module Yeptris
4
4
  # The gem's version lives in the parent namespace's file — the last
5
5
  # internal require (yeptris/version) retired with it.
6
- VERSION = "0.6.53.0".freeze
6
+ VERSION = "0.6.55.1".freeze
7
7
 
8
8
  # Informational notices are OPT-IN (yeptris-ruby#217): consumers
9
9
  # embed yeptris inside CLIs that assert clean stderr, and a
data/libyeptris.so CHANGED
Binary file
@@ -3,7 +3,7 @@
3
3
  cmake_minimum_required(VERSION 3.20)
4
4
 
5
5
  project(yeptris
6
- VERSION 0.6.53
6
+ VERSION 0.6.55
7
7
  DESCRIPTION "Ultra-fast YAML 1.2 parser, emitter and streamer in C"
8
8
  LANGUAGES C CXX
9
9
  )
@@ -105,8 +105,8 @@ typedef struct {
105
105
  uint8_t style;
106
106
  uint8_t flags; /* YEPTRIS_EF_* */
107
107
  uint8_t tag_id; /* resolved implicit tag (YeptrisTagId, resolve.h) —
108
- * the typing SSOT, so hosts never re-scan. Uses the
109
- * struct's pad byte: sizeof stays 36 (ABI-pinned) */
108
+ * the typing SSOT, so hosts never re-scan (the
109
+ * struct is 44B, ABI-pinned; the bindings mirror it) */
110
110
  uint32_t line;
111
111
  uint32_t col;
112
112
  uint32_t end_line; /* #179: libyaml end_mark semantics (see the
@@ -92,7 +92,9 @@ static void yep_avx2_copy_count3(char* dst, const char* src, size_t len, char c0
92
92
  memcpy(dst + i, src + i, len - i);
93
93
  }
94
94
  size_t ta = 0, tb = 0, td = 0;
95
- yep_text_count3_scalar(dst + i, len - i, c0, c1, c2, &ta, &tb, &td);
95
+ if (i < len) { /* NULL dst + 0 offset is still UB to form */
96
+ yep_text_count3_scalar(dst + i, len - i, c0, c1, c2, &ta, &tb, &td);
97
+ }
96
98
  *n0 = a + ta;
97
99
  *n1 = b + tb;
98
100
  *n2 = d + td;
@@ -590,6 +590,8 @@ void ytap_sink(yep_ytape* t, yep_sink* sink) {
590
590
  sink->on_scalar = yt_on_scalar;
591
591
  sink->on_block_open = yt_on_block_open;
592
592
  sink->on_block_item = yt_on_block_item;
593
+ sink->compose = 1; /* the tape replays into a DOM: the composer's
594
+ * undefined-alias rejection stays at parse time */
593
595
  }
594
596
 
595
597
  /* ---- replay ---- */
@@ -95,6 +95,15 @@ static int yep_transcode_utf16(const yep_allocator* sys, int big_endian, const u
95
95
  static int yep_transcode_utf32(const yep_allocator* sys, int big_endian, const unsigned char* src,
96
96
  size_t len, unsigned char** out, size_t* out_len, size_t* err_pos) {
97
97
  size_t units = len / 4;
98
+ if (len % 4 != 0) {
99
+ /* a dangling final unit is an error, not a silent truncation
100
+ * (the UTF-16 twin rejects its own; the header contract says
101
+ * truncated units error at the offending byte) */
102
+ if (err_pos != NULL) {
103
+ *err_pos = units * 4;
104
+ }
105
+ return -2;
106
+ }
98
107
  unsigned char* dst = yep_alloc(sys, len ? len : 1);
99
108
  if (dst == NULL) {
100
109
  return -1;
@@ -29,8 +29,14 @@ void yep_rec_free(yep_rec_store* s) {
29
29
  yep_rec_init(s);
30
30
  }
31
31
 
32
- static uint32_t arena_put(yep_rec_store* s, const char* p, uint32_t len) {
32
+ /* Returns 0 ok / -1 OOM. On OOM the record is NOT committed (the
33
+ * caller unwinds before s->n++): the old drop-the-string form left
34
+ * value_len set with offset 0, so materialize read whatever string
35
+ * lived at the arena head - or past a NULL arena on first-alloc
36
+ * failure. */
37
+ static int arena_put(yep_rec_store* s, const char* p, uint32_t len, uint32_t* off) {
33
38
  if (len == 0 || p == NULL) {
39
+ *off = 0;
34
40
  return 0;
35
41
  }
36
42
  if (s->arena_len + len > s->arena_cap) {
@@ -40,15 +46,15 @@ static uint32_t arena_put(yep_rec_store* s, const char* p, uint32_t len) {
40
46
  }
41
47
  char* na = realloc(s->arena, cap);
42
48
  if (na == NULL) {
43
- return 0; /* OOM: the string is dropped, not fatal */
49
+ return -1;
44
50
  }
45
51
  s->arena = na;
46
52
  s->arena_cap = cap;
47
53
  }
48
54
  memcpy(s->arena + s->arena_len, p, len);
49
- uint32_t off = (uint32_t)s->arena_len;
55
+ *off = (uint32_t)s->arena_len;
50
56
  s->arena_len += len;
51
- return off;
57
+ return 0;
52
58
  }
53
59
 
54
60
  int yep_rec_on_event(void* ctx, const yep_event* ev) {
@@ -116,11 +122,17 @@ int yep_rec_on_event(void* ctx, const yep_event* ev) {
116
122
  r->col = ev->col;
117
123
  r->end_line = ev->end_line;
118
124
  r->end_col = ev->end_col;
119
- r->value_off = arena_put(s, (const char*)ev->value.p, (uint32_t)ev->value.len);
125
+ if (arena_put(s, (const char*)ev->value.p, (uint32_t)ev->value.len, &r->value_off) != 0) {
126
+ return -1;
127
+ }
120
128
  r->value_len = (uint32_t)ev->value.len;
121
- r->anchor_off = arena_put(s, (const char*)ev->anchor.p, (uint32_t)ev->anchor.len);
129
+ if (arena_put(s, (const char*)ev->anchor.p, (uint32_t)ev->anchor.len, &r->anchor_off) != 0) {
130
+ return -1;
131
+ }
122
132
  r->anchor_len = (uint32_t)ev->anchor.len;
123
- r->tag_off = arena_put(s, (const char*)ev->tag.p, (uint32_t)ev->tag.len);
133
+ if (arena_put(s, (const char*)ev->tag.p, (uint32_t)ev->tag.len, &r->tag_off) != 0) {
134
+ return -1;
135
+ }
124
136
  r->tag_len = (uint32_t)ev->tag.len;
125
137
  s->n++;
126
138
  return 0;
@@ -161,7 +161,7 @@ YEPTRIS_API const YeptrisEvent* yeptris_iterparse_next(YeptrisIterparse it, size
161
161
  yep_engine_destroy(eng);
162
162
  if (rc == -1) {
163
163
  it->done = 1;
164
- it->status = YEPTRIS_ERROR_PARSE;
164
+ it->status = err != NULL ? YEPTRIS_ERROR_PARSE : YEPTRIS_ERROR_MEMORY;
165
165
  if (it->store.n == 0) {
166
166
  if (!it->emitted_stream_start) {
167
167
  /* the engine emitted +STR before failing: match it */
@@ -74,9 +74,13 @@ YEPTRIS_API YeptrisStatus yeptris_recorder_feed(YeptrisRecorder rec, const char*
74
74
  if (err != NULL) {
75
75
  rec->err_line = err->line;
76
76
  rec->err_col = err->col;
77
+ rec->status = YEPTRIS_ERROR_PARSE;
78
+ } else {
79
+ /* a clean error channel means the SINK failed: the capture
80
+ * ran out of memory, the bytes never were a parse error */
81
+ rec->status = YEPTRIS_ERROR_MEMORY;
77
82
  }
78
- rec->final_fed = 1; /* a parse error kills the stream */
79
- rec->status = YEPTRIS_ERROR_PARSE;
83
+ rec->final_fed = 1; /* a failed feed kills the stream */
80
84
  return rec->status;
81
85
  }
82
86
  rec->status = YEPTRIS_OK;
@@ -85,6 +85,14 @@ void* yep_arena_alloc(yep_arena* arena, size_t size, size_t align) {
85
85
  if (arena == NULL || size == 0 || !yep_align_ok(align)) {
86
86
  return NULL;
87
87
  }
88
+ /* a hostile size near SIZE_MAX must FAIL the fit test, not wrap
89
+ * start+size past the pointer space and pass it (the sizing sums
90
+ * below stay inside the guard's slack) */
91
+ if (size > (SIZE_MAX - align) / 2) {
92
+ /* half the pointer space: both the fit test's start+size and
93
+ * the new-block payload sums stay wrap-free below this */
94
+ return NULL;
95
+ }
88
96
 
89
97
  yep_arena_block* b = arena->head;
90
98
  uintptr_t base = (uintptr_t)b + sizeof(yep_arena_block);
@@ -43,6 +43,13 @@ void* yep_pool_alloc(yep_pool* pool, size_t size, size_t align) {
43
43
  if (pool == NULL || size == 0 || !yep_align_ok(align)) {
44
44
  return NULL;
45
45
  }
46
+ /* mirror of the arena guard: the fit test's start+size and the
47
+ * payload sums must not wrap on a hostile size */
48
+ if (size > (SIZE_MAX - align) / 2) {
49
+ /* half the pointer space: both the fit test's start+size and
50
+ * the new-block payload sums stay wrap-free below this */
51
+ return NULL;
52
+ }
46
53
 
47
54
  yep_block* b = pool->head;
48
55
  if (b == NULL) { /* the lazy first block (#157) */
@@ -1435,13 +1435,22 @@ static int e_alias(yep_engine* e, yep_event* ev) {
1435
1435
  return e_fail(e, YEP_ERR_UNEXPECTED, star);
1436
1436
  }
1437
1437
  uint32_t target = anchor_id_of(e, name);
1438
- if (target == 0 || (target <= e->anchor_serial && e->anchor_placed != NULL &&
1439
- e->anchor_placed[target - 1] == 0)) {
1438
+ /* libyaml's scanner/composer split: the scanner emits the ALIAS
1439
+ * event for ANY name; the composer rejects what it cannot resolve
1440
+ * ("found undefined alias"). Rejecting here unconditionally made
1441
+ * event streams (recorder/pull/push) diverge from libyaml's for
1442
+ * every dangling alias ({?\n:*c }, the nightly's r101), so the
1443
+ * rejection rides the sink's compose bit: document builders (the
1444
+ * DOM, the record tape) keep the parse-time error, event
1445
+ * consumers carry the name for their host's resolution (the ruby
1446
+ * materializer raises; the py loader does since this change too). */
1447
+ if (e->sink != NULL && e->sink->compose &&
1448
+ (target == 0 || (target <= e->anchor_serial && e->anchor_placed != NULL &&
1449
+ e->anchor_placed[target - 1] == 0))) {
1440
1450
  /* undefined, or defined-but-not-yet-placed: the props scan
1441
1451
  * registers the name before the anchor's node reaches the
1442
1452
  * output, so an alias here would precede its definition and
1443
- * the re-parse would reject the document (libyaml: "found
1444
- * undefined alias") */
1453
+ * the re-parse would reject the document */
1445
1454
  e->pos = star;
1446
1455
  return e_fail(e, YEP_ERR_UNDEFINED_ALIAS, star);
1447
1456
  }
@@ -110,6 +110,13 @@ typedef struct yep_sink {
110
110
  int (*on_scalar)(void* ctx, const struct yep_view* value, const struct yep_view* tag,
111
111
  const struct yep_view* anchor, uint32_t anchor_id, uint8_t tag_id,
112
112
  uint8_t style, uint8_t implicit, uint8_t flow, int borrowed);
113
+ /* Document composers (libyaml's scanner/composer split): the
114
+ * scanner emits the ALIAS event for ANY name, while a sink that
115
+ * builds a document rejects an alias whose target is undefined or
116
+ * not yet placed ("found undefined alias"). Set for the DOM and
117
+ * record-tape routes; event consumers (recorder/pull/push) leave
118
+ * it 0 so their streams carry every alias like libyaml's. */
119
+ uint8_t compose;
113
120
  } yep_sink;
114
121
 
115
122
  /* Value facts for on_block_pair (the classified value classes the
@@ -410,7 +410,8 @@ engine_enter:
410
410
  .on_block_pair = dom_on_block_pair,
411
411
  .on_scalar = dom_on_scalar,
412
412
  .on_block_open = dom_on_block_open,
413
- .on_block_item = dom_on_block_item};
413
+ .on_block_item = dom_on_block_item,
414
+ .compose = 1};
414
415
  }
415
416
  int rc = 0;
416
417
  if (have_tape && !norm_kept_raw && ytap_flow_rooted(&yt) == 0) {
@@ -248,7 +248,8 @@ YEPTRIS_API YeptrisStatus yeptris_schema_load(const char* source, size_t len, Ye
248
248
  .on_block_pair = dom_on_block_pair,
249
249
  .on_scalar = dom_on_scalar,
250
250
  .on_block_open = dom_on_block_open,
251
- .on_block_item = dom_on_block_item};
251
+ .on_block_item = dom_on_block_item,
252
+ .compose = 1};
252
253
  if (eng == NULL || dom == NULL) {
253
254
  st = YEPTRIS_ERROR_MEMORY;
254
255
  goto out;
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yeptris
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.53.0
4
+ version: 0.6.55.1
5
5
  platform: powerpc64le-linux
6
6
  authors:
7
7
  - Ribose Inc.