diff --git a/src/reader.c b/src/reader.c --- a/src/reader.c +++ b/src/reader.c @@ -407,6 +407,41 @@ } r->nread += *nread; } + else if (r->type == READER_TYPE_FD) + { + ssize_t n; + + if (r->eof) + return gpg_error (GPG_ERR_EOF); + + if (!length) + { + *nread = 0; + return 0; + } + + n = read (r->u.fd, buffer, length); + if (n > 0) + { + r->nread += n; + *nread = n; + } + else + { + *nread = 0; + + if (n < 0) + { + r->error = errno; + return gpg_error_from_errno (errno); + } + else + { + r->eof = 1; + return gpg_error (GPG_ERR_EOF); + } + } + } else return gpg_error (GPG_ERR_BUG); diff --git a/tests/Makefile.am b/tests/Makefile.am --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -39,7 +39,7 @@ BUILT_SOURCES = oidtranstbl.h CLEANFILES = oidtranstbl.h -TESTS = cert-basic t-crl-parser t-dnparser t-oid +TESTS = cert-basic t-crl-parser t-dnparser t-oid t-reader AM_CFLAGS = $(GPG_ERROR_CFLAGS) AM_LDFLAGS = -no-install diff --git a/tests/t-reader.c b/tests/t-reader.c new file mode 100644 --- /dev/null +++ b/tests/t-reader.c @@ -0,0 +1,207 @@ +/* t-reader.c - basic tests for the reader object + * Copyright (C) 2017 g10 Code GmbH + * + * This file is part of KSBA. + * + * KSBA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * KSBA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "../src/ksba.h" +#include "t-common.h" + +void +test_fd(const char* path) +{ + int fd = open (path, O_RDONLY); + gpg_error_t err = 0; + ksba_reader_t reader; + ksba_cert_t cert; + + if (fd < 0) + { + perror ("open() failed"); + exit (1); + } + + if ((err = ksba_reader_new (&reader))) + { + fprintf (stderr, "ksba_reader_new() failed: %s\n", gpg_strerror (err)); + exit (1); + } + + if ((err = ksba_reader_set_fd (reader, fd))) + { + fprintf (stderr, "ksba_reader_set_fd() failed: %s\n", gpg_strerror (err)); + exit (1); + } + + if ((err = ksba_cert_new (&cert))) + { + fprintf (stderr, "ksba_cert_new() failed: %s\n", gpg_strerror (err)); + exit (1); + } + + if ((err = ksba_cert_read_der (cert, reader))) + { + fprintf(stderr, "ksba_cert_read_der() failed: %s\n", gpg_strerror (err)); + exit (1); + } + + ksba_cert_release (cert); + ksba_reader_release (reader); + close (fd); +} + +void +test_file(const char* path) +{ + FILE* fp = fopen (path, "r"); + gpg_error_t err = 0; + ksba_reader_t reader; + ksba_cert_t cert; + + if (!fp) + { + perror ("fopen() failed"); + exit (1); + } + + if ((err = ksba_reader_new (&reader))) + { + fprintf (stderr, "ksba_reader_new() failed: %s\n", gpg_strerror (err)); + exit (1); + } + + if ((err = ksba_reader_set_file (reader, fp))) + { + fprintf (stderr, "ksba_reader_set_fd() failed: %s\n", gpg_strerror (err)); + exit (1); + } + + if ((err = ksba_cert_new (&cert))) + { + fprintf (stderr, "ksba_cert_new() failed: %s\n", gpg_strerror (err)); + exit (1); + } + + if ((err = ksba_cert_read_der (cert, reader))) + { + fprintf(stderr, "ksba_cert_read_der() failed: %s\n", gpg_strerror (err)); + exit (1); + } + + ksba_cert_release (cert); + ksba_reader_release (reader); + fclose (fp); +} + +void +test_mem(const char* path) +{ + int fd = open (path, O_RDONLY); + gpg_error_t err = 0; + ksba_reader_t reader; + ksba_cert_t cert; + char *mem = NULL; + ssize_t ret = 0; + size_t p = 0; + struct stat st; + + if (fd < 0) + { + perror ("fopen() failed"); + exit (1); + } + + if (fstat (fd, &st)) + { + fprintf (stderr, "fstat() failed: %s\n", gpg_strerror (err)); + exit (1); + } + + mem = xmalloc(st.st_size); + + while (p < st.st_size && (ret = read(fd, mem + p, st.st_size - p))) + { + if (ret < 0) + { + fprintf (stderr, "read() failed: %s\n", gpg_strerror (err)); + exit (1); + } + p += ret; + } + + if ((err = ksba_reader_new (&reader))) + { + exit (1); + } + + if ((err = ksba_reader_set_mem (reader, mem, st.st_size))) + { + fprintf (stderr, "ksba_reader_set_mem() failed: %s\n", gpg_strerror (err)); + exit (1); + } + + if ((err = ksba_cert_new (&cert))) + { + fprintf (stderr, "ksba_cert_new() failed: %s\n", gpg_strerror (err)); + exit (1); + } + + if ((err = ksba_cert_read_der (cert, reader))) + { + fprintf(stderr, "ksba_cert_read_der() failed: %s\n", gpg_strerror (err)); + exit (1); + } + + ksba_cert_release (cert); + ksba_reader_release (reader); + xfree (mem); + close (fd); +} + +int +main (int argc, char **argv) +{ + if (argc == 1) + { + test_fd (prepend_srcdir ("cert_g10code_test1.der")); + test_file (prepend_srcdir ("cert_g10code_test1.der")); + test_mem (prepend_srcdir ("cert_g10code_test1.der")); + } + else + { + for (int i = 1; i < argc; ++i) + { + test_fd (argv[i]); + test_file (argv[i]); + test_mem (argv[i]); + } + } + + return 0; +}