summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES3
-rw-r--r--configure.in11
-rw-r--r--include/apr_strings.h17
-rw-r--r--include/arch/netware/apr_private.h6
-rw-r--r--include/arch/win32/apr_private.h10
-rw-r--r--strings/apr_strings.c8
-rw-r--r--test/teststr.c15
7 files changed, 70 insertions, 0 deletions
diff --git a/CHANGES b/CHANGES
index 1389d9e6d..8ad43b57c 100644
--- a/CHANGES
+++ b/CHANGES
@@ -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;
}