From 07a926724c0a91d85b85a94441938d0094e88cff Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Thu, 21 Sep 2000 11:53:16 +0000 Subject: [PATCH] 481. [bug] nslookup:get_next_command() stack size exceeds per thread limit. 480. [bug] strtok() is not thread safe. [RT #349] replaced strtok() w/ strsep(). --- CHANGES | 5 ++++ bin/dig/dig.c | 24 ++++++++++------- bin/dig/dighost.c | 14 +++++----- bin/dig/nslookup.c | 65 ++++++++++++++++++++++++++-------------------- 4 files changed, 65 insertions(+), 43 deletions(-) diff --git a/CHANGES b/CHANGES index b18cedb726..2b6ab4d9f9 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,8 @@ + 481. [bug] nslookup:get_next_command() stack size exceeds + per thread limit. + + 480. [bug] strtok() is not thread safe. [RT #349] + 479. [func] The test suite can now be run by typing "make check" or "make test" at the top level. diff --git a/bin/dig/dig.c b/bin/dig/dig.c index d22fafd93c..6c9735e12d 100644 --- a/bin/dig/dig.c +++ b/bin/dig/dig.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dig.c,v 1.92 2000/09/13 00:27:21 mws Exp $ */ +/* $Id: dig.c,v 1.93 2000/09/21 11:53:13 marka Exp $ */ #include #include @@ -586,6 +586,7 @@ parse_args(isc_boolean_t is_batchfile, isc_boolean_t config_only, char rcfile[132]; #endif isc_boolean_t nibble = ISC_FALSE; + char *input; /* * The semantics for parsing the args is a bit complex; if @@ -618,11 +619,12 @@ parse_args(isc_boolean_t is_batchfile, isc_boolean_t config_only, batchfp) != 0) { debug("config line %s", batchline); bargc = 1; - bargv[bargc] = strtok(batchline, " \t\r\n"); + input = batchline; + bargv[bargc] = strsep(&input, " \t\r\n"); while ((bargv[bargc] != NULL) && (bargc < 14)) { bargc++; - bargv[bargc] = strtok(NULL, " \t\r\n"); + bargv[bargc] = strsep(&input, " \t\r\n"); } bargv[0] = argv[0]; @@ -909,13 +911,14 @@ parse_args(isc_boolean_t is_batchfile, isc_boolean_t config_only, rv++; rc--; } - ptr = strtok(ptr,":"); + input = ptr; + ptr = strsep(&input,":"); if (ptr == NULL) { show_usage(); exit(1); } strncpy(keynametext, ptr, MXNAME); - ptr = strtok(NULL, ""); + ptr = strsep(&input, ""); if (ptr == NULL) { show_usage(); exit(1); @@ -1093,10 +1096,11 @@ parse_args(isc_boolean_t is_batchfile, isc_boolean_t config_only, if (fgets(batchline, sizeof(batchline), batchfp) != 0) { debug("batch line %s", batchline); bargc = 1; - bargv[bargc] = strtok(batchline, " \t\r\n"); + input = batchline; + bargv[bargc] = strsep(&input, " \t\r\n"); while ((bargv[bargc] != NULL) && (bargc < 14)) { bargc++; - bargv[bargc] = strtok(NULL, " \t\r\n"); + bargv[bargc] = strsep(&input, " \t\r\n"); } bargv[0] = argv[0]; @@ -1132,6 +1136,7 @@ dighost_shutdown(void) { char batchline[MXNAME]; int bargc; char *bargv[16]; + char *input; if (batchname == NULL) { @@ -1150,10 +1155,11 @@ dighost_shutdown(void) { if (fgets(batchline, sizeof(batchline), batchfp) != 0) { debug("batch line %s", batchline); bargc = 1; - bargv[bargc] = strtok(batchline, " \t\r\n"); + input = batchline; + bargv[bargc] = strsep(&input, " \t\r\n"); while ((bargv[bargc] != NULL) && (bargc < 14)) { bargc++; - bargv[bargc] = strtok(NULL, " \t\r\n"); + bargv[bargc] = strsep(&input, " \t\r\n"); } bargv[0] = argv0; diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index 0d1578b34b..70f83528d9 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dighost.c,v 1.127 2000/09/14 20:11:47 mws Exp $ */ +/* $Id: dighost.c,v 1.128 2000/09/21 11:53:14 marka Exp $ */ /* * Notice to programmers: Do not use this code as an example of how to @@ -500,6 +500,7 @@ setup_system(void) { dig_server_t *srv; dig_searchlist_t *search; isc_boolean_t get_servers; + char *input; debug("setup_system()"); @@ -521,12 +522,13 @@ setup_system(void) { /* XXX Use lwres resolv.conf reader */ if (fp != NULL) { while (fgets(rcinput, MXNAME, fp) != 0) { - ptr = strtok(rcinput, " \t\r\n"); + input = rcinput; + ptr = strsep(&input, " \t\r\n"); if (ptr != NULL) { if (get_servers && strcasecmp(ptr, "nameserver") == 0) { debug("got a nameserver line"); - ptr = strtok(NULL, " \t\r\n"); + ptr = strsep(&input, " \t\r\n"); if (ptr != NULL) { srv = make_server(ptr); ISC_LIST_APPEND @@ -534,7 +536,7 @@ setup_system(void) { srv, link); } } else if (strcasecmp(ptr, "options") == 0) { - ptr = strtok(NULL, " \t\r\n"); + ptr = strsep(&input, " \t\r\n"); if (ptr != NULL) { if((strncasecmp(ptr, "ndots:", 6) == 0) && @@ -547,7 +549,7 @@ setup_system(void) { } } } else if (strcasecmp(ptr, "search") == 0){ - while ((ptr = strtok(NULL, " \t\r\n")) + while ((ptr = strsep(&input, " \t\r\n")) != NULL) { debug("adding search %s", ptr); @@ -572,7 +574,7 @@ setup_system(void) { } else if ((strcasecmp(ptr, "domain") == 0) && (fixeddomain[0] == 0 )){ have_domain = ISC_TRUE; - while ((ptr = strtok(NULL, " \t\r\n")) + while ((ptr = strsep(&input, " \t\r\n")) != NULL) { search = isc_mem_allocate( mctx, sizeof(struct diff --git a/bin/dig/nslookup.c b/bin/dig/nslookup.c index ba312288d6..48034b6d2a 100644 --- a/bin/dig/nslookup.c +++ b/bin/dig/nslookup.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: nslookup.c,v 1.45 2000/09/14 22:03:52 mws Exp $ */ +/* $Id: nslookup.c,v 1.46 2000/09/21 11:53:16 marka Exp $ */ #include @@ -193,6 +193,7 @@ printsection(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers, dns_rdataset_t *rdataset = NULL; dns_rdata_t rdata; char *ptr; + char *input; UNUSED(query); UNUSED(headers); @@ -256,41 +257,41 @@ printsection(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers, check_result(result, "dns_rdata_totext"); ((char *)isc_buffer_used(b))[0]=0; - ptr = strtok(isc_buffer_base(b), - " \t\r\n"); + input = isc_buffer_base(b); + ptr = strsep(&input, " \t\r\n"); if (ptr == NULL) break; printf("\torigin = %s\n", ptr); - ptr = strtok(NULL, " \t\r\n"); + ptr = strsep(&input, " \t\r\n"); if (ptr == NULL) break; printf("\tmail addr = %s\n", ptr); - ptr = strtok(NULL, " \t\r\n"); + ptr = strsep(&input, " \t\r\n"); if (ptr == NULL) break; - ptr = strtok(NULL, " \t\r\n"); + ptr = strsep(&input, " \t\r\n"); if (ptr == NULL) break; printf("\tserial = %s\n", ptr); - ptr = strtok(NULL, " \t\r\n"); + ptr = strsep(&input, " \t\r\n"); if (ptr == NULL) break; printf("\trefresh = %s\n", ptr); - ptr = strtok(NULL, " \t\r\n"); + ptr = strsep(&input, " \t\r\n"); if (ptr == NULL) break; printf("\tretry = %s\n", ptr); - ptr = strtok(NULL, " \t\r\n"); + ptr = strsep(&input, " \t\r\n"); if (ptr == NULL) break; printf("\texpire = %s\n", ptr); - ptr = strtok(NULL, " \t\r\n"); + ptr = strsep(&input, " \t\r\n"); if (ptr == NULL) break; printf("\tminimum = %s\n", @@ -347,6 +348,7 @@ detailsection(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers, dns_rdataset_t *rdataset = NULL; dns_rdata_t rdata; char *ptr; + char *input; UNUSED(query); @@ -404,41 +406,41 @@ detailsection(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers, check_result(result, "dns_rdata_totext"); ((char *)isc_buffer_used(b))[0]=0; - ptr = strtok(isc_buffer_base(b), - " \t\r\n"); + input = isc_buffer_base(b); + ptr = strsep(&input, " \t\r\n"); if (ptr == NULL) break; printf("\torigin = %s\n", ptr); - ptr = strtok(NULL, " \t\r\n"); + ptr = strsep(&input, " \t\r\n"); if (ptr == NULL) break; printf("\tmail addr = %s\n", ptr); - ptr = strtok(NULL, " \t\r\n"); + ptr = strsep(&input, " \t\r\n"); if (ptr == NULL) break; - ptr = strtok(NULL, " \t\r\n"); + ptr = strsep(&input, " \t\r\n"); if (ptr == NULL) break; printf("\tserial = %s\n", ptr); - ptr = strtok(NULL, " \t\r\n"); + ptr = strsep(&input, " \t\r\n"); if (ptr == NULL) break; printf("\trefresh = %s\n", ptr); - ptr = strtok(NULL, " \t\r\n"); + ptr = strsep(&input, " \t\r\n"); if (ptr == NULL) break; printf("\tretry = %s\n", ptr); - ptr = strtok(NULL, " \t\r\n"); + ptr = strsep(&input, " \t\r\n"); if (ptr == NULL) break; printf("\texpire = %s\n", ptr); - ptr = strtok(NULL, " \t\r\n"); + ptr = strsep(&input, " \t\r\n"); if (ptr == NULL) break; printf("\tminimum = %s\n", @@ -758,19 +760,24 @@ setsrv(char *opt) { static void get_next_command(void) { - char input[COMMSIZE]; + char *buf; char *ptr, *arg; + char *input; + buf = isc_mem_allocate(mctx, COMMSIZE); + if (buf == NULL) + fatal("Memory allocation failure."); fputs("> ", stderr); - ptr = fgets(input, COMMSIZE, stdin); + ptr = fgets(buf, COMMSIZE, stdin); if (ptr == NULL) { in_use = ISC_FALSE; - return; + goto cleanup; } - ptr = strtok(input, " \t\r\n"); + input = buf; + ptr = strsep(&input, " \t\r\n"); if (ptr == NULL) - return; - arg = strtok(NULL, " \t\r\n"); + goto cleanup; + arg = strsep(&input, " \t\r\n"); if ((strcasecmp(ptr, "set") == 0) && (arg != NULL)) setoption(arg); @@ -780,21 +787,23 @@ get_next_command(void) { setsrv(arg); } else if (strcasecmp(ptr, "exit") == 0) { in_use = ISC_FALSE; - return; + goto cleanup; } else if (strcasecmp(ptr, "help") == 0 || strcasecmp(ptr, "?") == 0) { printf("The '%s' command is not yet implemented.\n", ptr); - return; + goto cleanup; } else if (strcasecmp(ptr, "finger") == 0 || strcasecmp(ptr, "root") == 0 || strcasecmp(ptr, "ls") == 0 || strcasecmp(ptr, "view") == 0) { printf("The '%s' command is not implemented.\n", ptr); - return; + goto cleanup; } else addlookup(ptr); + cleanup: + isc_mem_free(mctx, buf); } static void