#include <errno.h>
#include <assert.h>
#include <inttypes.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int safe_atou(const char *s, unsigned *ret_u) {
char *x = NULL;
unsigned long l;
/* strtoul() is happy to parse negative values, and silently
* converts them to unsigned values without generating an
* error. We want a clean error, hence let's look for the "-"
* prefix on our own, and generate an error. But let's do so
* only after strtoul() validated that the string is clean
* otherwise, so that we return EINVAL preferably over
* ERANGE. */
errno = 0;
if (errno > 0)
return -errno;
if (!x || x == s || *x)
return -EINVAL;
if (s[0] == '-')
return -ERANGE;
if ((unsigned long) (unsigned) l != l)
return -ERANGE;
*ret_u = (unsigned) l;
return 0;
}
int main(void) {
unsigned res = 1337;
const char *tests[] = {"0day", "day0", "42", "-0", "-1", "0", "1337", "0p3nn3t", 0};
const char **test = tests;
while (*test) {
int err = safe_atou(*test, &res);
printf("\ninput: %.6s, err: %d, val: %i", *test
, err
, res
); test++;
}
}
I2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxhc3NlcnQuaD4KI2luY2x1ZGUgPGludHR5cGVzLmg+CiNpbmNsdWRlIDxsb2NhbGUuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgoKaW50IHNhZmVfYXRvdShjb25zdCBjaGFyICpzLCB1bnNpZ25lZCAqcmV0X3UpIHsKICAgICAgICBjaGFyICp4ID0gTlVMTDsKICAgICAgICB1bnNpZ25lZCBsb25nIGw7CgogICAgICAgIGFzc2VydChzKTsKICAgICAgICBhc3NlcnQocmV0X3UpOwoKICAgICAgICAvKiBzdHJ0b3VsKCkgaXMgaGFwcHkgdG8gcGFyc2UgbmVnYXRpdmUgdmFsdWVzLCBhbmQgc2lsZW50bHkKICAgICAgICAgKiBjb252ZXJ0cyB0aGVtIHRvIHVuc2lnbmVkIHZhbHVlcyB3aXRob3V0IGdlbmVyYXRpbmcgYW4KICAgICAgICAgKiBlcnJvci4gV2Ugd2FudCBhIGNsZWFuIGVycm9yLCBoZW5jZSBsZXQncyBsb29rIGZvciB0aGUgIi0iCiAgICAgICAgICogcHJlZml4IG9uIG91ciBvd24sIGFuZCBnZW5lcmF0ZSBhbiBlcnJvci4gQnV0IGxldCdzIGRvIHNvCiAgICAgICAgICogb25seSBhZnRlciBzdHJ0b3VsKCkgdmFsaWRhdGVkIHRoYXQgdGhlIHN0cmluZyBpcyBjbGVhbgogICAgICAgICAqIG90aGVyd2lzZSwgc28gdGhhdCB3ZSByZXR1cm4gRUlOVkFMIHByZWZlcmFibHkgb3ZlcgogICAgICAgICAqIEVSQU5HRS4gKi8KCiAgICAgICAgCiAgICAgICAgZXJybm8gPSAwOwogICAgICAgIGwgPSBzdHJ0b3VsKHMsICZ4LCAwKTsKICAgICAgICBpZiAoZXJybm8gPiAwKQogICAgICAgICAgICAgICAgcmV0dXJuIC1lcnJubzsKICAgICAgICBpZiAoIXggfHwgeCA9PSBzIHx8ICp4KQogICAgICAgICAgICAgICAgcmV0dXJuIC1FSU5WQUw7CiAgICAgICAgaWYgKHNbMF0gPT0gJy0nKQogICAgICAgICAgICAgICAgcmV0dXJuIC1FUkFOR0U7CiAgICAgICAgaWYgKCh1bnNpZ25lZCBsb25nKSAodW5zaWduZWQpIGwgIT0gbCkKICAgICAgICAgICAgICAgIHJldHVybiAtRVJBTkdFOwoKICAgICAgICAqcmV0X3UgPSAodW5zaWduZWQpIGw7CiAgICAgICAgcmV0dXJuIDA7Cn0KCmludCBtYWluKHZvaWQpIHsKICAgIHVuc2lnbmVkIHJlcyA9IDEzMzc7CiAgICBjb25zdCBjaGFyICp0ZXN0c1tdID0geyIwZGF5IiwgImRheTAiLCAiNDIiLCAiLTAiLCAiLTEiLCAiMCIsICIxMzM3IiwgIjBwM25uM3QiLCAwfTsKICAgIGNvbnN0IGNoYXIgKip0ZXN0ID0gdGVzdHM7CiAgICB3aGlsZSAoKnRlc3QpIHsKICAgICAgICBpbnQgZXJyID0gc2FmZV9hdG91KCp0ZXN0LCAmcmVzKTsKICAgICAgICBwcmludGYoIlxuaW5wdXQ6ICUuNnMsIGVycjogJWQsIHZhbDogJWkiLCAqdGVzdCwgZXJyLCByZXMpOwogICAgICAgIHRlc3QrKzsKICAgIH0KCn0KCg==
input: 0day, err: -22, val: 1337
input: day0, err: -22, val: 1337
input: 42, err: 0, val: 42
input: -0, err: -34, val: 42
input: -1, err: -34, val: 42
input: 0, err: 0, val: 0
input: 1337, err: 0, val: 1337
input: 0p3nn3, err: -22, val: 1337