From 88c6446daf19e48af2eb8bcbba6f5830f4a1024f Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Sun, 25 Nov 2012 09:34:15 -0500 Subject: [PATCH] Do locale swapping in the warning()/error() macros themselves instead of in the underlying functions. --- include/error.h | 101 ++++++++++++++++++++++++++------- plugins/sudoers/plugin_error.c | 36 +++++++++--- src/error.c | 29 +++++++--- 3 files changed, 130 insertions(+), 36 deletions(-) diff --git a/include/error.h b/include/error.h index aea0bb96b..fe2df4e19 100644 --- a/include/error.h +++ b/include/error.h @@ -50,18 +50,18 @@ # define errorx(rval, fmt...) do { \ sudo_debug_printf2(__func__, __FILE__, __LINE__, \ SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, fmt); \ - errorx_nodebug((rval), fmt); \ + errorx_nodebug((rval), fmt); \ } while (0) # define warning(fmt...) do { \ sudo_debug_printf2(__func__, __FILE__, __LINE__, \ SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO|sudo_debug_subsys, \ fmt); \ - warning_nodebug(fmt); \ + warning_nodebug(fmt); \ } while (0) # define warningx(fmt...) do { \ sudo_debug_printf2(__func__, __FILE__, __LINE__, \ SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, fmt); \ - warningx_nodebug(fmt); \ + warningx_nodebug(fmt); \ } while (0) # else # define error(rval, ...) do { \ @@ -73,51 +73,112 @@ # define errorx(rval, ...) do { \ sudo_debug_printf2(__func__, __FILE__, __LINE__, \ SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, __VA_ARGS__); \ - errorx_nodebug((rval), __VA_ARGS__); \ + errorx_nodebug((rval), __VA_ARGS__); \ } while (0) # define warning(...) do { \ sudo_debug_printf2(__func__, __FILE__, __LINE__, \ SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO|sudo_debug_subsys, \ __VA_ARGS__); \ - warning_nodebug(__VA_ARGS__); \ + warning_nodebug(__VA_ARGS__); \ } while (0) # define warningx(...) do { \ sudo_debug_printf2(__func__, __FILE__, __LINE__, \ SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|sudo_debug_subsys, __VA_ARGS__); \ - warningx_nodebug(__VA_ARGS__); \ + warningx_nodebug(__VA_ARGS__); \ } while (0) # endif /* __GNUC__ == 2 */ -# define verror(rval, fmt, ap) do { \ +# define verror(rval, fmt, ap) do { \ sudo_debug_vprintf2(__func__, __FILE__, __LINE__, \ SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO|sudo_debug_subsys, \ (fmt), (ap)); \ - verror_nodebug((rval), (fmt), (ap)); \ + verror_nodebug((rval), (fmt), (ap)); \ } while (0) # define verrorx(rval, fmt, ap) do { \ sudo_debug_vprintf2(__func__, __FILE__, __LINE__, \ SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, (fmt), (ap)); \ - verrorx_nodebug((rval), (fmt), (ap)); \ + verrorx_nodebug((rval), (fmt), (ap)); \ } while (0) # define vwarning(fmt, ap) do { \ sudo_debug_vprintf2(__func__, __FILE__, __LINE__, \ SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO|sudo_debug_subsys, \ (fmt), (ap)); \ - vwarning_nodebug((fmt), (ap)); \ + vwarning_nodebug((fmt), (ap)); \ + warning_restore_locale(); \ } while (0) -# define vwarningx(fmt, ap) do { \ +# define vwarningx(fmt, ap) do { \ sudo_debug_vprintf2(__func__, __FILE__, __LINE__, \ SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|sudo_debug_subsys, (fmt), (ap)); \ - vwarningx_nodebug((fmt), (ap)); \ + vwarningx_nodebug((fmt), (ap)); \ } while (0) #endif /* SUDO_ERROR_WRAP */ -void error_nodebug(int, const char *, ...) __printflike(2, 3) __attribute__((__noreturn__)); -void errorx_nodebug(int, const char *, ...) __printflike(2, 3) __attribute__((__noreturn__)); -void verror_nodebug(int, const char *, va_list ap) __attribute__((__noreturn__)); -void verrorx_nodebug(int, const char *, va_list ap) __attribute__((__noreturn__)); -void warning_nodebug(const char *, ...) __printflike(1, 2); -void warningx_nodebug(const char *, ...) __printflike(1, 2); -void vwarning_nodebug(const char *, va_list ap); -void vwarningx_nodebug(const char *, va_list ap); +#if defined(__GNUC__) && __GNUC__ == 2 +# define error_nodebug(rval, fmt...) do { \ + warning_set_locale(); \ + error2((rval), fmt); \ +} while (0) +# define errorx_nodebug(rval, fmt...) do { \ + warning_set_locale(); \ + errorx2((rval), fmt); \ +} while (0) +# define warning_nodebug(fmt...) do { \ + warning_set_locale(); \ + warning2(fmt); \ + warning_restore_locale(); \ +} while (0) +# define warningx_nodebug(fmt...) do { \ + warning_set_locale(); \ + warningx2(fmt); \ + warning_restore_locale(); \ +} while (0) +#else +# define error_nodebug(rval, ...) do { \ + warning_set_locale(); \ + error2((rval), __VA_ARGS__); \ +} while (0) +# define errorx_nodebug(rval, ...) do { \ + warning_set_locale(); \ + errorx2((rval), __VA_ARGS__); \ +} while (0) +# define warning_nodebug(...) do { \ + warning_set_locale(); \ + warning2(__VA_ARGS__); \ + warning_restore_locale(); \ +} while (0) +# define warningx_nodebug(...) do { \ + warning_set_locale(); \ + warningx2(__VA_ARGS__); \ + warning_restore_locale(); \ +} while (0) +#endif /* __GNUC__ == 2 */ +#define verror_nodebug(rval, fmt, ap) do { \ + warning_set_locale(); \ + verror2((rval), (fmt), (ap)); \ +} while (0) +#define verrorx_nodebug(rval, fmt, ap) do { \ + warning_set_locale(); \ + verrorx2((rval), (fmt), (ap)); \ +} while (0) +#define vwarning_nodebug(fmt, ap) do { \ + warning_set_locale(); \ + vwarning2((fmt), (ap)); \ + warning_restore_locale(); \ +} while (0) +#define vwarningx_nodebug(fmt, ap) do { \ + warning_set_locale(); \ + vwarningx2((fmt), (ap)); \ + warning_restore_locale(); \ +} while (0) + +void error2(int, const char *, ...) __printflike(2, 3) __attribute__((__noreturn__)); +void errorx2(int, const char *, ...) __printflike(2, 3) __attribute__((__noreturn__)); +void verror2(int, const char *, va_list ap) __attribute__((__noreturn__)); +void verrorx2(int, const char *, va_list ap) __attribute__((__noreturn__)); +void warning2(const char *, ...) __printflike(1, 2); +void warningx2(const char *, ...) __printflike(1, 2); +void vwarning2(const char *, va_list ap); +void vwarningx2(const char *, va_list ap); +void warning_set_locale(void); +void warning_restore_locale(void); #endif /* _SUDO_ERROR_H_ */ diff --git a/plugins/sudoers/plugin_error.c b/plugins/sudoers/plugin_error.c index ad5f6748d..80369a6d0 100644 --- a/plugins/sudoers/plugin_error.c +++ b/plugins/sudoers/plugin_error.c @@ -23,10 +23,16 @@ #include #include #include +#ifdef HAVE_STDBOOL_H +# include +#else +# include "compat/stdbool.h" +#endif /* HAVE_STDBOOL_H */ #include "missing.h" #include "alloc.h" #include "error.h" +#include "logging.h" #include "sudo_plugin.h" #define DEFAULT_TEXT_DOMAIN "sudoers" @@ -40,7 +46,7 @@ sigjmp_buf error_jmp; extern sudo_conv_t sudo_conv; void -error_nodebug(int eval, const char *fmt, ...) +error2(int eval, const char *fmt, ...) { va_list ap; @@ -55,7 +61,7 @@ error_nodebug(int eval, const char *fmt, ...) } void -errorx_nodebug(int eval, const char *fmt, ...) +errorx2(int eval, const char *fmt, ...) { va_list ap; @@ -70,7 +76,7 @@ errorx_nodebug(int eval, const char *fmt, ...) } void -verror_nodebug(int eval, const char *fmt, va_list ap) +verror2(int eval, const char *fmt, va_list ap) { _warning(1, fmt, ap); sudoers_cleanup(0); @@ -81,7 +87,7 @@ verror_nodebug(int eval, const char *fmt, va_list ap) } void -verrorx_nodebug(int eval, const char *fmt, va_list ap) +verrorx2(int eval, const char *fmt, va_list ap) { _warning(0, fmt, ap); sudoers_cleanup(0); @@ -92,7 +98,7 @@ verrorx_nodebug(int eval, const char *fmt, va_list ap) } void -warning_nodebug(const char *fmt, ...) +warning2(const char *fmt, ...) { va_list ap; @@ -102,7 +108,7 @@ warning_nodebug(const char *fmt, ...) } void -warningx_nodebug(const char *fmt, ...) +warningx2(const char *fmt, ...) { va_list ap; va_start(ap, fmt); @@ -111,13 +117,13 @@ warningx_nodebug(const char *fmt, ...) } void -vwarning_nodebug(const char *fmt, va_list ap) +vwarning2(const char *fmt, va_list ap) { _warning(1, fmt, ap); } void -vwarningx_nodebug(const char *fmt, va_list ap) +vwarningx2(const char *fmt, va_list ap) { _warning(0, fmt, ap); } @@ -168,3 +174,17 @@ _warning(int use_errno, const char *fmt, va_list ap) putc('\n', stderr); } } + +static int oldlocale; + +void +warning_set_locale(void) +{ + sudoers_setlocale(SUDOERS_LOCALE_USER, &oldlocale); +} + +void +warning_restore_locale(void) +{ + sudoers_setlocale(oldlocale, NULL); +} diff --git a/src/error.c b/src/error.c index 86207d7d0..ee758a052 100644 --- a/src/error.c +++ b/src/error.c @@ -33,7 +33,7 @@ static void _warning(int, const char *, va_list); void cleanup(int); void -error_nodebug(int eval, const char *fmt, ...) +error2(int eval, const char *fmt, ...) { va_list ap; va_start(ap, fmt); @@ -44,7 +44,7 @@ error_nodebug(int eval, const char *fmt, ...) } void -errorx_nodebug(int eval, const char *fmt, ...) +errorx2(int eval, const char *fmt, ...) { va_list ap; va_start(ap, fmt); @@ -55,7 +55,7 @@ errorx_nodebug(int eval, const char *fmt, ...) } void -verror_nodebug(int eval, const char *fmt, va_list ap) +verror2(int eval, const char *fmt, va_list ap) { _warning(1, fmt, ap); cleanup(0); @@ -63,7 +63,7 @@ verror_nodebug(int eval, const char *fmt, va_list ap) } void -verrorx_nodebug(int eval, const char *fmt, va_list ap) +verrorx2(int eval, const char *fmt, va_list ap) { _warning(0, fmt, ap); cleanup(0); @@ -71,7 +71,7 @@ verrorx_nodebug(int eval, const char *fmt, va_list ap) } void -warning_nodebug(const char *fmt, ...) +warning2(const char *fmt, ...) { va_list ap; va_start(ap, fmt); @@ -80,7 +80,7 @@ warning_nodebug(const char *fmt, ...) } void -warningx_nodebug(const char *fmt, ...) +warningx2(const char *fmt, ...) { va_list ap; va_start(ap, fmt); @@ -89,13 +89,13 @@ warningx_nodebug(const char *fmt, ...) } void -vwarning_nodebug(const char *fmt, va_list ap) +vwarning2(const char *fmt, va_list ap) { _warning(1, fmt, ap); } void -vwarningx_nodebug(const char *fmt, va_list ap) +vwarningx2(const char *fmt, va_list ap) { _warning(0, fmt, ap); } @@ -116,3 +116,16 @@ _warning(int use_errno, const char *fmt, va_list ap) } putc('\n', stderr); } + +/* No need to swap locales in the front end. */ +void +warning_set_locale(void) +{ + return; +} + +void +warning_restore_locale(void) +{ + return; +} -- 2.50.1