diff --git a/src/examples/fileserver_example_dirs.c b/src/examples/fileserver_example_dirs.c index 26086251..5ec60428 100644 --- a/src/examples/fileserver_example_dirs.c +++ b/src/examples/fileserver_example_dirs.c @@ -28,16 +28,27 @@ #include "platform.h" #include #include +#ifdef HAVE_UNISTD_H #include +#endif 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; } @@ -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, - "%s
", - e->d_name, - e->d_name); + res = snprintf (buf, max, + "%s
", + 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 index c2208170..192e00d1 100644 --- 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; + 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; } diff --git a/src/examples/https_fileserver_example.c b/src/examples/https_fileserver_example.c index ae304f72..30fbf4d8 100644 --- 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; }