1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
|
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* SPDX-License-Identifier: curl
*
***************************************************************************/
#include "unitcheck.h"
#include "urldata.h"
#include "sendf.h"
/*
* This test hardcodes the knowledge of the buffer size which is internal to
* Curl_infof(). If that buffer is changed in size, this tests needs to be
* updated to still be valid.
*/
static char input[4096];
static char output[4096];
/*
* This debugf callback is simply dumping the string into the static buffer
* for the unit test to inspect. Since we know that we're only dealing with
* text we can afford the luxury of skipping the type check here.
*/
static int debugf_cb(CURL *handle, curl_infotype type, char *buf, size_t size,
void *userptr)
{
(void)handle;
(void)type;
(void)userptr;
memset(output, '\0', sizeof(output));
memcpy(output, buf, size);
return 0;
}
static CURLcode t1652_setup(struct Curl_easy **easy)
{
CURLcode res = CURLE_OK;
global_init(CURL_GLOBAL_ALL);
*easy = curl_easy_init();
if(!*easy) {
curl_global_cleanup();
return CURLE_OUT_OF_MEMORY;
}
curl_easy_setopt(*easy, CURLOPT_DEBUGFUNCTION, debugf_cb);
curl_easy_setopt(*easy, CURLOPT_VERBOSE, 1L);
return res;
}
static void t1652_stop(struct Curl_easy *easy)
{
curl_easy_cleanup(easy);
curl_global_cleanup();
}
static int verify(const char *info, const char *two)
{
/* the 'info' one has a newline appended */
char *nl = strchr(info, '\n');
if(!nl)
return 1; /* nope */
return strncmp(info, two, nl - info);
}
static CURLcode test_unit1652(const char *arg)
{
struct Curl_easy *easy;
UNITTEST_BEGIN(t1652_setup(&easy))
#if defined(CURL_GNUC_DIAG) && !defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat"
#pragma GCC diagnostic ignored "-Wformat-zero-length"
#if __GNUC__ >= 7
#pragma GCC diagnostic ignored "-Wformat-overflow"
#endif
#endif
/* Injecting a simple short string via a format */
curl_msnprintf(input, sizeof(input), "Simple Test");
Curl_infof(easy, "%s", input);
fail_unless(verify(output, input) == 0, "Simple string test");
/* Injecting a few different variables with a format */
Curl_infof(easy, "%s %u testing %lu", input, 42, 43L);
fail_unless(verify(output, "Simple Test 42 testing 43\n") == 0,
"Format string");
/* Variations of empty strings */
Curl_infof(easy, "");
fail_unless(strlen(output) == 1, "Empty string");
Curl_infof(easy, "%s", (char *)NULL);
fail_unless(verify(output, "(nil)") == 0, "Passing NULL as string");
/* Note: libcurl's tracebuffer hold 2048 bytes, so the max strlen() we
* get out of it is 2047, since we need a \0 at the end.
* Curl_infof() in addition adds a \n at the end, making the effective
* output 2046 characters.
* Any input that long or longer will truncated, ending in '...\n'.
*/
/* A string just long enough to not be truncated */
memset(input, '\0', sizeof(input));
memset(input, 'A', 2045);
Curl_infof(easy, "%s", input);
fprintf(stderr, "output len %d: %s", (int)strlen(output), output);
/* output is input + \n */
fail_unless(strlen(output) == 2046, "No truncation of infof input");
fail_unless(verify(output, input) == 0, "No truncation of infof input");
fail_unless(output[sizeof(output) - 1] == '\0',
"No truncation of infof input");
/* Just over the limit without newline for truncation via '...' */
memset(input + 2045, 'A', 4);
Curl_infof(easy, "%s", input);
fprintf(stderr, "output len %d: %s", (int)strlen(output), output);
fail_unless(strlen(output) == 2047, "Truncation of infof input 1");
fail_unless(output[sizeof(output) - 1] == '\0',
"Truncation of infof input 1");
/* Just over the limit with newline for truncation via '...' */
memset(input + 2045, 'A', 4);
memset(input + 2045 + 4, '\n', 1);
Curl_infof(easy, "%s", input);
fprintf(stderr, "output len %d: %s", (int)strlen(output), output);
fail_unless(strlen(output) == 2047, "Truncation of infof input 2");
fail_unless(output[sizeof(output) - 1] == '\0',
"Truncation of infof input 2");
/* Way over the limit for truncation via '...' */
memset(input, '\0', sizeof(input));
memset(input, 'A', sizeof(input) - 1);
Curl_infof(easy, "%s", input);
fprintf(stderr, "output len %d: %s", (int)strlen(output), output);
fail_unless(strlen(output) == 2047, "Truncation of infof input 3");
fail_unless(output[sizeof(output) - 1] == '\0',
"Truncation of infof input 3");
#if defined(CURL_GNUC_DIAG) && !defined(__clang__)
#pragma GCC diagnostic pop
#endif
UNITTEST_END(t1652_stop(easy))
}
|