lyb BUGFIX length of the string is always written
Fixes CESNET/netopeer2#1022
diff --git a/src/parser_lyb.c b/src/parser_lyb.c
index 5e84cc1..bf03674 100644
--- a/src/parser_lyb.c
+++ b/src/parser_lyb.c
@@ -195,49 +195,26 @@
* @brief Read a string.
*
* @param[in] str Destination buffer, is allocated.
- * @param[in] with_length Whether the string is preceded with its length or it ends at the end of this "sibling".
+ * @param[in] len_size Number of bytes on which the length of the string is written.
* @param[in] lybctx LYB context.
* @return LY_ERR value.
*/
static LY_ERR
-lyb_read_string(char **str, ly_bool with_length, struct lylyb_ctx *lybctx)
+lyb_read_string(char **str, uint8_t len_size, struct lylyb_ctx *lybctx)
{
- ly_bool next_chunk = 0;
- size_t len = 0, cur_len;
+ uint64_t len = 0;
+
+ assert((len_size == 1) || (len_size == 2) || (len_size == 4) || (len_size == 8));
*str = NULL;
- if (with_length) {
- lyb_read_number(&len, sizeof len, 2, lybctx);
- } else {
- /* read until the end of this "sibling" */
- len = LYB_LAST_SIBLING(lybctx).written;
- if (LYB_LAST_SIBLING(lybctx).position) {
- next_chunk = 1;
- }
- }
+ lyb_read_number(&len, sizeof len, len_size, lybctx);
*str = malloc((len + 1) * sizeof **str);
LY_CHECK_ERR_RET(!*str, LOGMEM(lybctx->ctx), LY_EMEM);
lyb_read((uint8_t *)*str, len, lybctx);
- while (next_chunk) {
- cur_len = LYB_LAST_SIBLING(lybctx).written;
- if (LYB_LAST_SIBLING(lybctx).position) {
- next_chunk = 1;
- } else {
- next_chunk = 0;
- }
-
- *str = ly_realloc(*str, (len + cur_len + 1) * sizeof **str);
- LY_CHECK_ERR_RET(!*str, LOGMEM(lybctx->ctx), LY_EMEM);
-
- lyb_read(((uint8_t *)*str) + len, cur_len, lybctx);
-
- len += cur_len;
- }
-
(*str)[len] = '\0';
return LY_SUCCESS;
}
@@ -254,7 +231,7 @@
* @return LY_ERR value.
*/
static LY_ERR
-lyb_read_term_value(const struct lysc_node_leaf *term, uint8_t **term_value, uint32_t *term_value_len,
+lyb_read_term_value(const struct lysc_node_leaf *term, uint8_t **term_value, uint64_t *term_value_len,
struct lylyb_ctx *lybctx)
{
uint32_t allocated_size;
@@ -454,11 +431,11 @@
}
/* meta name */
- ret = lyb_read_string(&meta_name, 1, lybctx->lybctx);
+ ret = lyb_read_string(&meta_name, sizeof(uint16_t), lybctx->lybctx);
LY_CHECK_GOTO(ret, cleanup);
/* meta value */
- ret = lyb_read_string(&meta_value, 0, lybctx->lybctx);
+ ret = lyb_read_string(&meta_value, sizeof(uint64_t), lybctx->lybctx);
LY_CHECK_GOTO(ret, cleanup);
dynamic = 1;
@@ -521,10 +498,10 @@
ns = calloc(1, sizeof *ns);
/* prefix */
- LY_CHECK_GOTO(ret = lyb_read_string(&ns->prefix, 1, lybctx), cleanup);
+ LY_CHECK_GOTO(ret = lyb_read_string(&ns->prefix, sizeof(uint16_t), lybctx), cleanup);
/* namespace */
- LY_CHECK_GOTO(ret = lyb_read_string(&ns->uri, 1, lybctx), cleanup);
+ LY_CHECK_GOTO(ret = lyb_read_string(&ns->uri, sizeof(uint16_t), lybctx), cleanup);
LY_CHECK_GOTO(ret = ly_set_add(set, ns, 1, NULL), cleanup);
ns = NULL;
@@ -581,7 +558,7 @@
LY_CHECK_GOTO(ret, cleanup);
/* prefix, may be empty */
- ret = lyb_read_string(&prefix, 1, lybctx);
+ ret = lyb_read_string(&prefix, sizeof(uint16_t), lybctx);
LY_CHECK_GOTO(ret, cleanup);
if (!prefix[0]) {
free(prefix);
@@ -589,7 +566,7 @@
}
/* namespace, may be empty */
- ret = lyb_read_string(&module_name, 1, lybctx);
+ ret = lyb_read_string(&module_name, sizeof(uint16_t), lybctx);
LY_CHECK_GOTO(ret, cleanup);
if (!module_name[0]) {
free(module_name);
@@ -597,7 +574,7 @@
}
/* name */
- ret = lyb_read_string(&name, 1, lybctx);
+ ret = lyb_read_string(&name, sizeof(uint16_t), lybctx);
LY_CHECK_GOTO(ret, cleanup);
/* format */
@@ -608,7 +585,7 @@
LY_CHECK_GOTO(ret, cleanup);
/* value */
- ret = lyb_read_string(&value, 0, lybctx);
+ ret = lyb_read_string(&value, sizeof(uint64_t), lybctx);
LY_CHECK_ERR_GOTO(ret, ly_free_prefix_data(format, val_prefix_data), cleanup);
dynamic = 1;
@@ -977,7 +954,7 @@
LY_ERR ret;
ly_bool dynamic;
uint8_t *term_value;
- uint32_t term_value_len;
+ uint64_t term_value_len;
ret = lyb_read_term_value((struct lysc_node_leaf *)snode, &term_value, &term_value_len, lybctx->lybctx);
LY_CHECK_RET(ret);
@@ -1059,19 +1036,19 @@
lyb_read_number(&flags, sizeof flags, sizeof flags, lybctx->lybctx);
/* parse prefix */
- ret = lyb_read_string(&prefix, 1, lybctx->lybctx);
+ ret = lyb_read_string(&prefix, sizeof(uint16_t), lybctx->lybctx);
LY_CHECK_GOTO(ret, cleanup);
/* parse module key */
- ret = lyb_read_string(&module_key, 1, lybctx->lybctx);
+ ret = lyb_read_string(&module_key, sizeof(uint16_t), lybctx->lybctx);
LY_CHECK_GOTO(ret, cleanup);
/* parse name */
- ret = lyb_read_string(&name, 1, lybctx->lybctx);
+ ret = lyb_read_string(&name, sizeof(uint16_t), lybctx->lybctx);
LY_CHECK_GOTO(ret, cleanup);
/* parse value */
- ret = lyb_read_string(&value, 1, lybctx->lybctx);
+ ret = lyb_read_string(&value, sizeof(uint64_t), lybctx->lybctx);
LY_CHECK_ERR_GOTO(ret, ly_free_prefix_data(format, val_prefix_data), cleanup);
dynamic = 1;
@@ -1161,7 +1138,7 @@
}
/* read anydata content */
- ret = lyb_read_string(&value, 1, lybctx->lybctx);
+ ret = lyb_read_string(&value, sizeof(uint64_t), lybctx->lybctx);
LY_CHECK_GOTO(ret, error);
if (value_type == LYD_ANYDATA_LYB) {
diff --git a/src/printer_lyb.c b/src/printer_lyb.c
index 26f33d2..f792a3e 100644
--- a/src/printer_lyb.c
+++ b/src/printer_lyb.c
@@ -397,30 +397,47 @@
*
* @param[in] str String to write.
* @param[in] str_len Length of @p str.
- * @param[in] with_length Whether to precede the string with its length.
+ * @param[in] len_size Size of @ str_len in bytes.
* @param[in] out Out structure.
* @param[in] lybctx LYB context.
* @return LY_ERR value.
*/
static LY_ERR
-lyb_write_string(const char *str, size_t str_len, ly_bool with_length, struct ly_out *out, struct lylyb_ctx *lybctx)
+lyb_write_string(const char *str, size_t str_len, uint8_t len_size, struct ly_out *out, struct lylyb_ctx *lybctx)
{
+ ly_bool error;
+
if (!str) {
str = "";
LY_CHECK_ERR_RET(str_len, LOGINT(lybctx->ctx), LY_EINT);
}
+
if (!str_len) {
str_len = strlen(str);
}
- if (with_length) {
- /* print length on 2 bytes */
- if (str_len > UINT16_MAX) {
- LOGINT(lybctx->ctx);
- return LY_EINT;
- }
- LY_CHECK_RET(lyb_write_number(str_len, 2, out, lybctx));
+ switch (len_size) {
+ case sizeof(uint8_t):
+ error = str_len > UINT8_MAX;
+ break;
+ case sizeof(uint16_t):
+ error = str_len > UINT16_MAX;
+ break;
+ case sizeof(uint32_t):
+ error = str_len > UINT32_MAX;
+ break;
+ case sizeof(uint64_t):
+ error = str_len > UINT64_MAX;
+ break;
+ default:
+ error = 1;
}
+ if (error) {
+ LOGINT(lybctx->ctx);
+ return LY_EINT;
+ }
+
+ LY_CHECK_RET(lyb_write_number(str_len, len_size, out, lybctx));
LY_CHECK_RET(lyb_write(out, (const uint8_t *)str, str_len, lybctx));
@@ -442,7 +459,7 @@
/* model name length and model name */
if (mod) {
- LY_CHECK_RET(lyb_write_string(mod->name, 0, 1, out, lybctx));
+ LY_CHECK_RET(lyb_write_string(mod->name, 0, sizeof(uint16_t), out, lybctx));
} else {
lyb_write_number(0, 2, out, lybctx);
return LY_SUCCESS;
@@ -610,10 +627,10 @@
ns = set->objs[i];
/* prefix */
- LY_CHECK_RET(lyb_write_string(ns->prefix, 0, 1, out, lybctx));
+ LY_CHECK_RET(lyb_write_string(ns->prefix, 0, sizeof(uint16_t), out, lybctx));
/* namespace */
- LY_CHECK_RET(lyb_write_string(ns->uri, 0, 1, out, lybctx));
+ LY_CHECK_RET(lyb_write_string(ns->uri, 0, sizeof(uint16_t), out, lybctx));
}
break;
case LY_VALUE_JSON:
@@ -668,8 +685,8 @@
goto cleanup;
}
- /* Print the length of the data as 32-bit unsigned integer. */
- ret = lyb_write_number(value_len, sizeof(uint32_t), out, lybctx);
+ /* Print the length of the data as 64-bit unsigned integer. */
+ ret = lyb_write_number(value_len, sizeof(uint64_t), out, lybctx);
LY_CHECK_GOTO(ret, cleanup);
} else {
/* Fixed-length data. */
@@ -741,8 +758,8 @@
/* write the "default" metadata */
LY_CHECK_RET(lyb_write_start_siblings(out, lybctx->lybctx));
LY_CHECK_RET(lyb_print_model(out, wd_mod, lybctx->lybctx));
- LY_CHECK_RET(lyb_write_string("default", 0, 1, out, lybctx->lybctx));
- LY_CHECK_RET(lyb_write_string("true", 0, 0, out, lybctx->lybctx));
+ LY_CHECK_RET(lyb_write_string("default", 0, sizeof(uint16_t), out, lybctx->lybctx));
+ LY_CHECK_RET(lyb_write_string("true", 0, sizeof(uint16_t), out, lybctx->lybctx));
LY_CHECK_RET(lyb_write_stop_siblings(out, lybctx->lybctx));
}
@@ -755,10 +772,10 @@
LY_CHECK_RET(lyb_print_model(out, iter->annotation->module, lybctx->lybctx));
/* annotation name with length */
- LY_CHECK_RET(lyb_write_string(iter->name, 0, 1, out, lybctx->lybctx));
+ LY_CHECK_RET(lyb_write_string(iter->name, 0, sizeof(uint16_t), out, lybctx->lybctx));
/* metadata value */
- LY_CHECK_RET(lyb_write_string(lyd_get_meta_value(iter), 0, 0, out, lybctx->lybctx));
+ LY_CHECK_RET(lyb_write_string(lyd_get_meta_value(iter), 0, sizeof(uint64_t), out, lybctx->lybctx));
/* finish metadata sibling */
LY_CHECK_RET(lyb_write_stop_siblings(out, lybctx->lybctx));
@@ -798,13 +815,13 @@
LY_CHECK_RET(lyb_write_start_siblings(out, lybctx));
/* prefix */
- LY_CHECK_RET(lyb_write_string(iter->name.prefix, 0, 1, out, lybctx));
+ LY_CHECK_RET(lyb_write_string(iter->name.prefix, 0, sizeof(uint16_t), out, lybctx));
/* namespace */
- LY_CHECK_RET(lyb_write_string(iter->name.module_name, 0, 1, out, lybctx));
+ LY_CHECK_RET(lyb_write_string(iter->name.module_name, 0, sizeof(uint16_t), out, lybctx));
/* name */
- LY_CHECK_RET(lyb_write_string(iter->name.name, 0, 1, out, lybctx));
+ LY_CHECK_RET(lyb_write_string(iter->name.name, 0, sizeof(uint16_t), out, lybctx));
/* format */
LY_CHECK_RET(lyb_write_number(iter->format, 1, out, lybctx));
@@ -813,7 +830,7 @@
LY_CHECK_RET(lyb_print_prefix_data(out, iter->format, iter->val_prefix_data, lybctx));
/* value */
- LY_CHECK_RET(lyb_write_string(iter->value, 0, 0, out, lybctx));
+ LY_CHECK_RET(lyb_write_string(iter->value, 0, sizeof(uint64_t), out, lybctx));
/* finish attribute sibling */
LY_CHECK_RET(lyb_write_stop_siblings(out, lybctx));
@@ -959,16 +976,16 @@
LY_CHECK_RET(lyb_write_number(opaq->flags, sizeof opaq->flags, out, lybctx));
/* prefix */
- LY_CHECK_RET(lyb_write_string(opaq->name.prefix, 0, 1, out, lybctx));
+ LY_CHECK_RET(lyb_write_string(opaq->name.prefix, 0, sizeof(uint16_t), out, lybctx));
/* module reference */
- LY_CHECK_RET(lyb_write_string(opaq->name.module_name, 0, 1, out, lybctx));
+ LY_CHECK_RET(lyb_write_string(opaq->name.module_name, 0, sizeof(uint16_t), out, lybctx));
/* name */
- LY_CHECK_RET(lyb_write_string(opaq->name.name, 0, 1, out, lybctx));
+ LY_CHECK_RET(lyb_write_string(opaq->name.name, 0, sizeof(uint16_t), out, lybctx));
/* value */
- LY_CHECK_RET(lyb_write_string(opaq->value, 0, 1, out, lybctx));
+ LY_CHECK_RET(lyb_write_string(opaq->value, 0, sizeof(uint64_t), out, lybctx));
/* format */
LY_CHECK_RET(lyb_write_number(opaq->format, 1, out, lybctx));
@@ -1032,7 +1049,7 @@
}
/* followed by the content */
- LY_CHECK_GOTO(ret = lyb_write_string(str, (size_t)len, 1, out, lybctx), cleanup);
+ LY_CHECK_GOTO(ret = lyb_write_string(str, (size_t)len, sizeof(uint64_t), out, lybctx), cleanup);
cleanup:
ly_out_free(out2, NULL, 1);