aboutsummaryrefslogtreecommitdiffstats
path: root/unpack.c
diff options
context:
space:
mode:
authorTomasz Kramkowski <tk@the-tk.com>2021-08-07 15:10:44 +0100
committerTomasz Kramkowski <tk@the-tk.com>2021-08-07 15:17:22 +0100
commit98ef6a8510d555148528e4fffb6cfa587dbd4c46 (patch)
treef79f0f69a4be5b940d5a6b554102d062fa021719 /unpack.c
parentf382d3caec8c30c3884d5616da04f5a663afa39e (diff)
downloadpack-98ef6a8510d555148528e4fffb6cfa587dbd4c46.tar.gz
pack-98ef6a8510d555148528e4fffb6cfa587dbd4c46.tar.xz
pack-98ef6a8510d555148528e4fffb6cfa587dbd4c46.zip
always va_end even when an error occurs
Diffstat (limited to 'unpack.c')
-rw-r--r--unpack.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/unpack.c b/unpack.c
index 472cc8c..3143931 100644
--- a/unpack.c
+++ b/unpack.c
@@ -40,6 +40,7 @@ enum pack_status unpack(const void *buf_, size_t size, const char *fmt, ...)
{
enum pack_endian endianness = PACK_ENDIAN_BIG;
const unsigned char *buf = buf_;
+ enum pack_status ret = PACK_OK;
size_t offset = 0;
va_list ap;
@@ -73,7 +74,7 @@ enum pack_status unpack(const void *buf_, size_t size, const char *fmt, ...)
errno = 0;
c = strtoull(&fmt[i], &end, 10);
if ((c == ULLONG_MAX && errno == ERANGE) || c > SIZE_MAX)
- return PACK_FMTINVAL;
+ SET_AND_GOTO(ret, PACK_FMTINVAL, stop);
count = c;
i += end - &fmt[i];
} else if (fmt[i] == '*') {
@@ -95,15 +96,16 @@ enum pack_status unpack(const void *buf_, size_t size, const char *fmt, ...)
case PACK_TYPE_FLOAT: arg.f = va_arg(ap, float *); break;
case PACK_TYPE_DOUBLE: arg.d = va_arg(ap, double *); break;
case PACK_TYPE_PADDING: break;
- default: return PACK_FMTINVAL;
+ default: SET_AND_GOTO(ret, PACK_FMTINVAL, stop);
}
t = fmt[i];
s = getsize(t);
tr_debug("s: %" PRIuSIZE, s);
- if (s == (size_t)-1) return PACK_FMTINVAL;
+ if (s == (size_t)-1) SET_AND_GOTO(ret, PACK_FMTINVAL, stop);
- if (size - offset < s * count) return PACK_TOOSMALL;
+ if (size - offset < s * count)
+ SET_AND_GOTO(ret, PACK_TOOSMALL, stop);
if (t == PACK_TYPE_PADDING) goto skip;
@@ -149,7 +151,8 @@ skip:
offset += s * count;
}
+stop:
va_end(ap);
- return PACK_OK;
+ return ret;
}