1/*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 9 * 10 * This software is licensed as described in the file COPYING, which 11 * you should have received as part of this distribution. The terms 12 * are also available at https://curl.se/docs/copyright.html. 13 * 14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15 * copies of the Software, and permit persons to whom the Software is 16 * furnished to do so, under the terms of the COPYING file. 17 * 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 * KIND, either express or implied. 20 * 21 * SPDX-License-Identifier: curl 22 * 23 ***************************************************************************/ 24/* 25 * This source code is used for lib1502, lib1503, lib1504 and lib1505 with 26 * only #ifdefs controlling the cleanup sequence. 27 * 28 * Test case 1502 converted from bug report #3575448, identifying a memory 29 * leak in the CURLOPT_RESOLVE handling with the multi interface. 30 */ 31 32#include "test.h" 33 34#include <limits.h> 35 36#include "testutil.h" 37#include "warnless.h" 38#include "memdebug.h" 39 40#define TEST_HANG_TIMEOUT 60 * 1000 41 42int test(char *URL) 43{ 44 CURL *easy = NULL; 45 CURL *dup; 46 CURLM *multi = NULL; 47 int still_running; 48 int res = 0; 49 50 char redirect[160]; 51 52 /* DNS cache injection */ 53 struct curl_slist *dns_cache_list; 54 55 res_global_init(CURL_GLOBAL_ALL); 56 if(res) { 57 return res; 58 } 59 60 msnprintf(redirect, sizeof(redirect), "google.com:%s:%s", libtest_arg2, 61 libtest_arg3); 62 63 start_test_timing(); 64 65 dns_cache_list = curl_slist_append(NULL, redirect); 66 if(!dns_cache_list) { 67 fprintf(stderr, "curl_slist_append() failed\n"); 68 curl_global_cleanup(); 69 return TEST_ERR_MAJOR_BAD; 70 } 71 72 easy_init(easy); 73 74 easy_setopt(easy, CURLOPT_URL, URL); 75 easy_setopt(easy, CURLOPT_HEADER, 1L); 76 easy_setopt(easy, CURLOPT_RESOLVE, dns_cache_list); 77 78 dup = curl_easy_duphandle(easy); 79 if(dup) { 80 curl_easy_cleanup(easy); 81 easy = dup; 82 } 83 else { 84 curl_slist_free_all(dns_cache_list); 85 curl_easy_cleanup(easy); 86 curl_global_cleanup(); 87 return CURLE_OUT_OF_MEMORY; 88 } 89 90 multi_init(multi); 91 92 multi_add_handle(multi, easy); 93 94 multi_perform(multi, &still_running); 95 96 abort_on_test_timeout(); 97 98 while(still_running) { 99 struct timeval timeout; 100 fd_set fdread; 101 fd_set fdwrite; 102 fd_set fdexcep; 103 int maxfd = -99; 104 105 FD_ZERO(&fdread); 106 FD_ZERO(&fdwrite); 107 FD_ZERO(&fdexcep); 108 timeout.tv_sec = 1; 109 timeout.tv_usec = 0; 110 111 multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd); 112 113 /* At this point, maxfd is guaranteed to be greater or equal than -1. */ 114 115 select_test(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout); 116 117 abort_on_test_timeout(); 118 119 multi_perform(multi, &still_running); 120 121 abort_on_test_timeout(); 122 } 123 124test_cleanup: 125 126#ifdef LIB1502 127 /* undocumented cleanup sequence - type UA */ 128 curl_multi_cleanup(multi); 129 curl_easy_cleanup(easy); 130 curl_global_cleanup(); 131#endif 132 133#ifdef LIB1503 134 /* proper cleanup sequence - type PA */ 135 curl_multi_remove_handle(multi, easy); 136 curl_multi_cleanup(multi); 137 curl_easy_cleanup(easy); 138 curl_global_cleanup(); 139#endif 140 141#ifdef LIB1504 142 /* undocumented cleanup sequence - type UB */ 143 curl_easy_cleanup(easy); 144 curl_multi_cleanup(multi); 145 curl_global_cleanup(); 146#endif 147 148#ifdef LIB1505 149 /* proper cleanup sequence - type PB */ 150 curl_multi_remove_handle(multi, easy); 151 curl_easy_cleanup(easy); 152 curl_multi_cleanup(multi); 153 curl_global_cleanup(); 154#endif 155 156 curl_slist_free_all(dns_cache_list); 157 158 return res; 159} 160