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#define CURL_NO_FMT_CHECKS 25 26#include "curlcheck.h" 27 28#include "urldata.h" 29#include "sendf.h" 30 31/* 32 * This test hardcodes the knowledge of the buffer size which is internal to 33 * Curl_infof(). If that buffer is changed in size, this tests needs to be 34 * updated to still be valid. 35 */ 36 37static struct Curl_easy *data; 38 39static char input[4096]; 40static char result[4096]; 41 42int debugf_cb(CURL *handle, curl_infotype type, char *buf, size_t size, 43 void *userptr); 44 45/* 46 * This debugf callback is simply dumping the string into the static buffer 47 * for the unit test to inspect. Since we know that we're only dealing with 48 * text we can afford the luxury of skipping the type check here. 49 */ 50int 51debugf_cb(CURL *handle, curl_infotype type, char *buf, size_t size, 52 void *userptr) 53{ 54 (void)handle; 55 (void)type; 56 (void)userptr; 57 58 memset(result, '\0', sizeof(result)); 59 memcpy(result, buf, size); 60 return 0; 61} 62 63static CURLcode 64unit_setup(void) 65{ 66 CURLcode res = CURLE_OK; 67 68 global_init(CURL_GLOBAL_ALL); 69 data = curl_easy_init(); 70 if(!data) { 71 curl_global_cleanup(); 72 return CURLE_OUT_OF_MEMORY; 73 } 74 curl_easy_setopt(data, CURLOPT_DEBUGFUNCTION, debugf_cb); 75 curl_easy_setopt(data, CURLOPT_VERBOSE, 1L); 76 return res; 77} 78 79static void 80unit_stop(void) 81{ 82 curl_easy_cleanup(data); 83 curl_global_cleanup(); 84} 85 86static int verify(const char *info, const char *two) 87{ 88 /* the 'info' one has a newline appended */ 89 char *nl = strchr(info, '\n'); 90 if(!nl) 91 return 1; /* nope */ 92 return strncmp(info, two, nl - info); 93} 94 95UNITTEST_START 96 97/* Injecting a simple short string via a format */ 98msnprintf(input, sizeof(input), "Simple Test"); 99Curl_infof(data, "%s", input); 100fail_unless(verify(result, input) == 0, "Simple string test"); 101 102/* Injecting a few different variables with a format */ 103Curl_infof(data, "%s %u testing %lu", input, 42, 43L); 104fail_unless(verify(result, "Simple Test 42 testing 43\n") == 0, 105 "Format string"); 106 107/* Variations of empty strings */ 108Curl_infof(data, ""); 109fail_unless(strlen(result) == 1, "Empty string"); 110Curl_infof(data, "%s", (char *)NULL); 111fail_unless(verify(result, "(nil)") == 0, "Passing NULL as string"); 112 113/* A string just long enough to not be truncated */ 114memset(input, '\0', sizeof(input)); 115memset(input, 'A', 2047); 116Curl_infof(data, "%s", input); 117fail_unless(strlen(result) == 2048, "No truncation of infof input"); 118fail_unless(verify(result, input) == 0, "No truncation of infof input"); 119fail_unless(result[sizeof(result) - 1] == '\0', 120 "No truncation of infof input"); 121 122/* Just over the limit for truncation without newline */ 123memset(input + 2047, 'A', 4); 124Curl_infof(data, "%s", input); 125fail_unless(strlen(result) == 2048, "Truncation of infof input 1"); 126fail_unless(result[sizeof(result) - 1] == '\0', "Truncation of infof input 1"); 127 128/* Just over the limit for truncation with newline */ 129memset(input + 2047, 'A', 4); 130memset(input + 2047 + 4, '\n', 1); 131Curl_infof(data, "%s", input); 132fail_unless(strlen(result) == 2048, "Truncation of infof input 2"); 133fail_unless(result[sizeof(result) - 1] == '\0', "Truncation of infof input 2"); 134 135/* Way over the limit for truncation with newline */ 136memset(input, '\0', sizeof(input)); 137memset(input, 'A', sizeof(input) - 1); 138Curl_infof(data, "%s", input); 139fail_unless(strlen(result) == 2048, "Truncation of infof input 3"); 140fail_unless(result[sizeof(result) - 1] == '\0', "Truncation of infof input 3"); 141 142 143UNITTEST_STOP 144