The OpenBSD strtonum() uses very short error strings that can't
be translated usefully. Convert them to longer strings on error. Also use the longer strings for atomode() and atoid().
This commit is contained in:
@@ -75,20 +75,20 @@ atoid(const char *p, const char *sep, char **endp, const char **errstr)
|
|||||||
}
|
}
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
if (errstr != NULL)
|
if (errstr != NULL)
|
||||||
*errstr = N_("invalid");
|
*errstr = N_("invalid value");
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if ((errno == ERANGE && lval == LONG_MAX) || lval > INT_MAX) {
|
if ((errno == ERANGE && lval == LONG_MAX) || lval > INT_MAX) {
|
||||||
errno = ERANGE;
|
errno = ERANGE;
|
||||||
if (errstr != NULL)
|
if (errstr != NULL)
|
||||||
*errstr = N_("too large");
|
*errstr = N_("value too large");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if ((errno == ERANGE && lval == LONG_MIN) || lval < INT_MIN) {
|
if ((errno == ERANGE && lval == LONG_MIN) || lval < INT_MIN) {
|
||||||
errno = ERANGE;
|
errno = ERANGE;
|
||||||
if (errstr != NULL)
|
if (errstr != NULL)
|
||||||
*errstr = N_("too small");
|
*errstr = N_("value too small");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
rval = (id_t)lval;
|
rval = (id_t)lval;
|
||||||
@@ -103,14 +103,14 @@ atoid(const char *p, const char *sep, char **endp, const char **errstr)
|
|||||||
}
|
}
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
if (errstr != NULL)
|
if (errstr != NULL)
|
||||||
*errstr = N_("invalid");
|
*errstr = N_("invalid value");
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if ((errno == ERANGE && ulval == ULONG_MAX) || ulval > UINT_MAX) {
|
if ((errno == ERANGE && ulval == ULONG_MAX) || ulval > UINT_MAX) {
|
||||||
errno = ERANGE;
|
errno = ERANGE;
|
||||||
if (errstr != NULL)
|
if (errstr != NULL)
|
||||||
*errstr = N_("too large");
|
*errstr = N_("value too large");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
rval = (id_t)ulval;
|
rval = (id_t)ulval;
|
||||||
|
@@ -51,13 +51,13 @@ atomode(const char *cp, const char **errstr)
|
|||||||
lval = strtol(cp, &ep, 8);
|
lval = strtol(cp, &ep, 8);
|
||||||
if (ep == cp || *ep != '\0') {
|
if (ep == cp || *ep != '\0') {
|
||||||
if (errstr != NULL)
|
if (errstr != NULL)
|
||||||
*errstr = N_("invalid");
|
*errstr = N_("invalid value");
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
debug_return_int(0);
|
debug_return_int(0);
|
||||||
}
|
}
|
||||||
if (lval < 0 || lval > 0777) {
|
if (lval < 0 || lval > 0777) {
|
||||||
if (errstr != NULL)
|
if (errstr != NULL)
|
||||||
*errstr = lval < 0 ? N_("too small") : N_("too large");
|
*errstr = lval < 0 ? N_("value too small") : N_("value too large");
|
||||||
errno = ERANGE;
|
errno = ERANGE;
|
||||||
debug_return_int(0);
|
debug_return_int(0);
|
||||||
}
|
}
|
||||||
|
@@ -22,15 +22,59 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#ifdef STDC_HEADERS
|
||||||
|
# include <stdlib.h>
|
||||||
|
# include <stddef.h>
|
||||||
|
#else
|
||||||
# ifdef HAVE_STDLIB_H
|
# ifdef HAVE_STDLIB_H
|
||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
# endif
|
# endif
|
||||||
|
#endif /* STDC_HEADERS */
|
||||||
|
#ifdef HAVE_STRING_H
|
||||||
|
# include <string.h>
|
||||||
|
#endif /* HAVE_STRING_H */
|
||||||
|
#ifdef HAVE_STRINGS_H
|
||||||
|
# include <strings.h>
|
||||||
|
#endif /* HAVE_STRINGS_H */
|
||||||
|
|
||||||
#include "missing.h"
|
#include "missing.h"
|
||||||
|
|
||||||
#define DEFAULT_TEXT_DOMAIN "sudo"
|
#define DEFAULT_TEXT_DOMAIN "sudo"
|
||||||
#include "gettext.h"
|
#include "gettext.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_STRTONUM
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The OpenBSD strtonum error string too short to be translated sensibly.
|
||||||
|
* This wrapper just changes errstr as follows:
|
||||||
|
* invalid -> invalid value
|
||||||
|
* too large -> value too large
|
||||||
|
* too small -> value too small
|
||||||
|
*/
|
||||||
|
long long
|
||||||
|
rpl_strtonum(const char *str, long long minval, long long maxval,
|
||||||
|
const char **errstrp)
|
||||||
|
{
|
||||||
|
long long retval;
|
||||||
|
const char *errstr;
|
||||||
|
|
||||||
|
# undef strtonum
|
||||||
|
retval = strtonum(str, minval, maxval, &errstr);
|
||||||
|
if (errstr != NULL) {
|
||||||
|
if (errno == EINVAL) {
|
||||||
|
errstr = N_("invalid value");
|
||||||
|
} else if (errno == ERANGE) {
|
||||||
|
errstr = strcmp(errstr, "too large") == 0 ?
|
||||||
|
N_("value too large") : N_("value too small");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (errstrp != NULL)
|
||||||
|
*errstrp = errstr;
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
enum strtonum_err {
|
enum strtonum_err {
|
||||||
STN_VALID,
|
STN_VALID,
|
||||||
STN_INVALID,
|
STN_INVALID,
|
||||||
@@ -42,7 +86,7 @@ enum strtonum_err {
|
|||||||
* Convert a string to a number in the range [minval, maxval]
|
* Convert a string to a number in the range [minval, maxval]
|
||||||
*/
|
*/
|
||||||
long long
|
long long
|
||||||
strtonum(const char *str, long long minval, long long maxval,
|
rpl_strtonum(const char *str, long long minval, long long maxval,
|
||||||
const char **errstrp)
|
const char **errstrp)
|
||||||
{
|
{
|
||||||
const unsigned char *ustr = (const unsigned char *)str;
|
const unsigned char *ustr = (const unsigned char *)str;
|
||||||
@@ -136,20 +180,21 @@ done:
|
|||||||
result = 0;
|
result = 0;
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
if (errstrp != NULL)
|
if (errstrp != NULL)
|
||||||
*errstrp = N_("invalid");
|
*errstrp = N_("invalid value");
|
||||||
break;
|
break;
|
||||||
case STN_TOOSMALL:
|
case STN_TOOSMALL:
|
||||||
result = 0;
|
result = 0;
|
||||||
errno = ERANGE;
|
errno = ERANGE;
|
||||||
if (errstrp != NULL)
|
if (errstrp != NULL)
|
||||||
*errstrp = N_("too small");
|
*errstrp = N_("value too small");
|
||||||
break;
|
break;
|
||||||
case STN_TOOBIG:
|
case STN_TOOBIG:
|
||||||
result = 0;
|
result = 0;
|
||||||
errno = ERANGE;
|
errno = ERANGE;
|
||||||
if (errstrp != NULL)
|
if (errstrp != NULL)
|
||||||
*errstrp = N_("too large");
|
*errstrp = N_("value too large");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
#endif /* HAVE_STRTONUM */
|
||||||
|
18
configure
vendored
18
configure
vendored
@@ -18014,6 +18014,24 @@ esac
|
|||||||
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
# We wrap OpenBSD's strtonum() to get translatable error strings.
|
||||||
|
for ac_func in strtonum
|
||||||
|
do :
|
||||||
|
ac_fn_c_check_func "$LINENO" "strtonum" "ac_cv_func_strtonum"
|
||||||
|
if test "x$ac_cv_func_strtonum" = xyes; then :
|
||||||
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
#define HAVE_STRTONUM 1
|
||||||
|
_ACEOF
|
||||||
|
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
case " $LIBOBJS " in
|
||||||
|
*" strtonum.$ac_objext "* ) ;;
|
||||||
|
*) LIBOBJS="$LIBOBJS strtonum.$ac_objext"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
if test X"$ac_cv_type_struct_timespec" != X"no"; then
|
if test X"$ac_cv_type_struct_timespec" != X"no"; then
|
||||||
ac_fn_c_check_member "$LINENO" "struct stat" "st_mtim" "ac_cv_member_struct_stat_st_mtim" "$ac_includes_default"
|
ac_fn_c_check_member "$LINENO" "struct stat" "st_mtim" "ac_cv_member_struct_stat_st_mtim" "$ac_includes_default"
|
||||||
if test "x$ac_cv_member_struct_stat_st_mtim" = xyes; then :
|
if test "x$ac_cv_member_struct_stat_st_mtim" = xyes; then :
|
||||||
|
@@ -2415,6 +2415,9 @@ if test X"$ac_cv_have_working_snprintf$ac_cv_have_working_vsnprintf" = X"yesyes"
|
|||||||
AC_LIBOBJ(snprintf)
|
AC_LIBOBJ(snprintf)
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
# We wrap OpenBSD's strtonum() to get translatable error strings.
|
||||||
|
AC_CHECK_FUNCS(strtonum)
|
||||||
|
AC_LIBOBJ(strtonum)
|
||||||
if test X"$ac_cv_type_struct_timespec" != X"no"; then
|
if test X"$ac_cv_type_struct_timespec" != X"no"; then
|
||||||
AC_CHECK_MEMBER([struct stat.st_mtim], [AC_DEFINE(HAVE_ST_MTIM)]
|
AC_CHECK_MEMBER([struct stat.st_mtim], [AC_DEFINE(HAVE_ST_MTIM)]
|
||||||
[AC_CHECK_MEMBER([struct stat.st_mtim.st__tim], AC_DEFINE(HAVE_ST__TIM))],
|
[AC_CHECK_MEMBER([struct stat.st_mtim.st__tim], AC_DEFINE(HAVE_ST__TIM))],
|
||||||
|
@@ -475,7 +475,9 @@ char *strsignal(int);
|
|||||||
int sig2str(int, char *);
|
int sig2str(int, char *);
|
||||||
#endif
|
#endif
|
||||||
#ifndef HAVE_STRTONUM
|
#ifndef HAVE_STRTONUM
|
||||||
long long strtonum(const char *, long long, long long, const char **);
|
long long rpl_strtonum(const char *, long long, long long, const char **);
|
||||||
|
# undef strtonum
|
||||||
|
# define strtonum rpl_strtonum
|
||||||
#endif
|
#endif
|
||||||
void initprogname(const char *);
|
void initprogname(const char *);
|
||||||
|
|
||||||
|
@@ -610,7 +610,7 @@ store_int(char *val, struct sudo_defs_types *def, int op)
|
|||||||
i = strtonum(val, INT_MIN, INT_MAX, &errstr);
|
i = strtonum(val, INT_MIN, INT_MAX, &errstr);
|
||||||
if (errstr != NULL) {
|
if (errstr != NULL) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"%s is %s", val, errstr);
|
"%s: %s", val, errstr);
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
}
|
}
|
||||||
def->sd_un.ival = i;
|
def->sd_un.ival = i;
|
||||||
@@ -633,7 +633,7 @@ store_uint(char *val, struct sudo_defs_types *def, int op)
|
|||||||
u = strtonum(val, 0, UINT_MAX, &errstr);
|
u = strtonum(val, 0, UINT_MAX, &errstr);
|
||||||
if (errstr != NULL) {
|
if (errstr != NULL) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"%s is %s", val, errstr);
|
"%s: %s", val, errstr);
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
}
|
}
|
||||||
/* XXX - should have uival */
|
/* XXX - should have uival */
|
||||||
|
@@ -144,7 +144,7 @@ io_set_max_sessid(const char *maxval)
|
|||||||
if (errstr != NULL) {
|
if (errstr != NULL) {
|
||||||
if (errno != ERANGE) {
|
if (errno != ERANGE) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"bad maxseq: %s is %s", maxval, errstr);
|
"bad maxseq: %s: %s", maxval, errstr);
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
}
|
}
|
||||||
/* Out of range, clamp to SESSID_MAX as documented. */
|
/* Out of range, clamp to SESSID_MAX as documented. */
|
||||||
|
@@ -1421,8 +1421,8 @@ sudo_ldap_parse_keyword(const char *keyword, const char *value,
|
|||||||
case CONF_INT:
|
case CONF_INT:
|
||||||
*(int *)(cur->valp) = strtonum(value, INT_MIN, INT_MAX, &errstr);
|
*(int *)(cur->valp) = strtonum(value, INT_MIN, INT_MAX, &errstr);
|
||||||
if (errstr != NULL) {
|
if (errstr != NULL) {
|
||||||
warningx(U_("%s: %s: value %s out of range)"),
|
warningx(U_("%s: %s: %s: %s"),
|
||||||
path_ldap_conf, keyword, value);
|
path_ldap_conf, keyword, value, U_(errstr));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CONF_STR:
|
case CONF_STR:
|
||||||
|
@@ -846,7 +846,7 @@ parse_logfile(char *logfile)
|
|||||||
li->tstamp = strtonum(cp, LLONG_MIN, LLONG_MAX, &errstr);
|
li->tstamp = strtonum(cp, LLONG_MIN, LLONG_MAX, &errstr);
|
||||||
if (errstr != NULL) {
|
if (errstr != NULL) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"%s: timestamp %s is %s", logfile, cp, errstr);
|
"%s: timestamp %s: %s", logfile, cp, errstr);
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -885,14 +885,14 @@ parse_logfile(char *logfile)
|
|||||||
li->rows = strtonum(cp, 1, INT_MAX, &errstr);
|
li->rows = strtonum(cp, 1, INT_MAX, &errstr);
|
||||||
if (errstr != NULL) {
|
if (errstr != NULL) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"%s: tty rows %s is %s", logfile, cp, errstr);
|
"%s: tty rows %s: %s", logfile, cp, errstr);
|
||||||
}
|
}
|
||||||
if (ep != NULL) {
|
if (ep != NULL) {
|
||||||
cp = ep + 1;
|
cp = ep + 1;
|
||||||
li->cols = strtonum(cp, 1, INT_MAX, &errstr);
|
li->cols = strtonum(cp, 1, INT_MAX, &errstr);
|
||||||
if (errstr != NULL) {
|
if (errstr != NULL) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"%s: tty cols %s is %s", logfile, cp, errstr);
|
"%s: tty cols %s: %s", logfile, cp, errstr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -178,7 +178,7 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, char ***settingsp,
|
|||||||
char *cp, **env_add, **settings;
|
char *cp, **env_add, **settings;
|
||||||
const char *runas_user = NULL;
|
const char *runas_user = NULL;
|
||||||
const char *runas_group = NULL;
|
const char *runas_group = NULL;
|
||||||
const char *debug_flags, *errstr;
|
const char *debug_flags;
|
||||||
int nenv = 0;
|
int nenv = 0;
|
||||||
int env_size = 32;
|
int env_size = 32;
|
||||||
debug_decl(parse_args, SUDO_DEBUG_ARGS)
|
debug_decl(parse_args, SUDO_DEBUG_ARGS)
|
||||||
@@ -242,9 +242,8 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, char ***settingsp,
|
|||||||
SET(flags, MODE_BACKGROUND);
|
SET(flags, MODE_BACKGROUND);
|
||||||
break;
|
break;
|
||||||
case 'C':
|
case 'C':
|
||||||
strtonum(optarg, 4, INT_MAX, &errstr);
|
if (strtonum(optarg, 3, INT_MAX, NULL) == 0) {
|
||||||
if (errstr != NULL) {
|
warningx(_("the argument to -C must be a number greater than or equal to 3"));
|
||||||
warningx(U_("the argument to -C was %s"), U_(errstr));
|
|
||||||
usage(1);
|
usage(1);
|
||||||
}
|
}
|
||||||
sudo_settings[ARG_CLOSEFROM].value = optarg;
|
sudo_settings[ARG_CLOSEFROM].value = optarg;
|
||||||
|
@@ -449,7 +449,7 @@ get_process_ttyname(void)
|
|||||||
dev_t tdev = strtonum(cp, INT_MIN, INT_MAX, &errstr);
|
dev_t tdev = strtonum(cp, INT_MIN, INT_MAX, &errstr);
|
||||||
if (errstr) {
|
if (errstr) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"%s: tty device number %s", path, errstr);
|
"%s: tty device %s: %s", path, cp, errstr);
|
||||||
}
|
}
|
||||||
if (tdev > 0)
|
if (tdev > 0)
|
||||||
tty = sudo_ttyname_dev(tdev);
|
tty = sudo_ttyname_dev(tdev);
|
||||||
|
Reference in New Issue
Block a user