Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.

Commit 88daad5

Browse files
committed
Overflow check added
1 parent 2e77b65 commit 88daad5

File tree

1 file changed

+31
-4
lines changed

1 file changed

+31
-4
lines changed

src/core/internal/parseoptions.d

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,10 @@ do
176176
auto tail = find!(c => c == ' ')(str);
177177
size_t len = str.length - tail.length;
178178

179+
import core.checkedint : mulu;
180+
181+
bool overflowed;
182+
179183
for (; i < len; i++)
180184
{
181185
char c = str[i];
@@ -188,16 +192,17 @@ do
188192
{
189193
switch (c)
190194
{
195+
191196
case 'G':
192-
v <<= 30;
197+
v = mulu(v, 1024 * 1024 * 1024, overflowed);
193198
break;
194199

195200
case 'M':
196-
v <<= 20;
201+
v = mulu(v, 1024 * 1024, overflowed);
197202
break;
198203

199204
case 'K':
200-
v <<= 10;
205+
v = mulu(v, 1024, overflowed);
201206
break;
202207

203208
case 'B':
@@ -207,6 +212,9 @@ do
207212
return parseError("value with unit type M, K or B", optname, str, "with suffix");
208213
}
209214

215+
if (overflowed)
216+
return overflowedError(optname, str);
217+
210218
i++;
211219
break;
212220
}
@@ -222,7 +230,14 @@ do
222230
return parseError("a number", optname, str, errName);
223231

224232
if (mayHaveSuffix && isdigit(str[len-1]))
225-
v <<= 20; // No suffix found, default to megabytes
233+
{
234+
// No suffix found, default to megabytes
235+
236+
v = mulu(v, 1024 * 1024, overflowed);
237+
238+
if (overflowed)
239+
return overflowedError(optname, str);
240+
}
226241

227242
if (v > res.max)
228243
return parseError("a number " ~ T.max.stringof ~ " or below", optname, str[0 .. i], errName);
@@ -310,6 +325,16 @@ bool parseError(const scope char[] exp, const scope char[] opt, const scope char
310325
return false;
311326
}
312327

328+
bool overflowedError(const scope char[] opt, const scope char[] got)
329+
{
330+
version (CoreUnittest) if (inUnittest) return false;
331+
332+
fprintf(stderr, "Argument for %.*s option '%.*s' is too big.\n",
333+
cast(int)opt.length, opt.ptr,
334+
cast(int)got.length, got.ptr);
335+
return false;
336+
}
337+
313338
size_t min(size_t a, size_t b) { return a <= b ? a : b; }
314339

315340
version (CoreUnittest) __gshared bool inUnittest;
@@ -369,6 +394,8 @@ unittest
369394
assert(conf.disable);
370395
assert(conf.minPoolSize == 1024UL * 1024 * 1024 * 3);
371396

397+
assert(!conf.parseOptions("minPoolSize:922337203685477G"), "size_t overflow");
398+
372399
assert(conf.parseOptions("heapSizeFactor:3.1"));
373400
assert(conf.heapSizeFactor == 3.1f);
374401
assert(conf.parseOptions("heapSizeFactor:3.1234567890 disable:0"));

0 commit comments

Comments
 (0)