summaryrefslogtreecommitdiff
path: root/lib/strtoofft.c
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2017-08-14 23:33:23 +0200
committerDaniel Stenberg <daniel@haxx.se>2017-08-14 23:33:41 +0200
commitff50fe0348466cae1a9f9f759b362c03f7060c34 (patch)
tree6a5a6efbe7bd7b00e49982e09a5da8f8341de28c /lib/strtoofft.c
parentb53b4e44241415c0a7ad857c72ec323109d2a7c0 (diff)
downloadgnurl-ff50fe0348466cae1a9f9f759b362c03f7060c34.tar.gz
gnurl-ff50fe0348466cae1a9f9f759b362c03f7060c34.tar.bz2
gnurl-ff50fe0348466cae1a9f9f759b362c03f7060c34.zip
strtoofft: reduce integer overflow risks globally
... make sure we bail out on overflows. Reported-by: Brian Carpenter Closes #1758
Diffstat (limited to 'lib/strtoofft.c')
-rw-r--r--lib/strtoofft.c63
1 files changed, 59 insertions, 4 deletions
diff --git a/lib/strtoofft.c b/lib/strtoofft.c
index c2adc7280..f057bb1d6 100644
--- a/lib/strtoofft.c
+++ b/lib/strtoofft.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,7 @@
*
***************************************************************************/
+#include <errno.h>
#include "curl_setup.h"
#include "strtoofft.h"
@@ -32,6 +33,30 @@
* https://www.opengroup.org/onlinepubs/009695399/functions/strtoimax.html
*/
+#if (CURL_SIZEOF_CURL_OFF_T > CURL_SIZEOF_LONG)
+# ifdef HAVE_STRTOLL
+# define strtooff strtoll
+# else
+# if defined(_MSC_VER) && (_MSC_VER >= 1300) && (_INTEGRAL_MAX_BITS >= 64)
+# if defined(_SAL_VERSION)
+ _Check_return_ _CRTIMP __int64 __cdecl _strtoi64(
+ _In_z_ const char *_String,
+ _Out_opt_ _Deref_post_z_ char **_EndPtr, _In_ int _Radix);
+# else
+ _CRTIMP __int64 __cdecl _strtoi64(const char *_String,
+ char **_EndPtr, int _Radix);
+# endif
+# define strtooff _strtoi64
+# else
+ curl_off_t curlx_strtoll(const char *nptr, char **endptr, int base);
+# define strtooff curlx_strtoll
+# define NEED_CURL_STRTOLL 1
+# endif
+# endif
+#else
+# define strtooff strtol
+#endif
+
#ifdef NEED_CURL_STRTOLL
/* Range tests can be used for alphanum decoding if characters are consecutive,
@@ -48,11 +73,10 @@ static const char valchars[] =
static int get_char(char c, int base);
/**
- * Emulated version of the strtoll function. This extracts a long long
+ * Custom version of the strtooff function. This extracts a curl_off_t
* value from the given input string and returns it.
*/
-curl_off_t
-curlx_strtoll(const char *nptr, char **endptr, int base)
+static curl_off_t strtooff(const char *nptr, char **endptr, int base)
{
char *end;
int is_negative = 0;
@@ -186,3 +210,34 @@ static int get_char(char c, int base)
return value;
}
#endif /* Only present if we need strtoll, but don't have it. */
+
+/*
+ * Parse a *positive* up to 64 bit number written in ascii.
+ */
+CURLofft curlx_strtoofft(const char *str, char **endp, int base,
+ curl_off_t *num)
+{
+ char *end;
+ curl_off_t number;
+ errno = 0;
+ *num = 0; /* clear by default */
+ while(str && *str && ISSPACE(*str))
+ str++;
+ if('-' == *str) {
+ if(endp)
+ *endp = (char *)str; /* didn't actually move */
+ return CURL_OFFT_INVAL; /* nothing parsed */
+ }
+ number = strtooff(str, &end, base);
+ if(endp)
+ *endp = end;
+ if(errno == ERANGE)
+ /* overflow/underflow */
+ return CURL_OFFT_FLOW;
+ else if(str == end)
+ /* nothing parsed */
+ return CURL_OFFT_INVAL;
+
+ *num = number;
+ return CURL_OFFT_OK;
+}