diff options
author | Pawel Jakub Dawidek <pjd@FreeBSD.org> | 2015-01-30 12:31:29 +0000 |
---|---|---|
committer | Pawel Jakub Dawidek <pjd@FreeBSD.org> | 2015-01-30 12:31:29 +0000 |
commit | c06165279dbc4450c29f8f304126bc43687adef1 (patch) | |
tree | 043d03748ab77027ef8a5a10e38199fbb5cfaa3a /lib/libnv | |
parent | 1c9b585695f7993c3b9c7db91245dbeecb92fe47 (diff) | |
download | src-c06165279dbc4450c29f8f304126bc43687adef1.tar.gz src-c06165279dbc4450c29f8f304126bc43687adef1.zip |
Handle empty nvlists correctly.
Submitted by: Mariusz Zaborski <oshogbo@FreeBSD.org>
Notes
Notes:
svn path=/head/; revision=277925
Diffstat (limited to 'lib/libnv')
-rw-r--r-- | lib/libnv/nvlist.c | 51 |
1 files changed, 35 insertions, 16 deletions
diff --git a/lib/libnv/nvlist.c b/lib/libnv/nvlist.c index a94b3da2e64b..5330c53f4614 100644 --- a/lib/libnv/nvlist.c +++ b/lib/libnv/nvlist.c @@ -356,7 +356,8 @@ nvlist_dump_error_check(const nvlist_t *nvl, int fd, int level) void nvlist_dump(const nvlist_t *nvl, int fd) { - nvpair_t *nvp; + const nvlist_t *tmpnvl; + nvpair_t *nvp, *tmpnvp; int level; level = 0; @@ -386,13 +387,17 @@ nvlist_dump(const nvlist_t *nvl, int fd) break; case NV_TYPE_NVLIST: dprintf(fd, "\n"); - nvl = nvpair_get_nvlist(nvp); - if (nvlist_dump_error_check(nvl, fd, level + 1)) { - nvl = nvlist_get_parent(nvl, (void **)&nvp); + tmpnvl = nvpair_get_nvlist(nvp); + if (nvlist_dump_error_check(tmpnvl, fd, level + 1)) break; + tmpnvp = nvlist_first_nvpair(tmpnvl); + if (tmpnvp != NULL) { + nvl = tmpnvl; + nvp = tmpnvp; + level++; + continue; } - level++; - continue; + break; case NV_TYPE_DESCRIPTOR: dprintf(fd, " %d\n", nvpair_get_descriptor(nvp)); break; @@ -436,7 +441,8 @@ nvlist_fdump(const nvlist_t *nvl, FILE *fp) size_t nvlist_size(const nvlist_t *nvl) { - const nvpair_t *nvp; + const nvlist_t *tmpnvl; + const nvpair_t *nvp, *tmpnvp; size_t size; NVLIST_ASSERT(nvl); @@ -450,10 +456,14 @@ nvlist_size(const nvlist_t *nvl) if (nvpair_type(nvp) == NV_TYPE_NVLIST) { size += sizeof(struct nvlist_header); size += nvpair_header_size() + 1; - nvl = nvpair_get_nvlist(nvp); - PJDLOG_ASSERT(nvl->nvl_error == 0); - nvp = nvlist_first_nvpair(nvl); - continue; + tmpnvl = nvpair_get_nvlist(nvp); + PJDLOG_ASSERT(tmpnvl->nvl_error == 0); + tmpnvp = nvlist_first_nvpair(tmpnvl); + if (tmpnvp != NULL) { + nvl = tmpnvl; + nvp = tmpnvp; + continue; + } } else { size += nvpair_size(nvp); } @@ -575,7 +585,8 @@ nvlist_xpack(const nvlist_t *nvl, int64_t *fdidxp, size_t *sizep) { unsigned char *buf, *ptr; size_t left, size; - nvpair_t *nvp; + const nvlist_t *tmpnvl; + nvpair_t *nvp, *tmpnvp; NVLIST_ASSERT(nvl); @@ -618,10 +629,18 @@ nvlist_xpack(const nvlist_t *nvl, int64_t *fdidxp, size_t *sizep) ptr = nvpair_pack_string(nvp, ptr, &left); break; case NV_TYPE_NVLIST: - nvl = nvpair_get_nvlist(nvp); - nvp = nvlist_first_nvpair(nvl); - ptr = nvlist_pack_header(nvl, ptr, &left); - continue; + tmpnvl = nvpair_get_nvlist(nvp); + ptr = nvlist_pack_header(tmpnvl, ptr, &left); + if (ptr == NULL) + goto out; + tmpnvp = nvlist_first_nvpair(tmpnvl); + if (tmpnvp != NULL) { + nvl = tmpnvl; + nvp = tmpnvp; + continue; + } + ptr = nvpair_pack_nvlist_up(ptr, &left); + break; case NV_TYPE_DESCRIPTOR: ptr = nvpair_pack_descriptor(nvp, ptr, fdidxp, &left); break; |