2 * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
9 #define OPENSSL_SUPPRESS_DEPRECATED
12 #include <openssl/bio.h>
17 static int my_param_count
;
18 static BIO
*my_param_b
[MAXCOUNT
];
19 static int my_param_oper
[MAXCOUNT
];
20 static const char *my_param_argp
[MAXCOUNT
];
21 static int my_param_argi
[MAXCOUNT
];
22 static long my_param_argl
[MAXCOUNT
];
23 static long my_param_ret
[MAXCOUNT
];
24 static size_t my_param_len
[MAXCOUNT
];
25 static size_t my_param_processed
[MAXCOUNT
];
27 static long my_bio_cb_ex(BIO
*b
, int oper
, const char *argp
, size_t len
,
28 int argi
, long argl
, int ret
, size_t *processed
)
30 if (my_param_count
>= MAXCOUNT
)
32 my_param_b
[my_param_count
] = b
;
33 my_param_oper
[my_param_count
] = oper
;
34 my_param_argp
[my_param_count
] = argp
;
35 my_param_argi
[my_param_count
] = argi
;
36 my_param_argl
[my_param_count
] = argl
;
37 my_param_ret
[my_param_count
] = ret
;
38 my_param_len
[my_param_count
] = len
;
39 my_param_processed
[my_param_count
] = processed
!= NULL
? *processed
: 0;
45 static int test_bio_callback_ex(void)
50 char test1
[] = "test";
51 const size_t test1len
= sizeof(test1
) - 1;
52 char test2
[] = "hello";
53 const size_t test2len
= sizeof(test2
) - 1;
58 bio
= BIO_new(BIO_s_mem());
62 BIO_set_callback_ex(bio
, my_bio_cb_ex
);
63 i
= BIO_write(bio
, test1
, test1len
);
64 if (!TEST_int_eq(i
, test1len
)
65 || !TEST_int_eq(my_param_count
, 2)
66 || !TEST_ptr_eq(my_param_b
[0], bio
)
67 || !TEST_int_eq(my_param_oper
[0], BIO_CB_WRITE
)
68 || !TEST_ptr_eq(my_param_argp
[0], test1
)
69 || !TEST_size_t_eq(my_param_len
[0], test1len
)
70 || !TEST_long_eq(my_param_argl
[0], 0L)
71 || !TEST_int_eq((int)my_param_ret
[0], 1)
72 || !TEST_ptr_eq(my_param_b
[1], bio
)
73 || !TEST_int_eq(my_param_oper
[1], BIO_CB_WRITE
| BIO_CB_RETURN
)
74 || !TEST_ptr_eq(my_param_argp
[1], test1
)
75 || !TEST_size_t_eq(my_param_len
[1], test1len
)
76 || !TEST_long_eq(my_param_argl
[1], 0L)
77 || !TEST_size_t_eq(my_param_processed
[1], test1len
)
78 || !TEST_int_eq((int)my_param_ret
[1], 1))
82 i
= BIO_read(bio
, buf
, sizeof(buf
));
83 if (!TEST_mem_eq(buf
, i
, test1
, test1len
)
84 || !TEST_int_eq(my_param_count
, 2)
85 || !TEST_ptr_eq(my_param_b
[0], bio
)
86 || !TEST_int_eq(my_param_oper
[0], BIO_CB_READ
)
87 || !TEST_ptr_eq(my_param_argp
[0], buf
)
88 || !TEST_size_t_eq(my_param_len
[0], sizeof(buf
))
89 || !TEST_long_eq(my_param_argl
[0], 0L)
90 || !TEST_int_eq((int)my_param_ret
[0], 1)
91 || !TEST_ptr_eq(my_param_b
[1], bio
)
92 || !TEST_int_eq(my_param_oper
[1], BIO_CB_READ
| BIO_CB_RETURN
)
93 || !TEST_ptr_eq(my_param_argp
[1], buf
)
94 || !TEST_size_t_eq(my_param_len
[1], sizeof(buf
))
95 || !TEST_long_eq(my_param_argl
[1], 0L)
96 || !TEST_size_t_eq(my_param_processed
[1], test1len
)
97 || !TEST_int_eq((int)my_param_ret
[1], 1))
100 /* By default a mem bio returns -1 if it has run out of data */
102 i
= BIO_read(bio
, buf
, sizeof(buf
));
103 if (!TEST_int_eq(i
, -1)
104 || !TEST_int_eq(my_param_count
, 2)
105 || !TEST_ptr_eq(my_param_b
[0], bio
)
106 || !TEST_int_eq(my_param_oper
[0], BIO_CB_READ
)
107 || !TEST_ptr_eq(my_param_argp
[0], buf
)
108 || !TEST_size_t_eq(my_param_len
[0], sizeof(buf
))
109 || !TEST_long_eq(my_param_argl
[0], 0L)
110 || !TEST_int_eq((int)my_param_ret
[0], 1)
111 || !TEST_ptr_eq(my_param_b
[1], bio
)
112 || !TEST_int_eq(my_param_oper
[1], BIO_CB_READ
| BIO_CB_RETURN
)
113 || !TEST_ptr_eq(my_param_argp
[1], buf
)
114 || !TEST_size_t_eq(my_param_len
[1], sizeof(buf
))
115 || !TEST_long_eq(my_param_argl
[1], 0L)
116 || !TEST_size_t_eq(my_param_processed
[1], 0)
117 || !TEST_int_eq((int)my_param_ret
[1], -1))
120 /* Force the mem bio to return 0 if it has run out of data */
122 i
= BIO_set_mem_eof_return(bio
, 0);
123 if (!TEST_int_eq(i
, 1)
124 || !TEST_int_eq(my_param_count
, 2)
125 || !TEST_ptr_eq(my_param_b
[0], bio
)
126 || !TEST_int_eq(my_param_oper
[0], BIO_CB_CTRL
)
127 || !TEST_ptr_eq(my_param_argp
[0], NULL
)
128 || !TEST_int_eq(my_param_argi
[0], BIO_C_SET_BUF_MEM_EOF_RETURN
)
129 || !TEST_long_eq(my_param_argl
[0], 0L)
130 || !TEST_int_eq((int)my_param_ret
[0], 1)
131 || !TEST_ptr_eq(my_param_b
[1], bio
)
132 || !TEST_int_eq(my_param_oper
[1], BIO_CB_CTRL
| BIO_CB_RETURN
)
133 || !TEST_ptr_eq(my_param_argp
[1], NULL
)
134 || !TEST_int_eq(my_param_argi
[1], BIO_C_SET_BUF_MEM_EOF_RETURN
)
135 || !TEST_long_eq(my_param_argl
[1], 0L)
136 || !TEST_int_eq((int)my_param_ret
[1], 1))
139 i
= BIO_read(bio
, buf
, sizeof(buf
));
140 if (!TEST_int_eq(i
, 0)
141 || !TEST_int_eq(my_param_count
, 2)
142 || !TEST_ptr_eq(my_param_b
[0], bio
)
143 || !TEST_int_eq(my_param_oper
[0], BIO_CB_READ
)
144 || !TEST_ptr_eq(my_param_argp
[0], buf
)
145 || !TEST_size_t_eq(my_param_len
[0], sizeof(buf
))
146 || !TEST_long_eq(my_param_argl
[0], 0L)
147 || !TEST_int_eq((int)my_param_ret
[0], 1)
148 || !TEST_ptr_eq(my_param_b
[1], bio
)
149 || !TEST_int_eq(my_param_oper
[1], BIO_CB_READ
| BIO_CB_RETURN
)
150 || !TEST_ptr_eq(my_param_argp
[1], buf
)
151 || !TEST_size_t_eq(my_param_len
[1], sizeof(buf
))
152 || !TEST_long_eq(my_param_argl
[1], 0L)
153 || !TEST_size_t_eq(my_param_processed
[1], 0)
154 || !TEST_int_eq((int)my_param_ret
[1], 0))
158 i
= BIO_puts(bio
, test2
);
159 if (!TEST_int_eq(i
, 5)
160 || !TEST_int_eq(my_param_count
, 2)
161 || !TEST_ptr_eq(my_param_b
[0], bio
)
162 || !TEST_int_eq(my_param_oper
[0], BIO_CB_PUTS
)
163 || !TEST_ptr_eq(my_param_argp
[0], test2
)
164 || !TEST_int_eq(my_param_argi
[0], 0)
165 || !TEST_long_eq(my_param_argl
[0], 0L)
166 || !TEST_int_eq((int)my_param_ret
[0], 1)
167 || !TEST_ptr_eq(my_param_b
[1], bio
)
168 || !TEST_int_eq(my_param_oper
[1], BIO_CB_PUTS
| BIO_CB_RETURN
)
169 || !TEST_ptr_eq(my_param_argp
[1], test2
)
170 || !TEST_int_eq(my_param_argi
[1], 0)
171 || !TEST_long_eq(my_param_argl
[1], 0L)
172 || !TEST_size_t_eq(my_param_processed
[1], test2len
)
173 || !TEST_int_eq((int)my_param_ret
[1], 1))
178 if (!TEST_int_eq(i
, 1)
179 || !TEST_int_eq(my_param_count
, 1)
180 || !TEST_ptr_eq(my_param_b
[0], bio
)
181 || !TEST_int_eq(my_param_oper
[0], BIO_CB_FREE
)
182 || !TEST_ptr_eq(my_param_argp
[0], NULL
)
183 || !TEST_int_eq(my_param_argi
[0], 0)
184 || !TEST_long_eq(my_param_argl
[0], 0L)
185 || !TEST_int_eq((int)my_param_ret
[0], 1))
195 /* This helps finding memory leaks with ASAN */
196 memset(my_param_b
, 0, sizeof(my_param_b
));
197 memset(my_param_argp
, 0, sizeof(my_param_argp
));
201 #ifndef OPENSSL_NO_DEPRECATED_3_0
202 static long my_bio_callback(BIO
*b
, int oper
, const char *argp
, int argi
,
205 if (my_param_count
>= MAXCOUNT
)
207 my_param_b
[my_param_count
] = b
;
208 my_param_oper
[my_param_count
] = oper
;
209 my_param_argp
[my_param_count
] = argp
;
210 my_param_argi
[my_param_count
] = argi
;
211 my_param_argl
[my_param_count
] = argl
;
212 my_param_ret
[my_param_count
] = ret
;
217 static int test_bio_callback(void)
222 char test1
[] = "test";
223 const int test1len
= sizeof(test1
) - 1;
224 char test2
[] = "hello";
225 const int test2len
= sizeof(test2
) - 1;
230 bio
= BIO_new(BIO_s_mem());
234 BIO_set_callback(bio
, my_bio_callback
);
235 i
= BIO_write(bio
, test1
, test1len
);
236 if (!TEST_int_eq(i
, test1len
)
237 || !TEST_int_eq(my_param_count
, 2)
238 || !TEST_ptr_eq(my_param_b
[0], bio
)
239 || !TEST_int_eq(my_param_oper
[0], BIO_CB_WRITE
)
240 || !TEST_ptr_eq(my_param_argp
[0], test1
)
241 || !TEST_int_eq(my_param_argi
[0], test1len
)
242 || !TEST_long_eq(my_param_argl
[0], 0L)
243 || !TEST_long_eq(my_param_ret
[0], 1L)
244 || !TEST_ptr_eq(my_param_b
[1], bio
)
245 || !TEST_int_eq(my_param_oper
[1], BIO_CB_WRITE
| BIO_CB_RETURN
)
246 || !TEST_ptr_eq(my_param_argp
[1], test1
)
247 || !TEST_int_eq(my_param_argi
[1], test1len
)
248 || !TEST_long_eq(my_param_argl
[1], 0L)
249 || !TEST_long_eq(my_param_ret
[1], (long)test1len
))
253 i
= BIO_read(bio
, buf
, sizeof(buf
));
254 if (!TEST_mem_eq(buf
, i
, test1
, test1len
)
255 || !TEST_int_eq(my_param_count
, 2)
256 || !TEST_ptr_eq(my_param_b
[0], bio
)
257 || !TEST_int_eq(my_param_oper
[0], BIO_CB_READ
)
258 || !TEST_ptr_eq(my_param_argp
[0], buf
)
259 || !TEST_int_eq(my_param_argi
[0], sizeof(buf
))
260 || !TEST_long_eq(my_param_argl
[0], 0L)
261 || !TEST_long_eq(my_param_ret
[0], 1L)
262 || !TEST_ptr_eq(my_param_b
[1], bio
)
263 || !TEST_int_eq(my_param_oper
[1], BIO_CB_READ
| BIO_CB_RETURN
)
264 || !TEST_ptr_eq(my_param_argp
[1], buf
)
265 || !TEST_int_eq(my_param_argi
[1], sizeof(buf
))
266 || !TEST_long_eq(my_param_argl
[1], 0L)
267 || !TEST_long_eq(my_param_ret
[1], (long)test1len
))
270 /* By default a mem bio returns -1 if it has run out of data */
272 i
= BIO_read(bio
, buf
, sizeof(buf
));
273 if (!TEST_int_eq(i
, -1)
274 || !TEST_int_eq(my_param_count
, 2)
275 || !TEST_ptr_eq(my_param_b
[0], bio
)
276 || !TEST_int_eq(my_param_oper
[0], BIO_CB_READ
)
277 || !TEST_ptr_eq(my_param_argp
[0], buf
)
278 || !TEST_int_eq(my_param_argi
[0], sizeof(buf
))
279 || !TEST_long_eq(my_param_argl
[0], 0L)
280 || !TEST_long_eq(my_param_ret
[0], 1L)
281 || !TEST_ptr_eq(my_param_b
[1], bio
)
282 || !TEST_int_eq(my_param_oper
[1], BIO_CB_READ
| BIO_CB_RETURN
)
283 || !TEST_ptr_eq(my_param_argp
[1], buf
)
284 || !TEST_int_eq(my_param_argi
[1], sizeof(buf
))
285 || !TEST_long_eq(my_param_argl
[1], 0L)
286 || !TEST_long_eq(my_param_ret
[1], -1L))
289 /* Force the mem bio to return 0 if it has run out of data */
290 BIO_set_mem_eof_return(bio
, 0);
292 i
= BIO_read(bio
, buf
, sizeof(buf
));
293 if (!TEST_int_eq(i
, 0)
294 || !TEST_int_eq(my_param_count
, 2)
295 || !TEST_ptr_eq(my_param_b
[0], bio
)
296 || !TEST_int_eq(my_param_oper
[0], BIO_CB_READ
)
297 || !TEST_ptr_eq(my_param_argp
[0], buf
)
298 || !TEST_int_eq(my_param_argi
[0], sizeof(buf
))
299 || !TEST_long_eq(my_param_argl
[0], 0L)
300 || !TEST_long_eq(my_param_ret
[0], 1L)
301 || !TEST_ptr_eq(my_param_b
[1], bio
)
302 || !TEST_int_eq(my_param_oper
[1], BIO_CB_READ
| BIO_CB_RETURN
)
303 || !TEST_ptr_eq(my_param_argp
[1], buf
)
304 || !TEST_int_eq(my_param_argi
[1], sizeof(buf
))
305 || !TEST_long_eq(my_param_argl
[1], 0L)
306 || !TEST_long_eq(my_param_ret
[1], 0L))
310 i
= BIO_puts(bio
, test2
);
311 if (!TEST_int_eq(i
, 5)
312 || !TEST_int_eq(my_param_count
, 2)
313 || !TEST_ptr_eq(my_param_b
[0], bio
)
314 || !TEST_int_eq(my_param_oper
[0], BIO_CB_PUTS
)
315 || !TEST_ptr_eq(my_param_argp
[0], test2
)
316 || !TEST_int_eq(my_param_argi
[0], 0)
317 || !TEST_long_eq(my_param_argl
[0], 0L)
318 || !TEST_long_eq(my_param_ret
[0], 1L)
319 || !TEST_ptr_eq(my_param_b
[1], bio
)
320 || !TEST_int_eq(my_param_oper
[1], BIO_CB_PUTS
| BIO_CB_RETURN
)
321 || !TEST_ptr_eq(my_param_argp
[1], test2
)
322 || !TEST_int_eq(my_param_argi
[1], 0)
323 || !TEST_long_eq(my_param_argl
[1], 0L)
324 || !TEST_long_eq(my_param_ret
[1], (long)test2len
))
329 if (!TEST_int_eq(i
, 1)
330 || !TEST_int_eq(my_param_count
, 1)
331 || !TEST_ptr_eq(my_param_b
[0], bio
)
332 || !TEST_int_eq(my_param_oper
[0], BIO_CB_FREE
)
333 || !TEST_ptr_eq(my_param_argp
[0], NULL
)
334 || !TEST_int_eq(my_param_argi
[0], 0)
335 || !TEST_long_eq(my_param_argl
[0], 0L)
336 || !TEST_long_eq(my_param_ret
[0], 1L))
346 /* This helps finding memory leaks with ASAN */
347 memset(my_param_b
, 0, sizeof(my_param_b
));
348 memset(my_param_argp
, 0, sizeof(my_param_argp
));
353 int setup_tests(void)
355 ADD_TEST(test_bio_callback_ex
);
356 #ifndef OPENSSL_NO_DEPRECATED_3_0
357 ADD_TEST(test_bio_callback
);