Skip to content

Commit 451bbb2

Browse files
authored
Merge pull request #629 from gcampbell512/endian-fix
Fix big endian issues writing and reading .LYB files
2 parents 6338688 + 856a40e commit 451bbb2

File tree

3 files changed

+49
-32
lines changed

3 files changed

+49
-32
lines changed

src/parser_lyb.c

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <stdlib.h>
1818
#include <string.h>
1919
#include <inttypes.h>
20+
#include <endian.h>
2021

2122
#include "libyang.h"
2223
#include "common.h"
@@ -32,7 +33,7 @@ lyb_read(const char *data, uint8_t *buf, size_t count, struct lyb_state *lybs)
3233
{
3334
int ret = 0, i, empty_chunk_i;
3435
size_t to_read;
35-
LYB_META meta;
36+
uint8_t meta_buf[LYB_META_BYTES];
3637

3738
assert(data && lybs);
3839

@@ -76,12 +77,9 @@ lyb_read(const char *data, uint8_t *buf, size_t count, struct lyb_state *lybs)
7677

7778
if (empty_chunk_i > -1) {
7879
/* read the next chunk meta information */
79-
memcpy(&meta, data + ret, LYB_META_BYTES);
80-
lybs->written[empty_chunk_i] = 0;
81-
lybs->inner_chunks[empty_chunk_i] = 0;
82-
83-
memcpy(&lybs->written[empty_chunk_i], &meta, LYB_SIZE_BYTES);
84-
memcpy(&lybs->inner_chunks[empty_chunk_i], ((uint8_t *)&meta) + LYB_SIZE_BYTES, LYB_INCHUNK_BYTES);
80+
memcpy(meta_buf, data + ret, LYB_META_BYTES);
81+
lybs->written[empty_chunk_i] = meta_buf[0];
82+
lybs->inner_chunks[empty_chunk_i] = meta_buf[1];
8583

8684
/* remember whether there is a following chunk or not */
8785
lybs->position[empty_chunk_i] = (lybs->written[empty_chunk_i] == LYB_SIZE_MAX ? 1 : 0);
@@ -113,7 +111,9 @@ lyb_read_number(uint64_t *num, size_t bytes, const char *data, struct lyb_state
113111
static int
114112
lyb_read_enum(uint64_t *enum_idx, uint32_t count, const char *data, struct lyb_state *lybs)
115113
{
114+
int ret = 0;
116115
size_t bytes;
116+
uint64_t tmp_enum = 0;
117117

118118
if (count < (2 << 8)) {
119119
bytes = 1;
@@ -125,18 +125,24 @@ lyb_read_enum(uint64_t *enum_idx, uint32_t count, const char *data, struct lyb_s
125125
bytes = 4;
126126
}
127127

128-
return lyb_read_number(enum_idx, bytes, data, lybs);
128+
/* The enum is always read into a uint64_t buffer */
129+
ret = lyb_read_number(&tmp_enum, bytes, data, lybs);
130+
*enum_idx = le64toh(tmp_enum);
131+
132+
return ret;
129133
}
130134

131135
static int
132136
lyb_read_string(const char *data, char **str, int with_length, struct lyb_state *lybs)
133137
{
134138
int next_chunk = 0, r, ret = 0;
135139
size_t len = 0, cur_len;
140+
uint8_t len_buf[2];
136141

137142
if (with_length) {
138-
ret += (r = lyb_read(data, (uint8_t *)&len, 2, lybs));
143+
ret += (r = lyb_read(data, len_buf, 2, lybs));
139144
LYB_HAVE_READ_GOTO(r, data, error);
145+
len = len_buf[0] | (len_buf[1] << 8);
140146
} else {
141147
/* read until the end of this subtree */
142148
len = lybs->written[lybs->used - 1];
@@ -190,7 +196,7 @@ lyb_read_stop_subtree(struct lyb_state *lybs)
190196
static int
191197
lyb_read_start_subtree(const char *data, struct lyb_state *lybs)
192198
{
193-
LYB_META meta;
199+
uint8_t meta_buf[LYB_META_BYTES];
194200

195201
if (lybs->used == lybs->size) {
196202
lybs->size += LYB_STATE_STEP;
@@ -200,14 +206,11 @@ lyb_read_start_subtree(const char *data, struct lyb_state *lybs)
200206
LY_CHECK_ERR_RETURN(!lybs->written || !lybs->position || !lybs->inner_chunks, LOGMEM(NULL), -1);
201207
}
202208

203-
memcpy(&meta, data, LYB_META_BYTES);
209+
memcpy(meta_buf, data, LYB_META_BYTES);
204210

205211
++lybs->used;
206-
lybs->written[lybs->used - 1] = 0;
207-
lybs->inner_chunks[lybs->used - 1] = 0;
208-
209-
memcpy(&lybs->written[lybs->used - 1], &meta, LYB_SIZE_BYTES);
210-
memcpy(&lybs->inner_chunks[lybs->used - 1], ((uint8_t *)&meta) + LYB_SIZE_BYTES, LYB_INCHUNK_BYTES);
212+
lybs->written[lybs->used - 1] = meta_buf[0];
213+
lybs->inner_chunks[lybs->used - 1] = meta_buf[LYB_SIZE_BYTES];
211214
lybs->position[lybs->used - 1] = (lybs->written[lybs->used - 1] == LYB_SIZE_MAX ? 1 : 0);
212215

213216
return LYB_META_BYTES;
@@ -219,14 +222,16 @@ lyb_parse_model(struct ly_ctx *ctx, const char *data, const struct lys_module **
219222
int r, ret = 0;
220223
char *mod_name = NULL, mod_rev[11];
221224
uint16_t rev = 0;
225+
uint8_t tmp_buf[2];
222226

223227
/* model name */
224228
ret += (r = lyb_read_string(data, &mod_name, 1, lybs));
225229
LYB_HAVE_READ_GOTO(r, data, error);
226230

227231
/* revision */
228-
ret += (r = lyb_read(data, (uint8_t *)&rev, sizeof rev, lybs));
232+
ret += (r = lyb_read(data, tmp_buf, sizeof tmp_buf, lybs));
229233
LYB_HAVE_READ_GOTO(r, data, error);
234+
rev = tmp_buf[0] | (tmp_buf[1] << 8);
230235

231236
if (rev) {
232237
sprintf(mod_rev, "%04u-%02u-%02u", ((rev & 0xFE00) >> 9) + 2000, (rev & 0x01E0) >> 5, (rev & 0x001F));
@@ -430,15 +435,18 @@ lyb_parse_val_1(struct ly_ctx *ctx, struct lys_type *type, LY_DATA_TYPE value_ty
430435
case LY_TYPE_INT16:
431436
case LY_TYPE_UINT16:
432437
ret = lyb_read_number((uint64_t *)&value->uint16, 2, data, lybs);
438+
value->uint16 = le16toh(value->uint16);
433439
break;
434440
case LY_TYPE_INT32:
435441
case LY_TYPE_UINT32:
436442
ret = lyb_read_number((uint64_t *)&value->uint32, 4, data, lybs);
443+
value->uint32 = le32toh(value->uint32);
437444
break;
438445
case LY_TYPE_DEC64:
439446
case LY_TYPE_INT64:
440447
case LY_TYPE_UINT64:
441448
ret = lyb_read_number((uint64_t *)&value->uint64, 8, data, lybs);
449+
value->uint64 = le64toh(value->uint64);
442450
break;
443451
default:
444452
return -1;
@@ -1101,10 +1109,12 @@ static int
11011109
lyb_parse_data_models(struct ly_ctx *ctx, const char *data, struct lyb_state *lybs)
11021110
{
11031111
int i, r, ret = 0;
1112+
uint8_t mod_count_buf[2];
11041113

11051114
/* read model count */
1106-
ret += (r = lyb_read(data, (uint8_t *)&lybs->mod_count, 2, lybs));
1115+
ret += (r = lyb_read(data, mod_count_buf, 2, lybs));
11071116
LYB_HAVE_READ_RETURN(r, data, -1);
1117+
lybs->mod_count = mod_count_buf[0] | (mod_count_buf[1] << 8);
11081118

11091119
lybs->models = malloc(lybs->mod_count * sizeof *lybs->models);
11101120
LY_CHECK_ERR_RETURN(!lybs->models, LOGMEM(NULL), -1);

src/printer_lyb.c

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <string.h>
1919
#include <assert.h>
2020
#include <stdint.h>
21+
#include <endian.h>
2122

2223
#include "common.h"
2324
#include "printer.h"
@@ -323,7 +324,7 @@ lyb_write(struct lyout *out, const uint8_t *buf, size_t count, struct lyb_state
323324
{
324325
int ret, i, full_chunk_i;
325326
size_t r, to_write;
326-
LYB_META meta;
327+
uint8_t meta_buf[LYB_META_BYTES];
327328

328329
assert(out && lybs);
329330

@@ -359,10 +360,10 @@ lyb_write(struct lyout *out, const uint8_t *buf, size_t count, struct lyb_state
359360

360361
if (full_chunk_i > -1) {
361362
/* write the meta information (inner chunk count and chunk size) */
362-
memcpy(&meta, &lybs->written[full_chunk_i], LYB_SIZE_BYTES);
363-
memcpy(((uint8_t *)&meta) + LYB_SIZE_BYTES, &lybs->inner_chunks[full_chunk_i], LYB_INCHUNK_BYTES);
363+
meta_buf[0] = lybs->written[full_chunk_i] & 0xFF;
364+
meta_buf[1] = lybs->inner_chunks[full_chunk_i] & 0xFF;
364365

365-
r = ly_write_skipped(out, lybs->position[full_chunk_i], (char *)&meta, LYB_META_BYTES);
366+
r = ly_write_skipped(out, lybs->position[full_chunk_i], (char *)meta_buf, LYB_META_BYTES);
366367
if (r < LYB_META_BYTES) {
367368
return -1;
368369
}
@@ -397,13 +398,13 @@ static int
397398
lyb_write_stop_subtree(struct lyout *out, struct lyb_state *lybs)
398399
{
399400
int r;
400-
LYB_META meta;
401+
uint8_t meta_buf[LYB_META_BYTES];
401402

402403
/* write the meta chunk information */
403-
memcpy(&meta, &lybs->written[lybs->used - 1], LYB_SIZE_BYTES);
404-
memcpy(((uint8_t *)&meta) + LYB_SIZE_BYTES, &lybs->inner_chunks[lybs->used - 1], LYB_INCHUNK_BYTES);
404+
meta_buf[0] = lybs->written[lybs->used - 1] & 0xFF;
405+
meta_buf[1] = lybs->inner_chunks[lybs->used - 1] & 0xFF;
405406

406-
r = ly_write_skipped(out, lybs->position[lybs->used - 1], (char *)&meta, LYB_META_BYTES);
407+
r = ly_write_skipped(out, lybs->position[lybs->used - 1], (char *)&meta_buf, LYB_META_BYTES);
407408
if (r < LYB_META_BYTES) {
408409
return -1;
409410
}
@@ -448,9 +449,13 @@ lyb_write_number(uint64_t num, size_t bytes, struct lyout *out, struct lyb_state
448449
size_t i;
449450
uint8_t byte;
450451

452+
num = htole64(num);
451453
for (i = 0; i < bytes; ++i) {
452454
byte = *(((uint8_t *)&num) + i);
453455
ret += lyb_write(out, &byte, 1, lybs);
456+
if (ret < 0) {
457+
break;
458+
}
454459
}
455460

456461
return ret;
@@ -489,7 +494,7 @@ lyb_write_string(const char *str, size_t str_len, int with_length, struct lyout
489494

490495
if (with_length) {
491496
/* print length on 2 bytes */
492-
ret += (r = lyb_write(out, (uint8_t *)&str_len, 2, lybs));
497+
ret += (r = lyb_write_number(str_len, 2, out, lybs));
493498
if (r < 0) {
494499
return -1;
495500
}
@@ -534,8 +539,7 @@ lyb_print_model(struct lyout *out, const struct lys_module *mod, struct lyb_stat
534539

535540
revision |= r;
536541
}
537-
538-
ret += (r = lyb_write(out, (uint8_t *)&revision, sizeof revision, lybs));
542+
ret += (r = lyb_write_number(revision, sizeof revision, out, lybs));
539543
if (r < 0) {
540544
return -1;
541545
}
@@ -625,7 +629,7 @@ lyb_print_data_models(struct lyout *out, const struct lyd_node *root, struct lyb
625629
}
626630

627631
/* now write module count on 2 bytes */
628-
ret += lyb_write(out, (uint8_t *)&mod_count, 2, lybs);
632+
ret += lyb_write_number(mod_count, 2, out, lybs);
629633

630634
/* and all the used models */
631635
for (i = 0; i < mod_count; ++i) {

src/tree_data.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7335,6 +7335,7 @@ lyd_lyb_data_length(const char *data)
73357335
{
73367336
const char *ptr;
73377337
uint16_t i, mod_count, str_len;
7338+
uint8_t tmp_buf[2];
73387339
LYB_META meta;
73397340

73407341
if (!data) {
@@ -7353,13 +7354,15 @@ lyd_lyb_data_length(const char *data)
73537354
++ptr;
73547355

73557356
/* models */
7356-
memcpy(&mod_count, ptr, 2);
7357+
memcpy(tmp_buf, ptr, 2);
73577358
ptr += 2;
7359+
mod_count = tmp_buf[0] | (tmp_buf[1] << 8);
73587360

73597361
for (i = 0; i < mod_count; ++i) {
73607362
/* model name */
7361-
memcpy(&str_len, ptr, 2);
7363+
memcpy(tmp_buf, ptr, 2);
73627364
ptr += 2;
7365+
str_len = tmp_buf[0] | (tmp_buf[1] << 8);
73637366

73647367
ptr += str_len;
73657368

0 commit comments

Comments
 (0)