]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
3374. [bug] isc_parse_uint32 failed to return a range error on
authorckb <ckb@isc.org>
Wed, 12 Sep 2012 20:33:04 +0000 (15:33 -0500)
committerckb <ckb@isc.org>
Wed, 12 Sep 2012 20:33:04 +0000 (15:33 -0500)
                        systems with 64 bit longs [RT #30232]

CHANGES
lib/isc/parseint.c
lib/isc/tests/Makefile.in
lib/isc/tests/parse_test.c [new file with mode: 0644]

diff --git a/CHANGES b/CHANGES
index 589422846cc8b67ef7eae8413164854395684c54..37471d579bb10aaad2b5261ffa343554bdac8646 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+3374.   [bug]           isc_parse_uint32 failed to return a range error on 
+                        systems with 64 bit longs [RT #30232]   
+
        --- 9.7.7 released ---
 
 3373.  [bug]           win32: open raw files in binary mode. [RT #30944]
index 266d44cec5c5fd6550a70016b9fd870cc7a458c5..15b31130dc4165d7cf7e38ab5abba1fbd2aec98e 100644 (file)
@@ -32,6 +32,7 @@
 isc_result_t
 isc_parse_uint32(isc_uint32_t *uip, const char *string, int base) {
        unsigned long n;
+       isc_uint32_t r;
        char *e;
        if (! isalnum((unsigned char)(string[0])))
                return (ISC_R_BADNUMBER);
@@ -39,9 +40,15 @@ isc_parse_uint32(isc_uint32_t *uip, const char *string, int base) {
        n = strtoul(string, &e, base);
        if (*e != '\0')
                return (ISC_R_BADNUMBER);
-       if (n == ULONG_MAX && errno == ERANGE)
+       /*
+        * Where long is 64 bits we need to convert to 32 bits then test for
+        * equality.  This is a no-op on 32 bit machines and a good compiler
+        * will optimise it away.
+        */
+       r = (isc_uint32_t)n;
+       if ((n == ULONG_MAX && errno == ERANGE) || (n != (unsigned long)r))
                return (ISC_R_RANGE);
-       *uip = n;
+       *uip = r;
        return (ISC_R_SUCCESS);
 }
 
index e71911243ebdf2982ad99ade18ba407b4e16cc94..12d1d11f630977f57db4643a736abba1ffbe51fe 100644 (file)
@@ -35,10 +35,13 @@ ISCDEPLIBS =        ../libisc.@A@
 LIBS =         @LIBS@ @ATFLIBS@
 
 OBJS =         isctest.@O@
-SRCS =         isctest.c taskpool_test.c hash_test.c symtab_test.c
+
+SRCS =         isctest.c taskpool_test.c hash_test.c symtab_test.c \
+               parse_test.c
 
 SUBDIRS =
-TARGETS =      taskpool_test@EXEEXT@ hash_test@EXEEXT@ symtab_test@EXEEXT@
+TARGETS =      taskpool_test@EXEEXT@ hash_test@EXEEXT@ symtab_test@EXEEXT@ \
+               parse_test@EXEEXT@
 
 @BIND9_MAKE_RULES@
 
@@ -54,8 +57,14 @@ symtab_test@EXEEXT@: symtab_test.@O@ isctest.@O@ ${ISCDEPLIBS}
        ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
                        symtab_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS}
 
+parse_test@EXEEXT@: parse_test.@O@ isctest.@O@ ${ISCDEPLIBS}
+       ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+                       parse_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS}
+
+
 unit::
        sh ${top_srcdir}/unit/unittest.sh
 
 clean distclean::
        rm -f ${TARGETS}
+       rm -f atf.out
diff --git a/lib/isc/tests/parse_test.c b/lib/isc/tests/parse_test.c
new file mode 100644 (file)
index 0000000..3e1ef9f
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2011, 2012  Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <atf-c.h>
+
+#include <unistd.h>
+#include <time.h>
+
+#include <isc/parseint.h>
+
+#include "isctest.h"
+
+/*
+ * Individual unit tests
+ */
+
+/* Test for 32 bit overflow on 64 bit machines in isc_parse_uint32 */
+ATF_TC(parse_overflow);
+ATF_TC_HEAD(parse_overflow, tc) {
+       atf_tc_set_md_var(tc, "descr", "Check for 32 bit overflow");
+}
+ATF_TC_BODY(parse_overflow, tc) {
+       isc_result_t result;
+       isc_uint32_t output;
+       UNUSED(tc);
+
+       result = isc_test_begin(NULL, ISC_TRUE);
+       ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+       result = isc_parse_uint32(&output, "1234567890", 10);
+       ATF_CHECK_EQ(1234567890, output);
+
+       result = isc_parse_uint32(&output, "123456789012345", 10);
+       ATF_CHECK_EQ(ISC_R_RANGE, result);
+
+       result = isc_parse_uint32(&output, "12345678901234567890", 10);
+       ATF_CHECK_EQ(ISC_R_RANGE, result);
+
+       isc_test_end();
+}
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+       ATF_TP_ADD_TC(tp, parse_overflow);
+
+       return (atf_no_error());
+}
+