From 3d405a939c7130c58ace700947389305ec152944 Mon Sep 17 00:00:00 2001
From: Rob Swindell <rob@synchro.net>
Date: Sun, 30 Jan 2022 14:35:42 -0800
Subject: [PATCH] Fix HTTP-requests for files >= 2GB in size

An int is 32-bits on all supported platforms, so this has always been broken. The actual file size/request-length sent would depend on fun 2's complement math (a 32GB file was being truncated to 433MB).

Also fixed some wrong uses of PRIuOFF: off_t is a signed integer, so technically the maximum file size you can request now is 2^63 bytes, which is "big enough".
---
 src/sbbs3/websrvr.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/sbbs3/websrvr.c b/src/sbbs3/websrvr.c
index e3ae6e52ca..7149db35ad 100644
--- a/src/sbbs3/websrvr.c
+++ b/src/sbbs3/websrvr.c
@@ -1383,11 +1383,11 @@ static BOOL send_headers(http_session_t *session, const char *status, int chunke
 				}
 				else  {
 					if((session->req.range_start || session->req.range_end) && stat_code == 206) {
-						safe_snprintf(header,sizeof(header),"%s: %ld",get_header(HEAD_LENGTH),session->req.range_end-session->req.range_start+1);
+						safe_snprintf(header,sizeof(header),"%s: %"PRIdOFF, get_header(HEAD_LENGTH), session->req.range_end-session->req.range_start+1);
 						safecat(headers,header,MAX_HEADERS_SIZE);
 					}
 					else {
-						safe_snprintf(header,sizeof(header),"%s: %d",get_header(HEAD_LENGTH),(int)stats.st_size);
+						safe_snprintf(header,sizeof(header),"%s: %"PRIdOFF, get_header(HEAD_LENGTH), stats.st_size);
 						safecat(headers,header,MAX_HEADERS_SIZE);
 					}
 				}
@@ -1407,7 +1407,7 @@ static BOOL send_headers(http_session_t *session, const char *status, int chunke
 			if(session->req.range_start || session->req.range_end) {
 				switch(stat_code) {
 					case 206:	/* Partial reply */
-						safe_snprintf(header,sizeof(header),"%s: bytes %ld-%ld/%ld",get_header(HEAD_CONTENT_RANGE),session->req.range_start,session->req.range_end,(long)stats.st_size);
+						safe_snprintf(header,sizeof(header),"%s: bytes %"PRIdOFF"-%"PRIdOFF"/%"PRIdOFF,get_header(HEAD_CONTENT_RANGE),session->req.range_start,session->req.range_end,stats.st_size);
 						safecat(headers,header,MAX_HEADERS_SIZE);
 						break;
 					default:
@@ -6078,7 +6078,7 @@ static void respond(http_session_t * session)
 	if(session->req.send_content)  {
 		off_t snt=0;
 		time_t start = time(NULL);
-		lprintf(LOG_INFO,"%04d Sending file: %s (%"PRIuOFF" bytes)"
+		lprintf(LOG_INFO,"%04d Sending file: %s (%"PRIdOFF" bytes)"
 			,session->socket, session->req.physical_path, flength(session->req.physical_path));
 		snt=sock_sendfile(session,session->req.physical_path,session->req.range_start,session->req.range_end);
 		if(session->req.ld!=NULL) {
@@ -6090,7 +6090,7 @@ static void respond(http_session_t * session)
 			time_t e = time(NULL) - start;
 			if(e < 1)
 				e = 1;
-			lprintf(LOG_INFO, "%04d Sent file: %s (%"PRIuOFF" bytes, %ld cps)"
+			lprintf(LOG_INFO, "%04d Sent file: %s (%"PRIdOFF" bytes, %ld cps)"
 				,session->socket, session->req.physical_path, snt, (long)(snt / e));
 			if(session->filebase_access)
 				user_downloaded_file(&scfg, &session->user, &session->client, session->file.dir, session->file.name, snt);
@@ -6865,7 +6865,7 @@ void http_logging_thread(void* arg)
 		}
 		if(logfile!=NULL) {
 			if(ld->status) {
-				sprintf(sizestr,"%"PRIuOFF,ld->size);
+				sprintf(sizestr,"%"PRIdOFF,ld->size);
 				strftime(timestr,sizeof(timestr),"%d/%b/%Y:%H:%M:%S %z",&ld->completed);
 				/*
 				 * In case of a termination, do no block for a lock... just discard
-- 
GitLab