]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
3379. [bug] nsupdate terminated unexpectedly in interactive mode
authorMark Andrews <marka@isc.org>
Wed, 22 Aug 2012 03:38:51 +0000 (13:38 +1000)
committerMark Andrews <marka@isc.org>
Wed, 22 Aug 2012 03:41:29 +0000 (13:41 +1000)
                        if built with readline support. [RT #29550]

CHANGES
bin/nsupdate/nsupdate.c
bin/tests/system/nsupdate/commandlist [new file with mode: 0644]
bin/tests/system/nsupdate/tests.sh

diff --git a/CHANGES b/CHANGES
index d2558a2db9e4cf67232a892ada8d3f4e99a55137..7585c87a5b9040a83b2a824bcfea218149290ee7 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+3379.  [bug]           nsupdate terminated unexpectedly in interactive mode
+                       if built with readline support. [RT #29550]
+
 3368.  [bug]           <dns/iptable.h>, <dns/private.h> and <dns/zone.h>
                        were not C++ safe.
 
index ff8d2abf34034cb22d9c67f3cbaea2269601ff7c..ca367d5089e64da07c8832ba16c1748c866e4c10 100644 (file)
@@ -1126,7 +1126,7 @@ parse_name(char **cmdlinep, dns_message_t *msg, dns_name_t **namep) {
        isc_buffer_t source;
 
        word = nsu_strsep(cmdlinep, " \t\r\n");
-       if (*word == 0) {
+       if (word == NULL || *word == 0) {
                fprintf(stderr, "could not read owner name\n");
                return (STATUS_SYNTAX);
        }
@@ -1229,7 +1229,7 @@ make_prereq(char *cmdline, isc_boolean_t ispositive, isc_boolean_t isrrset) {
         */
        if (isrrset) {
                word = nsu_strsep(&cmdline, " \t\r\n");
-               if (*word == 0) {
+               if (word == NULL || *word == 0) {
                        fprintf(stderr, "could not read class or type\n");
                        goto failure;
                }
@@ -1245,7 +1245,7 @@ make_prereq(char *cmdline, isc_boolean_t ispositive, isc_boolean_t isrrset) {
                         * Now read the type.
                         */
                        word = nsu_strsep(&cmdline, " \t\r\n");
-                       if (*word == 0) {
+                       if (word == NULL || *word == 0) {
                                fprintf(stderr, "could not read type\n");
                                goto failure;
                        }
@@ -1319,7 +1319,7 @@ evaluate_prereq(char *cmdline) {
 
        ddebug("evaluate_prereq()");
        word = nsu_strsep(&cmdline, " \t\r\n");
-       if (*word == 0) {
+       if (word == NULL || *word == 0) {
                fprintf(stderr, "could not read operation code\n");
                return (STATUS_SYNTAX);
        }
@@ -1353,14 +1353,14 @@ evaluate_server(char *cmdline) {
        }
 
        word = nsu_strsep(&cmdline, " \t\r\n");
-       if (*word == 0) {
+       if (word == NULL || *word == 0) {
                fprintf(stderr, "could not read server name\n");
                return (STATUS_SYNTAX);
        }
        server = word;
 
        word = nsu_strsep(&cmdline, " \t\r\n");
-       if (*word == 0)
+       if (word == NULL || *word == 0)
                port = dnsport;
        else {
                char *endp;
@@ -1394,14 +1394,14 @@ evaluate_local(char *cmdline) {
        struct in6_addr in6;
 
        word = nsu_strsep(&cmdline, " \t\r\n");
-       if (*word == 0) {
+       if (word == NULL || *word == 0) {
                fprintf(stderr, "could not read server name\n");
                return (STATUS_SYNTAX);
        }
        local = word;
 
        word = nsu_strsep(&cmdline, " \t\r\n");
-       if (*word == 0)
+       if (word == NULL || *word == 0)
                port = 0;
        else {
                char *endp;
@@ -1450,7 +1450,7 @@ evaluate_key(char *cmdline) {
        char *n;
 
        namestr = nsu_strsep(&cmdline, " \t\r\n");
-       if (*namestr == 0) {
+       if (namestr == NULL || *namestr == 0) {
                fprintf(stderr, "could not read key name\n");
                return (STATUS_SYNTAX);
        }
@@ -1474,7 +1474,7 @@ evaluate_key(char *cmdline) {
        }
 
        secretstr = nsu_strsep(&cmdline, "\r\n");
-       if (*secretstr == 0) {
+       if (secretstr == NULL || *secretstr == 0) {
                fprintf(stderr, "could not read key secret\n");
                return (STATUS_SYNTAX);
        }
@@ -1515,7 +1515,7 @@ evaluate_zone(char *cmdline) {
        isc_result_t result;
 
        word = nsu_strsep(&cmdline, " \t\r\n");
-       if (*word == 0) {
+       if (word == NULL || *word == 0) {
                fprintf(stderr, "could not read zone name\n");
                return (STATUS_SYNTAX);
        }
@@ -1541,7 +1541,7 @@ evaluate_realm(char *cmdline) {
        char buf[1024];
 
        word = nsu_strsep(&cmdline, " \t\r\n");
-       if (*word == 0) {
+       if (word == NULL || *word == 0) {
                if (realm != NULL)
                        isc_mem_free(mctx, realm);
                realm = NULL;
@@ -1566,7 +1566,7 @@ evaluate_ttl(char *cmdline) {
        isc_uint32_t ttl;
 
        word = nsu_strsep(&cmdline, " \t\r\n");
-       if (*word == 0) {
+       if (word == NULL || *word == 0) {
                fprintf(stderr, "could not ttl\n");
                return (STATUS_SYNTAX);
        }
@@ -1600,7 +1600,7 @@ evaluate_class(char *cmdline) {
        dns_rdataclass_t rdclass;
 
        word = nsu_strsep(&cmdline, " \t\r\n");
-       if (*word == 0) {
+       if (word == NULL || *word == 0) {
                fprintf(stderr, "could not read class name\n");
                return (STATUS_SYNTAX);
        }
@@ -1658,7 +1658,7 @@ update_addordelete(char *cmdline, isc_boolean_t isdelete) {
         * If it's a delete, ignore a TTL if present (for compatibility).
         */
        word = nsu_strsep(&cmdline, " \t\r\n");
-       if (*word == 0) {
+       if (word == NULL || *word == 0) {
                if (!isdelete) {
                        fprintf(stderr, "could not read owner ttl\n");
                        goto failure;
@@ -1699,7 +1699,7 @@ update_addordelete(char *cmdline, isc_boolean_t isdelete) {
         */
        word = nsu_strsep(&cmdline, " \t\r\n");
  parseclass:
-       if (*word == 0) {
+       if (word == NULL || *word == 0) {
                if (isdelete) {
                        rdataclass = dns_rdataclass_any;
                        rdatatype = dns_rdatatype_any;
@@ -1723,7 +1723,7 @@ update_addordelete(char *cmdline, isc_boolean_t isdelete) {
                 * Now read the type.
                 */
                word = nsu_strsep(&cmdline, " \t\r\n");
-               if (*word == 0) {
+               if (word == NULL || *word == 0) {
                        if (isdelete) {
                                rdataclass = dns_rdataclass_any;
                                rdatatype = dns_rdatatype_any;
@@ -1803,7 +1803,7 @@ evaluate_update(char *cmdline) {
 
        ddebug("evaluate_update()");
        word = nsu_strsep(&cmdline, " \t\r\n");
-       if (*word == 0) {
+       if (word == NULL || *word == 0) {
                fprintf(stderr, "could not read operation code\n");
                return (STATUS_SYNTAX);
        }
@@ -1896,7 +1896,7 @@ do_next_command(char *cmdline) {
        ddebug("do_next_command()");
        word = nsu_strsep(&cmdline, " \t\r\n");
 
-       if (*word == 0)
+       if (word == NULL || *word == 0)
                return (STATUS_SEND);
        if (word[0] == ';')
                return (STATUS_MORE);
@@ -2017,8 +2017,17 @@ get_next_command(void) {
        } else
                cmdline = fgets(cmdlinebuf, MAXCMD, input);
        isc_app_unblock();
-       if (cmdline != NULL)
+
+       if (cmdline != NULL) {
+               char *tmp = cmdline;
+
+               /*
+                * Normalize input by removing any eol as readline()
+                * removes eol but fgets doesn't.
+                */
+               (void)nsu_strsep(&tmp, "\r\n");
                result = do_next_command(cmdline);
+       }
 #ifdef HAVE_READLINE
        if (interactive)
                free(cmdline);
diff --git a/bin/tests/system/nsupdate/commandlist b/bin/tests/system/nsupdate/commandlist
new file mode 100644 (file)
index 0000000..41c8049
--- /dev/null
@@ -0,0 +1,15 @@
+server 127.0.0.1
+server 127.0.0.1 port
+update
+update delete
+update delete dummy
+update delete dummy in
+update delete dummy in a
+update delete dummy in a 127.0.0.1
+update add
+update add domain
+update add domain 0
+update add domain 0 in
+update add domain 0 in a
+update add domain 0 a
+update add domain 0 a in
index fafebb5b84f7f06f47b79b9866fa811a050350ac..48988a8c8d5a82bd5ba74a2419e2da7ab6a382f8 100644 (file)
@@ -461,5 +461,28 @@ if [ $ret -ne 0 ]; then
     status=1
 fi
 
+n=`expr $n + 1`
+ret=0
+echo "I:check command list ($n)"
+(
+while read cmd 
+do
+    echo "$cmd" | $NSUPDATE  > /dev/null 2>&1
+    if test $? -gt 1 ; then
+       echo "I: failed ($cmd)"
+       ret=1
+    fi
+    echo "$cmd " | $NSUPDATE  > /dev/null 2>&1
+    if test $? -gt 1 ; then
+       echo "I: failed ($cmd)"
+       ret=1
+    fi
+done
+exit $ret
+) < commandlist || ret=1
+if [ $ret -ne 0 ]; then
+    status=1
+fi
+
 echo "I:exit status: $status"
 exit $status