libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit aefa12e99a7ff7fa5a3166ea24883a7c8788f639
parent 73340d1dafcda6c084502baa627003f937653ef8
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
Date:   Wed,  1 Jun 2022 16:16:22 +0300

src/examples/*fileserver*.c: added error checking

Diffstat:
Msrc/examples/fileserver_example_dirs.c | 33+++++++++++++++++++++++++--------
Msrc/examples/fileserver_example_external_select.c | 17+++++++++++++----
Msrc/examples/https_fileserver_example.c | 15++++++++++++---
3 files changed, 50 insertions(+), 15 deletions(-)

diff --git a/src/examples/fileserver_example_dirs.c b/src/examples/fileserver_example_dirs.c @@ -28,16 +28,27 @@ #include "platform.h" #include <dirent.h> #include <microhttpd.h> +#ifdef HAVE_UNISTD_H #include <unistd.h> +#endif static ssize_t file_reader (void *cls, uint64_t pos, char *buf, size_t max) { - FILE *file = cls; - - (void) fseek (file, pos, SEEK_SET); - return fread (buf, 1, max, file); + FILE *file = (FILE *) cls; + size_t bytes_read; + + /* 'fseek' may not support files larger 2GiB, depending on platform. + * For production code, make sure that 'pos' has valid values, supported by + * 'fseek', or use 'fseeko' or similar function. */ + if (0 != fseek (file, (long) pos, SEEK_SET)) + return MHD_CONTENT_READER_END_WITH_ERROR; + bytes_read = fread (buf, 1, max, file); + if (0 == bytes_read) + return (0 != ferror (file)) ? MHD_CONTENT_READER_END_WITH_ERROR : + MHD_CONTENT_READER_END_OF_STREAM; + return (ssize_t) bytes_read; } @@ -63,6 +74,7 @@ dir_reader (void *cls, uint64_t pos, char *buf, size_t max) { DIR *dir = cls; struct dirent *e; + int res; if (max < 512) return 0; @@ -73,10 +85,15 @@ dir_reader (void *cls, uint64_t pos, char *buf, size_t max) if (e == NULL) return MHD_CONTENT_READER_END_OF_STREAM; } while (e->d_name[0] == '.'); - return snprintf (buf, max, - "<a href=\"/%s\">%s</a><br>", - e->d_name, - e->d_name); + res = snprintf (buf, max, + "<a href=\"/%s\">%s</a><br>", + e->d_name, + e->d_name); + if (0 >= res) + return MHD_CONTENT_READER_END_WITH_ERROR; + if (max < (size_t) res) + return MHD_CONTENT_READER_END_WITH_ERROR; + return (ssize_t) res; } diff --git a/src/examples/fileserver_example_external_select.c b/src/examples/fileserver_example_external_select.c @@ -35,10 +35,19 @@ static ssize_t file_reader (void *cls, uint64_t pos, char *buf, size_t max) { - FILE *file = cls; - - (void) fseek (file, pos, SEEK_SET); - return fread (buf, 1, max, file); + FILE *file = (FILE *) cls; + size_t bytes_read; + + /* 'fseek' may not support files larger 2GiB, depending on platform. + * For production code, make sure that 'pos' has valid values, supported by + * 'fseek', or use 'fseeko' or similar function. */ + if (0 != fseek (file, (long) pos, SEEK_SET)) + return MHD_CONTENT_READER_END_WITH_ERROR; + bytes_read = fread (buf, 1, max, file); + if (0 == bytes_read) + return (0 != ferror (file)) ? MHD_CONTENT_READER_END_WITH_ERROR : + MHD_CONTENT_READER_END_OF_STREAM; + return (ssize_t) bytes_read; } diff --git a/src/examples/https_fileserver_example.c b/src/examples/https_fileserver_example.c @@ -112,10 +112,19 @@ OT1qAbIblaRuWqCsid8BzP7ZQiAnAWgMRSUg1gzDwSwRhrYQRRWAyn/Qipzec+27\n\ static ssize_t file_reader (void *cls, uint64_t pos, char *buf, size_t max) { - FILE *file = cls; + FILE *file = (FILE *) cls; + size_t bytes_read; - (void) fseek (file, pos, SEEK_SET); - return fread (buf, 1, max, file); + /* 'fseek' may not support files larger 2GiB, depending on platform. + * For production code, make sure that 'pos' has valid values, supported by + * 'fseek', or use 'fseeko' or similar function. */ + if (0 != fseek (file, (long) pos, SEEK_SET)) + return MHD_CONTENT_READER_END_WITH_ERROR; + bytes_read = fread (buf, 1, max, file); + if (0 == bytes_read) + return (0 != ferror (file)) ? MHD_CONTENT_READER_END_WITH_ERROR : + MHD_CONTENT_READER_END_OF_STREAM; + return (ssize_t) bytes_read; }