Skip to content

Commit 2db30d7

Browse files
committed
parser data UPDATE flag for parsing LYB with non-matching ctx
Refs #2443
1 parent 7199faa commit 2db30d7

File tree

2 files changed

+30
-15
lines changed

2 files changed

+30
-15
lines changed

src/parser_data.h

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* @author Michal Vasko <[email protected]>
55
* @brief Data parsers for libyang
66
*
7-
* Copyright (c) 2015-2023 CESNET, z.s.p.o.
7+
* Copyright (c) 2015 - 2025 CESNET, z.s.p.o.
88
*
99
* This source code is licensed under BSD 3-Clause License (the "License").
1010
* You may not use this file except in compliance with the License.
@@ -149,7 +149,21 @@ struct ly_in;
149149
#define LYD_PARSE_OPAQ 0x040000 /**< Instead of silently ignoring data without definition, parse them into
150150
an opaq node. Do not combine with ::LYD_PARSE_STRICT (except for ::LYD_LYB). */
151151
#define LYD_PARSE_NO_STATE 0x080000 /**< Forbid state data in the parsed data. Usually used with ::LYD_VALIDATE_NO_STATE. */
152-
#define LYD_PARSE_LYB_MOD_UPDATE 0x100000 /**< Deprecated, ignored. */
152+
#define LYD_PARSE_LYB_SKIP_CTX_CHECK 0x100000 /**< Normally, when printing LYB data, the context hash is written into
153+
the data that describes the context (see ::ly_ctx_get_modules_hash()).
154+
Then, when parsing the data, the hash is compared with the current
155+
context and an error is generated if they do not match. The reason
156+
for that is that the data may be parsed incorrectly possibly
157+
leading to a crash. However, this hash restriction is too severe
158+
and the hash must match only with regard to the modules with actual
159+
YANG data in the LYB data to guarantee correct data parsing. In other
160+
words, if there is a module A in the printing context but no data
161+
of this module in the LYB data, the parsing context does not have
162+
to have module A loaded but the hash check will fail in that case.
163+
So, if you are able to guarantee that the parsing context will
164+
have all the required YANG modules in the same state as in the
165+
printed context you can use this flag to effectively soften the
166+
context restriction. */
153167
#define LYD_PARSE_ORDERED 0x200000 /**< Do not search for the correct place of each node but instead expect
154168
that the nodes are being parsed in the correct schema-based order,
155169
which is always true if the data were printed by libyang and not

src/parser_lyb.c

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1503,49 +1503,50 @@ lyb_parse_siblings(struct lyd_lyb_ctx *lybctx, struct lyd_node *parent, ly_bool
15031503
* @return LY_ERR value.
15041504
*/
15051505
static LY_ERR
1506-
lyb_parse_header(struct lylyb_parse_ctx *lybctx)
1506+
lyb_parse_header(struct lyd_lyb_ctx *lybctx)
15071507
{
15081508
uint8_t byte;
15091509
uint32_t data_hash, cur_hash;
1510+
struct lylyb_parse_ctx *pctx = lybctx->parse_ctx;
15101511

15111512
/* version */
15121513
byte = 0;
1513-
lyb_read(&byte, LYB_HEADER_VERSION_BITS, lybctx);
1514+
lyb_read(&byte, LYB_HEADER_VERSION_BITS, pctx);
15141515
if (byte != LYB_HEADER_VERSION_NUM) {
1515-
LOGERR(lybctx->ctx, LY_EINVAL, "Invalid LYB format version \"0x%" PRIx8 "\", expected \"0x%x\".",
1516+
LOGERR(pctx->ctx, LY_EINVAL, "Invalid LYB format version \"0x%" PRIx8 "\", expected \"0x%x\".",
15161517
byte, LYB_HEADER_VERSION_NUM);
15171518
return LY_EINVAL;
15181519
}
15191520

15201521
/* hash algorithm */
15211522
byte = 0;
1522-
lyb_read(&byte, LYB_HEADER_HASH_ALG_BITS, lybctx);
1523+
lyb_read(&byte, LYB_HEADER_HASH_ALG_BITS, pctx);
15231524
if (byte != LYB_HEADER_HASH_ALG_NUM) {
1524-
LOGERR(lybctx->ctx, LY_EINVAL, "Different LYB format hash algorithm \"0x%" PRIx8 "\" used, expected \"0x%x\".",
1525+
LOGERR(pctx->ctx, LY_EINVAL, "Different LYB format hash algorithm \"0x%" PRIx8 "\" used, expected \"0x%x\".",
15251526
byte, LYB_HEADER_HASH_ALG_NUM);
15261527
return LY_EINVAL;
15271528
}
15281529

15291530
/* shrink */
15301531
byte = 0;
1531-
lyb_read(&byte, LYB_HEADER_SHRINK_FLAG_BITS, lybctx);
1532+
lyb_read(&byte, LYB_HEADER_SHRINK_FLAG_BITS, pctx);
15321533
if (byte) {
1533-
lybctx->shrink = 1;
1534+
pctx->shrink = 1;
15341535
}
15351536

15361537
/* context hash */
15371538
data_hash = 0;
1538-
lyb_read((uint8_t *)&data_hash, LYB_HEADER_CTX_HASH_BITS, lybctx);
1539+
lyb_read((uint8_t *)&data_hash, LYB_HEADER_CTX_HASH_BITS, pctx);
15391540

15401541
if (!data_hash) {
15411542
/* fine for no data */
1542-
lybctx->empty_hash = 1;
1543-
} else {
1543+
pctx->empty_hash = 1;
1544+
} else if (!(lybctx->parse_opts & LYD_PARSE_LYB_SKIP_CTX_CHECK)) {
15441545
/* truncate context hash to the same bit size */
1545-
cur_hash = lyb_truncate_hash_nonzero(ly_ctx_get_modules_hash(lybctx->ctx), LYB_HEADER_CTX_HASH_BITS);
1546+
cur_hash = lyb_truncate_hash_nonzero(ly_ctx_get_modules_hash(pctx->ctx), LYB_HEADER_CTX_HASH_BITS);
15461547

15471548
if (data_hash != cur_hash) {
1548-
LOGERR(lybctx->ctx, LY_EINVAL, "Different current LYB context modules hash compared to the one stored in the "
1549+
LOGERR(pctx->ctx, LY_EINVAL, "Different current LYB context modules hash compared to the one stored in the "
15491550
"LYB data (0x%" PRIx32 " != 0x%" PRIx32 ").", data_hash, cur_hash);
15501551
return LY_EINVAL;
15511552
}
@@ -1593,7 +1594,7 @@ lyd_parse_lyb(const struct ly_ctx *ctx, const struct lysc_ext_instance *ext, str
15931594
LY_CHECK_GOTO(rc = lyd_parser_find_operation(parent, int_opts, &lybctx->op_node), cleanup);
15941595

15951596
/* read header */
1596-
rc = lyb_parse_header(lybctx->parse_ctx);
1597+
rc = lyb_parse_header(lybctx);
15971598
LY_CHECK_GOTO(rc, cleanup);
15981599

15991600
/* read sibling(s) */

0 commit comments

Comments
 (0)