diff options
author | Peter Stephenson <p.w.stephenson@ntlworld.com> | 2015-09-19 23:08:46 +0100 |
---|---|---|
committer | Peter Stephenson <p.w.stephenson@ntlworld.com> | 2015-09-19 23:08:46 +0100 |
commit | df0d86b847fbf5bd1ad383531cd52b261dc07717 (patch) | |
tree | 1b0e356cac173e6c56f25af74a80cc85e9c13e6e | |
parent | cc44b10da1bcc4af87fb7bb0336177a31798608e (diff) | |
download | zsh-df0d86b847fbf5bd1ad383531cd52b261dc07717.tar.gz zsh-df0d86b847fbf5bd1ad383531cd52b261dc07717.tar.xz zsh-df0d86b847fbf5bd1ad383531cd52b261dc07717.zip |
36559: test earlier for overflow in pattern range
-rw-r--r-- | ChangeLog | 3 | ||||
-rw-r--r-- | Src/pattern.c | 23 | ||||
-rw-r--r-- | Src/zsh.h | 7 |
3 files changed, 28 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog index 2852b4de9..bb03894a0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2015-09-19 Peter Stephenson <p.w.stephenson@ntlworld.com> + * 36559: Src/pattern.c: test earlier for overflow in pattern + range. + * unposted: Test/D07multibyte.ztst: fix typo. 2015-09-18 Barton E. Schaefer <schaefer@zsh.org> diff --git a/Src/pattern.c b/Src/pattern.c index 3b55ccf1c..af56bd9cc 100644 --- a/Src/pattern.c +++ b/Src/pattern.c @@ -220,8 +220,10 @@ typedef union upat *Upat; #if defined(ZSH_64_BIT_TYPE) || defined(LONG_IS_64_BIT) typedef zlong zrange_t; #define ZRANGE_T_IS_SIGNED (1) +#define ZRANGE_MAX ZLONG_MAX #else typedef unsigned long zrange_t; +#define ZRANGE_MAX ULONG_MAX #endif #ifdef MULTIBYTE_SUPPORT @@ -2641,19 +2643,30 @@ patmatch(Upat prog) start = compend = patinput; comp = 0; while (patinput < patinend && idigit(*patinput)) { - if (comp) - comp *= 10; - comp += *patinput - '0'; + int out_of_range = 0; + int digit = *patinput - '0'; + if (comp > ZRANGE_MAX / (zlong)10) { + out_of_range = 1; + } else { + zrange_t c10 = comp ? comp * 10 : 0; + if (ZRANGE_MAX - c10 < digit) { + out_of_range = 1; + } else { + comp = c10; + comp += digit; + } + } patinput++; compend++; - if (comp & ((zrange_t)1 << (sizeof(comp)*8 - + if (out_of_range || + (comp & ((zrange_t)1 << (sizeof(comp)*8 - #ifdef ZRANGE_T_IS_SIGNED 2 #else 1 #endif - ))) { + )))) { /* * Out of range (allowing for signedness, which * we need if we are using zlongs). diff --git a/Src/zsh.h b/Src/zsh.h index 4e2cb656e..9c7e5d9dc 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -36,6 +36,12 @@ */ #ifdef ZSH_64_BIT_TYPE typedef ZSH_64_BIT_TYPE zlong; +#if defind(ZLONG_IS_LONG_LONG) && defined(LLONG_MAX) +#define ZLONG_MAX LLONG_MAX +#else +/* umm... */ +#define ZLONG_MAX ((zlong)9223372036854775807) +#endif #ifdef ZSH_64_BIT_UTYPE typedef ZSH_64_BIT_UTYPE zulong; #else @@ -44,6 +50,7 @@ typedef unsigned zlong zulong; #else typedef long zlong; typedef unsigned long zulong; +#define ZLONG_MAX LONG_MAX #endif /* |