Merge pull request #1256 from brauner/2016-09-06/remove_atoi

remove atoi
This commit is contained in:
Serge Hallyn 2016-11-21 22:46:21 -06:00 committed by GitHub
commit 7688de67c6
15 changed files with 380 additions and 106 deletions

View File

@ -61,7 +61,7 @@ struct lxc_arguments {
const char *share_ns[32]; // size must be greater than LXC_NS_MAX
/* for lxc-console */
int ttynum;
unsigned int ttynum;
char escape;
/* for lxc-wait */

View File

@ -2504,7 +2504,8 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
{
char veth1buf[IFNAMSIZ], *veth1;
char veth2buf[IFNAMSIZ], *veth2;
int bridge_index, err, mtu = 0;
int bridge_index, err;
unsigned int mtu = 0;
if (netdev->priv.veth_attr.pair) {
veth1 = netdev->priv.veth_attr.pair;
@ -2556,8 +2557,10 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
}
if (netdev->mtu) {
mtu = atoi(netdev->mtu);
INFO("Retrieved mtu %d", mtu);
if (lxc_safe_uint(netdev->mtu, &mtu) < 0)
WARN("Failed to parse mtu from.");
else
INFO("Retrieved mtu %d", mtu);
} else if (netdev->link) {
bridge_index = if_nametoindex(netdev->link);
if (bridge_index) {
@ -2706,6 +2709,7 @@ static int instantiate_vlan(struct lxc_handler *handler, struct lxc_netdev *netd
char peer[IFNAMSIZ];
int err;
static uint16_t vlan_cntr = 0;
unsigned int mtu = 0;
if (!netdev->link) {
ERROR("no link specified for vlan netdev");
@ -2735,7 +2739,12 @@ static int instantiate_vlan(struct lxc_handler *handler, struct lxc_netdev *netd
DEBUG("instantiated vlan '%s', ifindex is '%d'", " vlan1000",
netdev->ifindex);
if (netdev->mtu) {
err = lxc_netdev_set_mtu(peer, atoi(netdev->mtu));
if (lxc_safe_uint(netdev->mtu, &mtu) < 0) {
ERROR("Failed to retrieve mtu from: '%d'/'%s'.",
netdev->ifindex, netdev->name);
return -1;
}
err = lxc_netdev_set_mtu(peer, mtu);
if (err) {
ERROR("failed to set mtu '%s' for %s : %s",
netdev->mtu, peer, strerror(-err));
@ -4450,8 +4459,10 @@ void suggest_default_idmap(void)
p2++;
if (!*p2)
continue;
uid = atoi(p);
urange = atoi(p2);
if (lxc_safe_uint(p, &uid) < 0)
WARN("Could not parse UID.");
if (lxc_safe_uint(p2, &urange) < 0)
WARN("Could not parse UID range.");
}
fclose(f);
@ -4479,8 +4490,10 @@ void suggest_default_idmap(void)
p2++;
if (!*p2)
continue;
gid = atoi(p);
grange = atoi(p2);
if (lxc_safe_uint(p, &gid) < 0)
WARN("Could not parse GID.");
if (lxc_safe_uint(p2, &grange) < 0)
WARN("Could not parse GID range.");
}
fclose(f);

View File

@ -62,7 +62,7 @@ enum {
struct lxc_inetdev {
struct in_addr addr;
struct in_addr bcast;
int prefix;
unsigned int prefix;
};
struct lxc_route {
@ -80,7 +80,7 @@ struct lxc_inet6dev {
struct in6_addr addr;
struct in6_addr mcast;
struct in6_addr acast;
int prefix;
unsigned int prefix;
};
struct lxc_route6 {
@ -293,8 +293,8 @@ struct saved_nic {
struct lxc_conf {
int is_execute;
char *fstab;
int tty;
int pts;
unsigned int tty;
unsigned int pts;
int reboot;
int need_utmp_watch;
signed long personality;
@ -317,7 +317,7 @@ struct lxc_conf {
struct lxc_list hooks[NUM_LXC_HOOKS];
char *lsm_aa_profile;
int lsm_aa_allow_incomplete;
unsigned int lsm_aa_allow_incomplete;
char *lsm_se_context;
int tmp_umount_proc;
char *seccomp; // filename with the seccomp rules
@ -325,11 +325,11 @@ struct lxc_conf {
scmp_filter_ctx seccomp_ctx;
#endif
int maincmd_fd;
int autodev; // if 1, mount and fill a /dev at start
unsigned int autodev; // if 1, mount and fill a /dev at start
int haltsignal; // signal used to halt container
int rebootsignal; // signal used to reboot container
int stopsignal; // signal used to hard stop container
int kmsg; // if 1, create /dev/kmsg symlink
unsigned int kmsg; // if 1, create /dev/kmsg symlink
char *rcfile; // Copy of the top level rcfile we read
// Logfile and logleve can be set in a container config file.
@ -343,14 +343,14 @@ struct lxc_conf {
int inherit_ns_fd[LXC_NS_MAX];
int start_auto;
int start_delay;
unsigned int start_auto;
unsigned int start_delay;
int start_order;
struct lxc_list groups;
int nbd_idx;
/* unshare the mount namespace in the monitor */
int monitor_unshare;
unsigned int monitor_unshare;
/* set to true when rootfs has been setup */
bool rootfs_setup;
@ -377,7 +377,7 @@ struct lxc_conf {
gid_t init_gid;
/* indicator if the container will be destroyed on shutdown */
int ephemeral;
unsigned int ephemeral;
/* The facility to pass to syslog. Let's users establish as what type of
* program liblxc is supposed to write to the syslog. */

View File

@ -853,8 +853,12 @@ static int config_network_ipv4(const char *key, const char *value,
}
/* no prefix specified, determine it from the network class */
inetdev->prefix = prefix ? atoi(prefix) :
config_ip_prefix(&inetdev->addr);
if (prefix) {
if (lxc_safe_uint(prefix, &inetdev->prefix) < 0)
return -1;
} else {
inetdev->prefix = config_ip_prefix(&inetdev->addr);
}
/* if no broadcast address, let compute one from the
* prefix and address
@ -952,7 +956,8 @@ static int config_network_ipv6(const char *key, const char *value,
if (slash) {
*slash = '\0';
netmask = slash + 1;
inet6dev->prefix = atoi(netmask);
if (lxc_safe_uint(netmask, &inet6dev->prefix) < 0)
return -1;
}
if (!inet_pton(AF_INET6, valdup, &inet6dev->addr)) {
@ -1060,14 +1065,24 @@ static int config_init_cmd(const char *key, const char *value,
static int config_init_uid(const char *key, const char *value,
struct lxc_conf *lxc_conf)
{
lxc_conf->init_uid = atoi(value);
unsigned int init_uid;
if (lxc_safe_uint(value, &init_uid) < 0)
return -1;
lxc_conf->init_uid = init_uid;
return 0;
}
static int config_init_gid(const char *key, const char *value,
struct lxc_conf *lxc_conf)
{
lxc_conf->init_gid = atoi(value);
unsigned int init_gid;
if (lxc_safe_uint(value, &init_gid) < 0)
return -1;
lxc_conf->init_gid = init_gid;
return 0;
}
@ -1127,9 +1142,8 @@ static int config_personality(const char *key, const char *value,
static int config_pts(const char *key, const char *value,
struct lxc_conf *lxc_conf)
{
int maxpts = atoi(value);
lxc_conf->pts = maxpts;
if (lxc_safe_uint(value, &lxc_conf->pts) < 0)
return -1;
return 0;
}
@ -1138,15 +1152,20 @@ static int config_start(const char *key, const char *value,
struct lxc_conf *lxc_conf)
{
if(strcmp(key, "lxc.start.auto") == 0) {
lxc_conf->start_auto = atoi(value);
if (lxc_safe_uint(value, &lxc_conf->start_auto) < 0)
return -1;
if (lxc_conf->start_auto > 1)
return -1;
return 0;
}
else if (strcmp(key, "lxc.start.delay") == 0) {
lxc_conf->start_delay = atoi(value);
if (lxc_safe_uint(value, &lxc_conf->start_delay) < 0)
return -1;
return 0;
}
else if (strcmp(key, "lxc.start.order") == 0) {
lxc_conf->start_order = atoi(value);
if (lxc_safe_int(value, &lxc_conf->start_order) < 0)
return -1;
return 0;
}
SYSERROR("Unknown key: %s", key);
@ -1157,7 +1176,8 @@ static int config_monitor(const char *key, const char *value,
struct lxc_conf *lxc_conf)
{
if(strcmp(key, "lxc.monitor.unshare") == 0) {
lxc_conf->monitor_unshare = atoi(value);
if (lxc_safe_uint(value, &lxc_conf->monitor_unshare) < 0)
return -1;
return 0;
}
SYSERROR("Unknown key: %s", key);
@ -1240,9 +1260,8 @@ freak_out:
static int config_tty(const char *key, const char *value,
struct lxc_conf *lxc_conf)
{
int nbtty = atoi(value);
lxc_conf->tty = nbtty;
if (lxc_safe_uint(value, &lxc_conf->tty) < 0)
return -1;
return 0;
}
@ -1256,9 +1275,11 @@ static int config_ttydir(const char *key, const char *value,
static int config_kmsg(const char *key, const char *value,
struct lxc_conf *lxc_conf)
{
int v = atoi(value);
if (lxc_safe_uint(value, &lxc_conf->kmsg) < 0)
return -1;
lxc_conf->kmsg = v;
if (lxc_conf->kmsg > 1)
return -1;
return 0;
}
@ -1272,9 +1293,13 @@ static int config_lsm_aa_profile(const char *key, const char *value,
static int config_lsm_aa_incomplete(const char *key, const char *value,
struct lxc_conf *lxc_conf)
{
int v = atoi(value);
if (lxc_safe_uint(value, &lxc_conf->lsm_aa_allow_incomplete) < 0)
return -1;
lxc_conf->lsm_aa_allow_incomplete = v == 1 ? 1 : 0;
if (lxc_conf->lsm_aa_allow_incomplete > 1) {
ERROR("Wrong value for lxc.lsm_aa_allow_incomplete. Can only be set to 0 or 1");
return -1;
}
return 0;
}
@ -1306,10 +1331,12 @@ static int config_loglevel(const char *key, const char *value,
if (!value || strlen(value) == 0)
return 0;
if (value[0] >= '0' && value[0] <= '9')
newlevel = atoi(value);
else
if (value[0] >= '0' && value[0] <= '9') {
if (lxc_safe_int(value, &newlevel) < 0)
return -1;
} else {
newlevel = lxc_log_priority_to_int(value);
}
// store these values in the lxc_conf, and then try to set for
// actual current logging.
lxc_conf->loglevel = newlevel;
@ -1319,9 +1346,13 @@ static int config_loglevel(const char *key, const char *value,
static int config_autodev(const char *key, const char *value,
struct lxc_conf *lxc_conf)
{
int v = atoi(value);
if (lxc_safe_uint(value, &lxc_conf->autodev) < 0)
return -1;
lxc_conf->autodev = v;
if (lxc_conf->autodev > 1) {
ERROR("Wrong value for lxc.autodev. Can only be set to 0 or 1");
return -1;
}
return 0;
}
@ -2933,13 +2964,12 @@ bool network_new_hwaddrs(struct lxc_conf *conf)
static int config_ephemeral(const char *key, const char *value,
struct lxc_conf *lxc_conf)
{
int v = atoi(value);
if (lxc_safe_uint(value, &lxc_conf->ephemeral) < 0)
return -1;
if (v != 0 && v != 1) {
if (lxc_conf->ephemeral > 1) {
ERROR("Wrong value for lxc.ephemeral. Can only be set to 0 or 1");
return -1;
} else {
lxc_conf->ephemeral = v;
}
return 0;
@ -2951,7 +2981,7 @@ static int config_syslog(const char *key, const char *value,
int facility;
facility = lxc_syslog_priority_to_int(value);
if (facility == -EINVAL) {
ERROR("Wrong value for lxc.syslog");
ERROR("Wrong value for lxc.syslog.");
return -1;
}
@ -2962,12 +2992,16 @@ static int config_syslog(const char *key, const char *value,
static int config_no_new_privs(const char *key, const char *value,
struct lxc_conf *lxc_conf)
{
int v = atoi(value);
unsigned int v;
if (v != 0 && v != 1) {
if (lxc_safe_uint(value, &v) < 0)
return -1;
if (v > 1) {
ERROR("Wrong value for lxc.no_new_privs. Can only be set to 0 or 1");
return -1;
}
lxc_conf->no_new_privs = v ? true : false;
return 0;

View File

@ -362,14 +362,15 @@ int main(int argc, char *argv[])
ret = snprintf(logpath, sizeof(logpath), "%s/lxc-monitord.log",
(strcmp(LXCPATH, lxcpath) ? lxcpath : LOGPATH ) );
if (ret < 0 || ret >= sizeof(logpath))
return EXIT_FAILURE;
exit(EXIT_FAILURE);
ret = lxc_log_init(NULL, logpath, "NOTICE", "lxc-monitord", 0, lxcpath);
if (ret)
INFO("Failed to open log file %s, log will be lost", lxcpath);
lxc_log_options_no_override();
pipefd = atoi(argv[2]);
if (lxc_safe_int(argv[2], &pipefd) < 0)
exit(EXIT_FAILURE);
if (sigfillset(&mask) ||
sigdelset(&mask, SIGILL) ||
@ -378,7 +379,7 @@ int main(int argc, char *argv[])
sigdelset(&mask, SIGTERM) ||
sigprocmask(SIG_BLOCK, &mask, NULL)) {
SYSERROR("failed to set signal mask");
return 1;
exit(EXIT_FAILURE);
}
signal(SIGILL, lxc_monitord_sig_handler);
@ -428,7 +429,5 @@ int main(int argc, char *argv[])
ret = EXIT_SUCCESS;
NOTICE("monitor exiting");
out:
if (ret == 0)
return 0;
return 1;
exit(ret);
}

View File

@ -223,7 +223,10 @@ restart:
if (!strcmp(direntp->d_name, ".."))
continue;
fd = atoi(direntp->d_name);
if (lxc_safe_int(direntp->d_name, &fd) < 0) {
INFO("Could not parse file descriptor for: %s", direntp->d_name);
continue;
}
if (fd == fddir || fd == lxc_log_fd || fd == fd_to_ignore)
continue;

View File

@ -26,6 +26,7 @@
#include "arguments.h"
#include "list.h"
#include "log.h"
#include "utils.h"
lxc_log_define(lxc_autostart_ui, lxc);
static struct lxc_list *accumulate_list(char *input, char *delimiter, struct lxc_list *str_list);
@ -35,14 +36,31 @@ struct lxc_list *cmd_groups_list = NULL;
static int my_parser(struct lxc_arguments* args, int c, char* arg)
{
switch (c) {
case 'k': args->hardstop = 1; break;
case 'L': args->list = 1; break;
case 'r': args->reboot = 1; break;
case 's': args->shutdown = 1; break;
case 'a': args->all = 1; break;
case 'A': args->ignore_auto = 1; break;
case 'g': cmd_groups_list = accumulate_list( arg, ",", cmd_groups_list); break;
case 't': args->timeout = atoi(arg); break;
case 'k':
args->hardstop = 1;
break;
case 'L':
args->list = 1;
break;
case 'r':
args->reboot = 1;
break;
case 's':
args->shutdown = 1;
break;
case 'a':
args->all = 1;
break;
case 'A':
args->ignore_auto = 1;
break;
case 'g':
cmd_groups_list = accumulate_list(arg, ",", cmd_groups_list);
break;
case 't':
if (lxc_safe_long(arg, &args->timeout) < 0)
return -1;
break;
}
return 0;
}
@ -290,7 +308,9 @@ static int get_config_integer(struct lxc_container *c, char *key) {
return 0;
}
ret = atoi(value);
if (lxc_safe_int(value, &ret) < 0)
DEBUG("Could not parse config item.");
free(value);
return ret;

View File

@ -22,29 +22,29 @@
*/
#define _GNU_SOURCE
#include <stdio.h>
#undef _GNU_SOURCE
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <libgen.h>
#include <poll.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <lxc/lxccontainer.h>
#include "error.h"
#include "lxc.h"
#include "log.h"
#include "mainloop.h"
#include "arguments.h"
#include "commands.h"
#include "error.h"
#include "log.h"
#include "lxc.h"
#include "mainloop.h"
#include "utils.h"
lxc_log_define(lxc_console_ui, lxc);
@ -58,8 +58,13 @@ static char etoc(const char *expr)
static int my_parser(struct lxc_arguments* args, int c, char* arg)
{
switch (c) {
case 't': args->ttynum = atoi(arg); break;
case 'e': args->escape = etoc(arg); break;
case 't':
if (lxc_safe_uint(arg, &args->ttynum) < 0)
return -1;
break;
case 'e':
args->escape = etoc(arg);
break;
}
return 0;
}

View File

@ -58,10 +58,19 @@ static int my_checker(const struct lxc_arguments* args)
static int my_parser(struct lxc_arguments* args, int c, char* arg)
{
switch (c) {
case 'f': args->rcfile = arg; break;
case 's': return lxc_config_define_add(&defines, arg); break;
case 'u': args->uid = atoi(arg); break;
case 'g': args->gid = atoi(arg);
case 'f':
args->rcfile = arg;
break;
case 's':
return lxc_config_define_add(&defines, arg);
break;
case 'u':
if (lxc_safe_uint(arg, &args->uid) < 0)
return -1;
break;
case 'g':
if (lxc_safe_uint(arg, &args->gid) < 0)
return -1;
}
return 0;
}

View File

@ -459,8 +459,14 @@ static int ls_get(struct ls **m, size_t *size, const struct lxc_arguments *args,
goto put_and_next;
tmp = ls_get_config_item(c, "lxc.start.auto", running);
if (tmp)
l->autostart = atoi(tmp);
if (tmp) {
unsigned int astart = 0;
if (lxc_safe_uint(tmp, &astart) < 0)
WARN("Could not parse value for 'lxc.start.auto'.");
if (astart > 1)
DEBUG("Wrong value for 'lxc.start.auto = %d'.", astart);
l->autostart = astart == 1 ? true : false;
}
free(tmp);
if (running) {

View File

@ -38,15 +38,28 @@
lxc_log_define(lxc_stop_ui, lxc);
static int my_parser(struct lxc_arguments* args, int c, char* arg)
static int my_parser(struct lxc_arguments *args, int c, char *arg)
{
switch (c) {
case 'r': args->reboot = 1; break;
case 'W': args->nowait = 1; break;
case 't': args->timeout = atoi(arg); break;
case 'k': args->hardstop = 1; break;
case OPT_NO_LOCK: args->nolock = 1; break;
case OPT_NO_KILL: args->nokill = 1; break;
case 'r':
args->reboot = 1;
break;
case 'W':
args->nowait = 1;
break;
case 't':
if (lxc_safe_long(arg, &args->timeout) < 0)
return -1;
break;
case 'k':
args->hardstop = 1;
break;
case OPT_NO_LOCK:
args->nolock = 1;
break;
case OPT_NO_KILL:
args->nokill = 1;
break;
}
return 0;
}
@ -155,17 +168,14 @@ int main(int argc, char *argv[])
/* Set default timeout */
if (my_args.timeout == -2) {
if (my_args.hardstop) {
if (my_args.hardstop)
my_args.timeout = 0;
}
else {
else
my_args.timeout = 60;
}
}
if (my_args.nowait) {
if (my_args.nowait)
my_args.timeout = 0;
}
/* some checks */
if (!my_args.hardstop && my_args.timeout < -1) {

View File

@ -74,9 +74,16 @@ static int ct_alloc_cnt = 0;
static int my_parser(struct lxc_arguments* args, int c, char* arg)
{
switch (c) {
case 'd': delay = atoi(arg); break;
case 's': sort_by = arg[0]; break;
case 'r': sort_reverse = 1; break;
case 'd':
if (lxc_safe_int(arg, &delay) < 0)
return -1;
break;
case 's':
sort_by = arg[0];
break;
case 'r':
sort_reverse = 1;
break;
}
return 0;
}

View File

@ -1766,7 +1766,7 @@ int mount_proc_if_needed(const char *rootfs)
{
char path[MAXPATHLEN];
char link[20];
int linklen, ret;
int link_to_pid, linklen, ret;
int mypid;
ret = snprintf(path, MAXPATHLEN, "%s/proc/self", rootfs);
@ -1785,7 +1785,9 @@ int mount_proc_if_needed(const char *rootfs)
}
if (linklen < 0) /* /proc not mounted */
goto domount;
if (atoi(link) != mypid) {
if (lxc_safe_int(link, &link_to_pid) < 0)
return -1;
if (link_to_pid != mypid) {
/* wrong /procs mounted */
umount2(path, MNT_DETACH); /* ignore failure */
goto domount;
@ -1988,3 +1990,63 @@ int lxc_preserve_ns(const int pid, const char *ns)
return open(path, O_RDONLY | O_CLOEXEC);
}
int lxc_safe_uint(const char *numstr, unsigned int *converted)
{
char *err = NULL;
unsigned long int uli;
errno = 0;
uli = strtoul(numstr, &err, 0);
if (errno > 0)
return -errno;
if (!err || err == numstr || *err != '\0')
return -EINVAL;
if (uli > UINT_MAX)
return -ERANGE;
*converted = (unsigned int)uli;
return 0;
}
int lxc_safe_int(const char *numstr, int *converted)
{
char *err = NULL;
signed long int sli;
errno = 0;
sli = strtol(numstr, &err, 0);
if (errno > 0)
return -errno;
if (!err || err == numstr || *err != '\0')
return -EINVAL;
if (sli > INT_MAX)
return -ERANGE;
*converted = (int)sli;
return 0;
}
int lxc_safe_long(const char *numstr, long int *converted)
{
char *err = NULL;
signed long int sli;
errno = 0;
sli = strtol(numstr, &err, 0);
if (errno > 0)
return -errno;
if (!err || err == numstr || *err != '\0')
return -EINVAL;
if (sli > LONG_MAX)
return -ERANGE;
*converted = sli;
return 0;
}

View File

@ -316,4 +316,10 @@ int lxc_preserve_ns(const int pid, const char *ns);
/* Check whether a signal is blocked by a process. */
bool task_blocking_signal(pid_t pid, int signal);
/* Helper functions to parse numbers. */
int lxc_safe_uint(const char *numstr, unsigned int *converted);
int lxc_safe_int(const char *numstr, int *converted);
int lxc_safe_long(const char *numstr, long int *converted);
#endif /* __LXC_UTILS_H */

View File

@ -22,8 +22,11 @@
*/
#define _GNU_SOURCE
#define __STDC_FORMAT_MACROS
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <limits.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
@ -222,6 +225,100 @@ non_test_error:
exit(fret);
}
void test_lxc_safe_uint(void)
{
int ret;
unsigned int n;
size_t len = /* 2^64 = 21 - 1 */ 21;
char uint_max[len];
ret = snprintf(uint_max, len, "%lu", (unsigned long)UINT_MAX + 1);
if (ret < 0 || (size_t)ret >= len) {
lxc_error("%s\n", "Failed to create string via snprintf().");
exit(EXIT_FAILURE);
}
lxc_test_assert_abort((0 == lxc_safe_uint("1234345", &n)) && n == 1234345);
lxc_test_assert_abort((0 == lxc_safe_uint(" 345", &n)) && n == 345);
lxc_test_assert_abort((-EINVAL == lxc_safe_uint(" g345", &n)));
lxc_test_assert_abort((-EINVAL == lxc_safe_uint(" 3g45", &n)));
lxc_test_assert_abort((-EINVAL == lxc_safe_uint(" 345g", &n)));
lxc_test_assert_abort((-EINVAL == lxc_safe_uint("g345", &n)));
lxc_test_assert_abort((-EINVAL == lxc_safe_uint("3g45", &n)));
lxc_test_assert_abort((-EINVAL == lxc_safe_uint("345g", &n)));
lxc_test_assert_abort((-EINVAL == lxc_safe_uint("g345 ", &n)));
lxc_test_assert_abort((-EINVAL == lxc_safe_uint("3g45 ", &n)));
lxc_test_assert_abort((-EINVAL == lxc_safe_uint("345g ", &n)));
lxc_test_assert_abort((-EINVAL == lxc_safe_uint("g", &n)));
lxc_test_assert_abort((-EINVAL == lxc_safe_uint(" g345", &n)));
lxc_test_assert_abort((-ERANGE == lxc_safe_uint(uint_max, &n)));
}
void test_lxc_safe_int(void)
{
int ret;
signed int n;
size_t len = /* 2^64 = 21 - 1 */ 21;
char int_max[len];
ret = snprintf(int_max, len, "%ld", (signed long)INT_MAX + 1);
if (ret < 0 || (size_t)ret >= len) {
lxc_error("%s\n", "Failed to create string via snprintf().");
exit(EXIT_FAILURE);
}
lxc_test_assert_abort((0 == lxc_safe_int("1234345", &n)) && n == 1234345);
lxc_test_assert_abort((0 == lxc_safe_int(" 345", &n)) && n == 345);
lxc_test_assert_abort((0 == lxc_safe_int("-1234345", &n)) && n == -1234345);
lxc_test_assert_abort((0 == lxc_safe_int(" -345", &n)) && n == -345);
lxc_test_assert_abort((-EINVAL == lxc_safe_int(" g345", &n)));
lxc_test_assert_abort((-EINVAL == lxc_safe_int(" 3g45", &n)));
lxc_test_assert_abort((-EINVAL == lxc_safe_int(" 345g", &n)));
lxc_test_assert_abort((-EINVAL == lxc_safe_int("g345", &n)));
lxc_test_assert_abort((-EINVAL == lxc_safe_int("3g45", &n)));
lxc_test_assert_abort((-EINVAL == lxc_safe_int("345g", &n)));
lxc_test_assert_abort((-EINVAL == lxc_safe_int("g345 ", &n)));
lxc_test_assert_abort((-EINVAL == lxc_safe_int("3g45 ", &n)));
lxc_test_assert_abort((-EINVAL == lxc_safe_int("345g ", &n)));
lxc_test_assert_abort((-EINVAL == lxc_safe_int("g", &n)));
lxc_test_assert_abort((-EINVAL == lxc_safe_int(" g345", &n)));
lxc_test_assert_abort((-ERANGE == lxc_safe_int(int_max, &n)));
}
void test_lxc_safe_long(void)
{
int ret;
signed long int n;
size_t len = /* 2^64 = 21 - 1 */ 21;
char long_max[len];
ret = snprintf(long_max, len, "%lld", LLONG_MAX);
if (ret < 0 || (size_t)ret >= len) {
lxc_error("%s\n", "Failed to create string via snprintf().");
exit(EXIT_FAILURE);
}
lxc_test_assert_abort((0 == lxc_safe_long("1234345", &n)) && n == 1234345);
lxc_test_assert_abort((0 == lxc_safe_long(" 345", &n)) && n == 345);
lxc_test_assert_abort((0 == lxc_safe_long("-1234345", &n)) && n == -1234345);
lxc_test_assert_abort((0 == lxc_safe_long(" -345", &n)) && n == -345);
lxc_test_assert_abort((-EINVAL == lxc_safe_long(" g345", &n)));
lxc_test_assert_abort((-EINVAL == lxc_safe_long(" 3g45", &n)));
lxc_test_assert_abort((-EINVAL == lxc_safe_long(" 345g", &n)));
lxc_test_assert_abort((-EINVAL == lxc_safe_long("g345", &n)));
lxc_test_assert_abort((-EINVAL == lxc_safe_long("3g45", &n)));
lxc_test_assert_abort((-EINVAL == lxc_safe_long("345g", &n)));
lxc_test_assert_abort((-EINVAL == lxc_safe_long("g345 ", &n)));
lxc_test_assert_abort((-EINVAL == lxc_safe_long("3g45 ", &n)));
lxc_test_assert_abort((-EINVAL == lxc_safe_long("345g ", &n)));
lxc_test_assert_abort((-EINVAL == lxc_safe_long("g", &n)));
lxc_test_assert_abort((-EINVAL == lxc_safe_long(" g345", &n)));
if (LONG_MAX != LLONG_MAX)
lxc_test_assert_abort((-ERANGE == lxc_safe_long(long_max, &n)));
else
lxc_test_assert_abort((0 == lxc_safe_long(long_max, &n)) && n == LONG_MAX);
}
void test_lxc_string_replace(void)
{
char *s;
@ -280,6 +377,9 @@ int main(int argc, char *argv[])
test_lxc_string_in_array();
test_lxc_deslashify();
test_detect_ramfs_rootfs();
test_lxc_safe_uint();
test_lxc_safe_int();
test_lxc_safe_long();
exit(EXIT_SUCCESS);
}