diff --git a/CHANGES b/CHANGES index b9c7909920..16437031f5 100644 --- 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] , and were not C++ safe. diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c index b756a90c53..9d5d597026 100644 --- a/bin/nsupdate/nsupdate.c +++ b/bin/nsupdate/nsupdate.c @@ -1153,7 +1153,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); } @@ -1256,7 +1256,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; } @@ -1272,7 +1272,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; } @@ -1346,7 +1346,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); } @@ -1380,14 +1380,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; @@ -1421,14 +1421,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; @@ -1477,7 +1477,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); } @@ -1501,7 +1501,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); } @@ -1542,7 +1542,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); } @@ -1568,7 +1568,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; @@ -1593,7 +1593,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); } @@ -1627,7 +1627,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); } @@ -1685,7 +1685,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; @@ -1726,7 +1726,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; @@ -1750,7 +1750,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; @@ -1830,7 +1830,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); } @@ -1923,7 +1923,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); @@ -2044,8 +2044,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 index 0000000000..41c8049a32 --- /dev/null +++ b/bin/tests/system/nsupdate/commandlist @@ -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 diff --git a/bin/tests/system/nsupdate/tests.sh b/bin/tests/system/nsupdate/tests.sh index e9b837373c..bd5590e8e3 100644 --- a/bin/tests/system/nsupdate/tests.sh +++ b/bin/tests/system/nsupdate/tests.sh @@ -481,5 +481,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