diff options
-rw-r--r-- | CHANGES | 3 | ||||
-rw-r--r-- | configure.in | 11 | ||||
-rw-r--r-- | include/apr_strings.h | 17 | ||||
-rw-r--r-- | include/arch/netware/apr_private.h | 6 | ||||
-rw-r--r-- | include/arch/win32/apr_private.h | 10 | ||||
-rw-r--r-- | strings/apr_strings.c | 8 | ||||
-rw-r--r-- | test/teststr.c | 15 |
7 files changed, 70 insertions, 0 deletions
@@ -7,6 +7,9 @@ Changes for APR 1.1 [Deferring these features when 1.0 is rolled out.] Changes with APR 1.0 + *) Add apr_strtoff() function for converting numeric strings into + apr_off_t values. [André Malo <nd perlig.de>, Joe Orton] + *) Fix stack overflow with IPv6 apr_socket_accept() on Win32. PR 28471. [inoue <inoue ariel-networks.com>] diff --git a/configure.in b/configure.in index 0817ff3fa..b25abe6eb 100644 --- a/configure.in +++ b/configure.in @@ -1222,6 +1222,7 @@ if test "${ac_cv_sizeof_off_t}${apr_cv_use_lfs64}" = "4yes"; then # LFS is go! off_t_fmt='#define APR_OFF_T_FMT APR_INT64_T_FMT' off_t_value='off64_t' + off_t_strfn='apr_strtoi64' elif test "${ac_cv_sizeof_off_t}x${ac_cv_sizeof_long}" = "4x4"; then # Special case: off_t may change size with _FILE_OFFSET_BITS # on 32-bit systems with LFS support. To avoid compatibility @@ -1229,16 +1230,20 @@ elif test "${ac_cv_sizeof_off_t}x${ac_cv_sizeof_long}" = "4x4"; then # hard-code apr_off_t to long. off_t_value=long off_t_fmt='#define APR_OFF_T_FMT "ld"' + off_t_strfn='strtol' elif test "$ac_cv_type_off_t" = "yes"; then off_t_value=off_t # off_t is more commonly a long than an int; prefer that case # where int and long are the same size. if test "$ac_cv_sizeof_off_t" = "$ac_cv_sizeof_long"; then off_t_fmt='#define APR_OFF_T_FMT "ld"' + off_t_strfn='strtol' elif test "$ac_cv_sizeof_off_t" = "$ac_cv_sizeof_int"; then off_t_fmt='#define APR_OFF_T_FMT "d"' + off_t_strfn='strtoi' elif test "$ac_cv_sizeof_off_t" = "$ac_cv_sizeof_long_long"; then off_t_fmt='#define APR_OFF_T_FMT APR_INT64_T_FMT' + off_t_strfn='apr_strtoi64' else AC_ERROR([could not determine the size of off_t]) fi @@ -1246,6 +1251,7 @@ else # Fallback on int off_t_value=apr_int32_t off_t_fmt=d + off_t_strfn='strtoi' fi AC_MSG_RESULT($off_t_value) @@ -1346,6 +1352,11 @@ AC_SUBST(have_strstr) AC_SUBST(have_memchr) AC_SUBST(have_int64_strfn) AC_SUBST(int64_strfn) +if test "$off_t_strfn" = "apr_strtoi64" && test "$have_int64_strfn" = "1"; then + off_t_strfn=$int64_strfn +fi +AC_DEFINE_UNQUOTED(APR_OFF_T_STRFN, [$off_t_strfn], + [Define as function used for conversion of strings to apr_off_t]) dnl ----------------------------- Checking for DSO support echo "${nl}Checking for DSO..." diff --git a/include/apr_strings.h b/include/apr_strings.h index 7934ff6cd..c189cb6a4 100644 --- a/include/apr_strings.h +++ b/include/apr_strings.h @@ -296,6 +296,23 @@ APR_DECLARE(char *) apr_ltoa(apr_pool_t *p, long n); APR_DECLARE(char *) apr_off_t_toa(apr_pool_t *p, apr_off_t n); /** + * Convert a numeric string into an apr_off_t numeric value. + * @param offset The value of the parsed string. + * @param buf The string to parse. It may contain optional whitespace, + * followed by an optional '+' (positive, default) or '-' (negative) + * character, followed by an optional '0x' prefix if base is 0 or 16, + * followed by numeric digits appropriate for base. + * @param end A pointer to the end of the valid character in buf. If + * not NULL, it is set to the first invalid character in buf. + * @param base A numeric base in the range between 2 and 36 inclusive, + * or 0. If base is zero, buf will be treated as base ten unless its + * digits are prefixed with '0x', in which case it will be treated as + * base 16. + */ +APR_DECLARE(apr_status_t) apr_strtoff(apr_off_t *offset, const char *buf, + char **end, int base); + +/** * parse a numeric string into a 64-bit numeric value * @param buf The string to parse. It may contain optional whitespace, * followed by an optional '+' (positive, default) or '-' (negative) diff --git a/include/arch/netware/apr_private.h b/include/arch/netware/apr_private.h index b24758b03..c334509ae 100644 --- a/include/arch/netware/apr_private.h +++ b/include/arch/netware/apr_private.h @@ -156,6 +156,12 @@ void* getStatCache(); #undef malloc #define malloc(x) library_malloc(gLibHandle,x) +#if APR_HAS_LARGE_FILES +#define APR_OFF_T_STRFN strtoll +#else +#define APR_OFF_T_STRFN strtol +#endif + /* * Include common private declarations. */ diff --git a/include/arch/win32/apr_private.h b/include/arch/win32/apr_private.h index 700d853ce..98d88b99c 100644 --- a/include/arch/win32/apr_private.h +++ b/include/arch/win32/apr_private.h @@ -143,6 +143,16 @@ APR_DECLARE_DATA int errno; #define HAVE_GETNAMEINFO 1 #endif +#if APR_HAS_LARGE_FILES +#if APR_HAVE_INT64_STRFN +#define APR_OFF_T_STRFN APR_INT64_STRFN +#else +#define APR_OFF_T_STRFN apr_strtoi64 +#endif +#else +#define APR_OFF_T_STRFN strtoi +#endif + /* * Include common private declarations. */ diff --git a/strings/apr_strings.c b/strings/apr_strings.c index a88f35e09..811599c28 100644 --- a/strings/apr_strings.c +++ b/strings/apr_strings.c @@ -233,6 +233,14 @@ void *memchr(const void *s, int c, size_t n) #define INT64_MIN (-APR_INT64_C(0x7fffffffffffffff) - APR_INT64_C(1)) #endif +APR_DECLARE(apr_status_t) apr_strtoff(apr_off_t *offset, const char *nptr, + char **endptr, int base) +{ + errno = 0; + *offset = APR_OFF_T_STRFN(nptr, endptr, base); + return APR_FROM_OS_ERROR(errno); +} + APR_DECLARE(apr_int64_t) apr_strtoi64(const char *nptr, char **endptr, int base) { #if (APR_HAVE_INT64_STRFN) diff --git a/test/teststr.c b/test/teststr.c index 02ede380f..a01bce07b 100644 --- a/test/teststr.c +++ b/test/teststr.c @@ -246,6 +246,20 @@ static void string_strtoi64(abts_case *tc, void *data) } } +static void string_strtoff(abts_case *tc, void *data) +{ + apr_off_t off; + + ABTS_ASSERT(tc, "strtoff fails on out-of-range integer", + apr_strtoff(&off, "999999999999999999999999999999", + NULL, 10) != APR_SUCCESS); + + ABTS_ASSERT(tc, "strtoff does not fail on 1234", + apr_strtoff(&off, "1234", NULL, 10) == APR_SUCCESS); + + ABTS_ASSERT(tc, "strtoff parsed 1234 correctly,", off == 1234); +} + abts_suite *teststr(abts_suite *suite) { suite = ADD_SUITE(suite) @@ -257,6 +271,7 @@ abts_suite *teststr(abts_suite *suite) abts_run_test(suite, string_error, NULL); abts_run_test(suite, string_long, NULL); abts_run_test(suite, string_strtoi64, NULL); + abts_run_test(suite, string_strtoff, NULL); return suite; } |