]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
tool_cb_prg: avoid integer overflows
authorDaniel Stenberg <daniel@haxx.se>
Tue, 14 Jul 2026 20:49:38 +0000 (22:49 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Thu, 16 Jul 2026 06:52:16 +0000 (08:52 +0200)
Verify in test 2093

Fixes #22316
Reported-by: xmoezzz on github
Closes #22328

src/tool_cb_prg.c
tests/data/Makefile.am
tests/data/test2093 [new file with mode: 0644]

index 7d7f3a8d519ec628b8c762ff2958d73fd858b9cc..b570923c4129ea7dc9ca53a61a126ae3f16e4964 100644 (file)
@@ -128,6 +128,14 @@ int tool_progress_cb(void *clientp,
   struct ProgressData *bar = &per->progressbar;
   curl_off_t total;
   curl_off_t point;
+  curl_off_t totalall;
+  curl_off_t nowall;
+
+  totalall = ((CURL_OFF_T_MAX - dltotal) < ultotal) ?
+    CURL_OFF_T_MAX : dltotal + ultotal;
+
+  nowall = ((CURL_OFF_T_MAX - dlnow) < ulnow) ?
+    CURL_OFF_T_MAX : dlnow + ulnow;
 
   if(!bar->calls)
     update_width(bar);
@@ -136,27 +144,27 @@ int tool_progress_cb(void *clientp,
      indicating that we are expecting to get the filesize from the remote */
   if(bar->initial_size < 0) {
     if(dltotal || ultotal)
-      total = dltotal + ultotal;
+      total = totalall;
     else
       total = CURL_OFF_T_MAX;
   }
-  else if((CURL_OFF_T_MAX - bar->initial_size) < (dltotal + ultotal))
+  else if((CURL_OFF_T_MAX - bar->initial_size) < totalall)
     total = CURL_OFF_T_MAX;
   else
-    total = dltotal + ultotal + bar->initial_size;
+    total = totalall + bar->initial_size;
 
   /* Calculate the current progress. initial_size can be less than zero when
      indicating that we are expecting to get the filesize from the remote */
   if(bar->initial_size < 0) {
     if(dltotal || ultotal)
-      point = dlnow + ulnow;
+      point = nowall;
     else
       point = CURL_OFF_T_MAX;
   }
-  else if((CURL_OFF_T_MAX - bar->initial_size) < (dlnow + ulnow))
+  else if((CURL_OFF_T_MAX - bar->initial_size) < nowall)
     point = CURL_OFF_T_MAX;
   else
-    point = dlnow + ulnow + bar->initial_size;
+    point = nowall + bar->initial_size;
 
   if(bar->calls) {
     /* after first call... */
index 83704d1020725a77ba1299cd71edd99eb248d3cb..40e7c7da5cd7ab942ec7a88aacea32fa00b197e5 100644 (file)
@@ -252,7 +252,7 @@ test2056 test2057 test2058 test2059 test2060 test2061 test2062 test2063 \
 test2064 test2065 test2066 test2067 test2068 test2069 test2070 test2071 \
 test2072 test2073 test2074 test2075 test2076 test2077 test2078 test2079 \
 test2080 test2081 test2082 test2083 test2084 test2085 test2086 test2087 \
-test2088 test2089 test2090 test2091 test2092 \
+test2088 test2089 test2090 test2091 test2092 test2093 \
 test2100 test2101 test2102 test2103 test2104 test2105 test2106 test2107 \
 test2108 test2109 test2110 test2113 test2114 test2115 test2116 \
 \
diff --git a/tests/data/test2093 b/tests/data/test2093
new file mode 100644 (file)
index 0000000..6c15614
--- /dev/null
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="US-ASCII"?>
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+# Server-side
+<reply>
+<data crlf="headers">
+HTTP/1.1 200 OK swsclose
+Content-Length: 9223372036854775807
+Content-Type: text/html
+
+-foo-
+</data>
+</reply>
+
+# Client-side
+<client>
+<server>
+http
+</server>
+<name>
+HTTP POST a few bytes with 2^63-1 bytes response
+</name>
+<command>
+http://%HOSTIP:%HTTPPORT/%TESTNUMBER -# -d "sending data"
+</command>
+</client>
+
+# Verify data after the test has been "shot"
+<verify>
+<protocol crlf="headers" nonewline="yes">
+POST /%TESTNUMBER HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
+Accept: */*
+Content-Length: 12
+Content-Type: application/x-www-form-urlencoded
+
+sending data
+</protocol>
+<errorcode>
+18
+</errorcode>
+</verify>
+</testcase>