123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- /*
- * 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;
- }
|