mirror of
https://github.com/fish-shell/fish-shell
synced 2024-11-10 23:24:39 +00:00
Add a template to parse integers easily/correctly (#3405)
* Adds a template to parse integers easily. It's not enough to use intmax_t and check for empty strings: there are limits. Adds a template to make it easy to parse an integer of any type. Adds a compiler flag to flag existing dangers. * nix warning, include <limits>, fix namespace error. on MacOS `xcodebuild -quiet` will flag these intmax_t -> * conversions, just use that if you want to find them.
This commit is contained in:
parent
e9b5505169
commit
f843eb3d31
2 changed files with 20 additions and 2 deletions
|
@ -1594,8 +1594,8 @@ int builtin_function(parser_t &parser, io_streams_t &streams, const wcstring_lis
|
|||
e.param1.job_id = job_id;
|
||||
}
|
||||
} else {
|
||||
pid_t pid = wcstoimax(w.woptarg, &end, 10);
|
||||
if (pid < 1 || !(*w.woptarg != L'\0' && *end == L'\0')) {
|
||||
pid_t pid;
|
||||
if (!(parse_integer(w.woptarg, &pid)) || pid < 1) {
|
||||
append_format(*out_err, _(L"%ls: Invalid process id '%ls'"), argv[0],
|
||||
w.woptarg);
|
||||
res = STATUS_BUILTIN_ERROR;
|
||||
|
|
18
src/common.h
18
src/common.h
|
@ -11,6 +11,9 @@
|
|||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <termios.h>
|
||||
#include <stddef.h>
|
||||
#include <limits>
|
||||
#include <inttypes.h>
|
||||
#include <wchar.h>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
|
@ -692,6 +695,21 @@ ssize_t read_loop(int fd, void *buff, size_t count);
|
|||
void __attribute__((noinline)) debug(int level, const char *msg, ...);
|
||||
void __attribute__((noinline)) debug(int level, const wchar_t *msg, ...);
|
||||
|
||||
/// Parse an integer and check limits for type
|
||||
/// The only way to be safe from overflows is intmax_t.
|
||||
/// Do that, and make sure the result isn't bigger than the maximum supported for whatever type.
|
||||
template <typename T>
|
||||
bool parse_integer(const wchar_t *in, T* out) {
|
||||
wchar_t *end;
|
||||
intmax_t res = wcstoimax(in, &end, 0);
|
||||
|
||||
if (!(*in != L'\0' && *end == L'\0')) return false;
|
||||
if (std::numeric_limits<T>::max() < res || res < std::numeric_limits<T>::min()) return false;
|
||||
|
||||
*out = static_cast<T>(res);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Replace special characters with backslash escape sequences. Newline is replaced with \n, etc.
|
||||
///
|
||||
/// \param in The string to be escaped
|
||||
|
|
Loading…
Reference in a new issue