unit1652.c (5601B)
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 #include "unitcheck.h" 25 26 #include "urldata.h" 27 #include "sendf.h" 28 29 /* 30 * This test hardcodes the knowledge of the buffer size which is internal to 31 * Curl_infof(). If that buffer is changed in size, this tests needs to be 32 * updated to still be valid. 33 */ 34 35 static char input[4096]; 36 static char output[4096]; 37 38 /* 39 * This debugf callback is simply dumping the string into the static buffer 40 * for the unit test to inspect. Since we know that we're only dealing with 41 * text we can afford the luxury of skipping the type check here. 42 */ 43 static int debugf_cb(CURL *handle, curl_infotype type, char *buf, size_t size, 44 void *userptr) 45 { 46 (void)handle; 47 (void)type; 48 (void)userptr; 49 50 memset(output, '\0', sizeof(output)); 51 memcpy(output, buf, size); 52 return 0; 53 } 54 55 static CURLcode t1652_setup(struct Curl_easy **easy) 56 { 57 CURLcode res = CURLE_OK; 58 59 global_init(CURL_GLOBAL_ALL); 60 *easy = curl_easy_init(); 61 if(!*easy) { 62 curl_global_cleanup(); 63 return CURLE_OUT_OF_MEMORY; 64 } 65 curl_easy_setopt(*easy, CURLOPT_DEBUGFUNCTION, debugf_cb); 66 curl_easy_setopt(*easy, CURLOPT_VERBOSE, 1L); 67 return res; 68 } 69 70 static void t1652_stop(struct Curl_easy *easy) 71 { 72 curl_easy_cleanup(easy); 73 curl_global_cleanup(); 74 } 75 76 static int verify(const char *info, const char *two) 77 { 78 /* the 'info' one has a newline appended */ 79 char *nl = strchr(info, '\n'); 80 if(!nl) 81 return 1; /* nope */ 82 return strncmp(info, two, nl - info); 83 } 84 85 static CURLcode test_unit1652(char *arg) 86 { 87 struct Curl_easy *easy; 88 89 UNITTEST_BEGIN(t1652_setup(&easy)) 90 91 #if defined(CURL_GNUC_DIAG) && !defined(__clang__) 92 #pragma GCC diagnostic push 93 #pragma GCC diagnostic ignored "-Wformat" 94 #pragma GCC diagnostic ignored "-Wformat-zero-length" 95 #if __GNUC__ >= 7 96 #pragma GCC diagnostic ignored "-Wformat-overflow" 97 #endif 98 #endif 99 100 /* Injecting a simple short string via a format */ 101 curl_msnprintf(input, sizeof(input), "Simple Test"); 102 Curl_infof(easy, "%s", input); 103 fail_unless(verify(output, input) == 0, "Simple string test"); 104 105 /* Injecting a few different variables with a format */ 106 Curl_infof(easy, "%s %u testing %lu", input, 42, 43L); 107 fail_unless(verify(output, "Simple Test 42 testing 43\n") == 0, 108 "Format string"); 109 110 /* Variations of empty strings */ 111 Curl_infof(easy, ""); 112 fail_unless(strlen(output) == 1, "Empty string"); 113 Curl_infof(easy, "%s", (char *)NULL); 114 fail_unless(verify(output, "(nil)") == 0, "Passing NULL as string"); 115 116 /* Note: libcurl's tracebuffer hold 2048 bytes, so the max strlen() we 117 * get out of it is 2047, since we need a \0 at the end. 118 * Curl_infof() in addition adds a \n at the end, making the effective 119 * output 2046 characters. 120 * Any input that long or longer will truncated, ending in '...\n'. 121 */ 122 123 /* A string just long enough to not be truncated */ 124 memset(input, '\0', sizeof(input)); 125 memset(input, 'A', 2045); 126 Curl_infof(easy, "%s", input); 127 fprintf(stderr, "output len %d: %s", (int)strlen(output), output); 128 /* output is input + \n */ 129 fail_unless(strlen(output) == 2046, "No truncation of infof input"); 130 fail_unless(verify(output, input) == 0, "No truncation of infof input"); 131 fail_unless(output[sizeof(output) - 1] == '\0', 132 "No truncation of infof input"); 133 134 /* Just over the limit without newline for truncation via '...' */ 135 memset(input + 2045, 'A', 4); 136 Curl_infof(easy, "%s", input); 137 fprintf(stderr, "output len %d: %s", (int)strlen(output), output); 138 fail_unless(strlen(output) == 2047, "Truncation of infof input 1"); 139 fail_unless(output[sizeof(output) - 1] == '\0', 140 "Truncation of infof input 1"); 141 142 /* Just over the limit with newline for truncation via '...' */ 143 memset(input + 2045, 'A', 4); 144 memset(input + 2045 + 4, '\n', 1); 145 Curl_infof(easy, "%s", input); 146 fprintf(stderr, "output len %d: %s", (int)strlen(output), output); 147 fail_unless(strlen(output) == 2047, "Truncation of infof input 2"); 148 fail_unless(output[sizeof(output) - 1] == '\0', 149 "Truncation of infof input 2"); 150 151 /* Way over the limit for truncation via '...' */ 152 memset(input, '\0', sizeof(input)); 153 memset(input, 'A', sizeof(input) - 1); 154 Curl_infof(easy, "%s", input); 155 fprintf(stderr, "output len %d: %s", (int)strlen(output), output); 156 fail_unless(strlen(output) == 2047, "Truncation of infof input 3"); 157 fail_unless(output[sizeof(output) - 1] == '\0', 158 "Truncation of infof input 3"); 159 160 #if defined(CURL_GNUC_DIAG) && !defined(__clang__) 161 #pragma GCC diagnostic pop 162 #endif 163 164 UNITTEST_END(t1652_stop(easy)) 165 }