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:
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;
}