aboutsummaryrefslogtreecommitdiffstats
path: root/unpack.c
diff options
context:
space:
mode:
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;
}