diff options
Diffstat (limited to 'test/bio_readbuffer_test.c')
-rw-r--r-- | test/bio_readbuffer_test.c | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/test/bio_readbuffer_test.c b/test/bio_readbuffer_test.c new file mode 100644 index 000000000000..58a03c216365 --- /dev/null +++ b/test/bio_readbuffer_test.c @@ -0,0 +1,131 @@ +/* + * Copyright 2021 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <openssl/bio.h> +#include "testutil.h" + +static const char *filename = NULL; + +/* + * Test that a BIO_f_readbuffer() with a BIO_new_file() behaves nicely if + * BIO_gets() and BIO_read_ex() are both called. + * Since the BIO_gets() calls buffer the reads, the BIO_read_ex() should + * still be able to read the buffered data if we seek back to the start. + * + * The following cases are tested using tstid: + * 0 : Just use BIO_read_ex(). + * 1 : Try a few reads using BIO_gets() before using BIO_read_ex() + * 2 : Read the entire file using BIO_gets() before using BIO_read_ex(). + */ +static int test_readbuffer_file_bio(int tstid) +{ + int ret = 0, len, partial; + BIO *in = NULL, *in_bio = NULL, *readbuf_bio = NULL; + char buf[255]; + char expected[4096]; + size_t readbytes = 0, bytes = 0, count = 0; + + /* Open a file BIO and read all the data */ + if (!TEST_ptr(in = BIO_new_file(filename, "r")) + || !TEST_int_eq(BIO_read_ex(in, expected, sizeof(expected), + &readbytes), 1) + || !TEST_int_lt(readbytes, sizeof(expected))) + goto err; + BIO_free(in); + in = NULL; + + /* Create a new file bio that sits under a readbuffer BIO */ + if (!TEST_ptr(readbuf_bio = BIO_new(BIO_f_readbuffer())) + || !TEST_ptr(in_bio = BIO_new_file(filename, "r"))) + goto err; + + in_bio = BIO_push(readbuf_bio, in_bio); + readbuf_bio = NULL; + + if (!TEST_int_eq(BIO_tell(in_bio), 0)) + goto err; + + if (tstid != 0) { + partial = 4; + while (!BIO_eof(in_bio)) { + len = BIO_gets(in_bio, buf, sizeof(buf)); + if (len == 0) { + if (!TEST_true(BIO_eof(in_bio))) + goto err; + } else { + if (!TEST_int_gt(len, 0) + || !TEST_int_le(len, (int)sizeof(buf) - 1)) + goto err; + if (!TEST_true(buf[len] == 0)) + goto err; + if (len > 1 + && !BIO_eof(in_bio) + && len != ((int)sizeof(buf) - 1) + && !TEST_true(buf[len - 1] == '\n')) + goto err; + } + if (tstid == 1 && --partial == 0) + break; + } + } + if (!TEST_int_eq(BIO_seek(in_bio, 0), 1)) + goto err; + + len = 8; /* Do a small partial read to start with */ + while (!BIO_eof(in_bio)) { + if (!TEST_int_eq(BIO_read_ex(in_bio, buf, len, &bytes), 1)) + break; + if (!TEST_mem_eq(buf, bytes, expected + count, bytes)) + goto err; + count += bytes; + len = sizeof(buf); /* fill the buffer on subsequent reads */ + } + if (!TEST_int_eq(count, readbytes)) + goto err; + ret = 1; +err: + BIO_free(in); + BIO_free_all(in_bio); + BIO_free(readbuf_bio); + return ret; +} + +typedef enum OPTION_choice { + OPT_ERR = -1, + OPT_EOF = 0, + OPT_TEST_ENUM +} OPTION_CHOICE; + +const OPTIONS *test_get_options(void) +{ + static const OPTIONS test_options[] = { + OPT_TEST_OPTIONS_WITH_EXTRA_USAGE("file\n"), + { OPT_HELP_STR, 1, '-', "file\tFile to run tests on.\n" }, + { NULL } + }; + return test_options; +} + +int setup_tests(void) +{ + OPTION_CHOICE o; + + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_TEST_CASES: + break; + default: + return 0; + } + } + filename = test_get_argument(0); + + ADD_ALL_TESTS(test_readbuffer_file_bio, 3); + return 1; +} |