Replace off_t with size_t
While off_t might be better suited for file-offsets and -sizes, the IEEE Computer Society was unable to mandate limits (min, max) for it in the POSIX specification in the last 32 years. Because it's impossible to portably determine these numbers for signed integers, I decided to switch to size_t for the offsets to be able to pass proper values to strtonum(), because C99 is sane and has defined limits for size_t (i.e. SIZE_MIN and SIZE_MAX). On my system, long long and off_t have the same size, so it didn't trigger any bugs, but strtonum() could pass a bigger number to lower and upper than they can handle and make them overflow. The rationale for switching to size_t is actually given by the fact that functions like mmap() blur the border between memory and filesystem. Another point is that glibc has a horrible define _FILE_OFFSET_BITS you need to set to 64 to actually get decent values for off_t, which was a huge headache in sbase until we found that out. Signed-off-by: Laslo Hunhold <dev@frign.de>
This commit is contained in:
parent
d105c28aad
commit
cb7a1f6390
3 changed files with 10 additions and 9 deletions
10
http.c
10
http.c
|
@ -396,7 +396,7 @@ squash:
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum status
|
static enum status
|
||||||
parse_range(const char *str, off_t size, off_t *lower, off_t *upper)
|
parse_range(const char *str, size_t size, size_t *lower, size_t *upper)
|
||||||
{
|
{
|
||||||
char first[FIELD_MAX], last[FIELD_MAX];
|
char first[FIELD_MAX], last[FIELD_MAX];
|
||||||
const char *p, *q, *r, *err;
|
const char *p, *q, *r, *err;
|
||||||
|
@ -469,10 +469,10 @@ parse_range(const char *str, off_t size, off_t *lower, off_t *upper)
|
||||||
* last byte if 'last' is not given),
|
* last byte if 'last' is not given),
|
||||||
* inclusively, and byte-numbering beginning at 0
|
* inclusively, and byte-numbering beginning at 0
|
||||||
*/
|
*/
|
||||||
*lower = strtonum(first, 0, LLONG_MAX, &err);
|
*lower = strtonum(first, 0, SIZE_MAX, &err);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
if (last[0] != '\0') {
|
if (last[0] != '\0') {
|
||||||
*upper = strtonum(last, 0, LLONG_MAX, &err);
|
*upper = strtonum(last, 0, SIZE_MAX, &err);
|
||||||
} else {
|
} else {
|
||||||
*upper = size - 1;
|
*upper = size - 1;
|
||||||
}
|
}
|
||||||
|
@ -504,7 +504,7 @@ parse_range(const char *str, off_t size, off_t *lower, off_t *upper)
|
||||||
* use upper as a temporary storage for 'num',
|
* use upper as a temporary storage for 'num',
|
||||||
* as we know 'upper' is size - 1
|
* as we know 'upper' is size - 1
|
||||||
*/
|
*/
|
||||||
*upper = strtonum(last, 0, LLONG_MAX, &err);
|
*upper = strtonum(last, 0, SIZE_MAX, &err);
|
||||||
if (err) {
|
if (err) {
|
||||||
return S_BAD_REQUEST;
|
return S_BAD_REQUEST;
|
||||||
}
|
}
|
||||||
|
@ -536,7 +536,7 @@ http_send_response(int fd, const struct request *req)
|
||||||
struct stat st;
|
struct stat st;
|
||||||
struct tm tm = { 0 };
|
struct tm tm = { 0 };
|
||||||
size_t len, i;
|
size_t len, i;
|
||||||
off_t lower, upper;
|
size_t lower, upper;
|
||||||
int hasport, ipv6host;
|
int hasport, ipv6host;
|
||||||
static char realtarget[PATH_MAX], tmptarget[PATH_MAX];
|
static char realtarget[PATH_MAX], tmptarget[PATH_MAX];
|
||||||
char *p, *mime;
|
char *p, *mime;
|
||||||
|
|
7
resp.c
7
resp.c
|
@ -156,7 +156,8 @@ cleanup:
|
||||||
|
|
||||||
enum status
|
enum status
|
||||||
resp_file(int fd, const char *name, const struct request *req,
|
resp_file(int fd, const char *name, const struct request *req,
|
||||||
const struct stat *st, const char *mime, off_t lower, off_t upper)
|
const struct stat *st, const char *mime, size_t lower,
|
||||||
|
size_t upper)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
enum status sendstatus;
|
enum status sendstatus;
|
||||||
|
@ -166,7 +167,7 @@ resp_file(int fd, const char *name, const struct request *req,
|
||||||
.field[RES_ACCEPT_RANGES] = "bytes",
|
.field[RES_ACCEPT_RANGES] = "bytes",
|
||||||
};
|
};
|
||||||
ssize_t bread, bwritten;
|
ssize_t bread, bwritten;
|
||||||
off_t remaining;
|
size_t remaining;
|
||||||
static char buf[BUFSIZ], *p;
|
static char buf[BUFSIZ], *p;
|
||||||
|
|
||||||
/* open file */
|
/* open file */
|
||||||
|
@ -217,7 +218,7 @@ resp_file(int fd, const char *name, const struct request *req,
|
||||||
remaining = upper - lower + 1;
|
remaining = upper - lower + 1;
|
||||||
|
|
||||||
while ((bread = fread(buf, 1, MIN(sizeof(buf),
|
while ((bread = fread(buf, 1, MIN(sizeof(buf),
|
||||||
(size_t)remaining), fp))) {
|
remaining), fp))) {
|
||||||
if (bread < 0) {
|
if (bread < 0) {
|
||||||
res.status = S_INTERNAL_SERVER_ERROR;
|
res.status = S_INTERNAL_SERVER_ERROR;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
2
resp.h
2
resp.h
|
@ -9,6 +9,6 @@
|
||||||
|
|
||||||
enum status resp_dir(int, const char *, const struct request *);
|
enum status resp_dir(int, const char *, const struct request *);
|
||||||
enum status resp_file(int, const char *, const struct request *,
|
enum status resp_file(int, const char *, const struct request *,
|
||||||
const struct stat *, const char *, off_t, off_t);
|
const struct stat *, const char *, size_t, size_t);
|
||||||
|
|
||||||
#endif /* RESP_H */
|
#endif /* RESP_H */
|
||||||
|
|
Loading…
Reference in a new issue