diff options
| author | bitflash-maintainer <noreply@bitflash.invalid> | 2026-09-02 16:42:39 +0000 |
|---|---|---|
| committer | bitflash-maintainer <noreply@bitflash.invalid> | 2026-09-02 16:42:39 +0000 |
| commit | e3cc976ae3f211727e3fae702776aacca46efb0c (patch) | |
| tree | 61966e75b38ce20e1f7089fac8a7da453c58e998 /src | |
| parent | 456b3b4a3372e7d13b764f41006bf2c15d92f46e (diff) | |
log: reject a -maxdebugfilesize that is not a plain count of MB
atoi64() is strtoll() with the endptr discarded, so it yields 0 for
anything it cannot read. -maxdebugfilesize=1G and -maxdebugfilesize=1024MB
both parsed as 0, which the roll reads as "never roll" -- indistinguishable
from requesting that deliberately, and silent. An operator who wrote a unit
suffix got no rotation and no warning. Only a negative value said anything.
The multiplication was unchecked as well: a large enough N made
nMB * 1024 * 1024 overflow to a negative cap, which disables the roll too.
Parse with strtoll() and its endptr, and reject trailing characters,
ERANGE, negatives, and any value that would overflow the byte cap --
each reported with the reason and the cap being kept. 0 still means
never roll and is still accepted without comment.
Diffstat (limited to 'src')
| -rw-r--r-- | src/main_gui.cpp | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/src/main_gui.cpp b/src/main_gui.cpp index 163d78e..0e64985 100644 --- a/src/main_gui.cpp +++ b/src/main_gui.cpp | |||
| @@ -210,10 +210,33 @@ static void ParseStartupArguments(int argc, char* argv[]) | |||
| 210 | string strMaxDebugSize = argval2(argc, argv, "/maxdebugfilesize", "-maxdebugfilesize"); | 210 | string strMaxDebugSize = argval2(argc, argv, "/maxdebugfilesize", "-maxdebugfilesize"); |
| 211 | if (!strMaxDebugSize.empty()) | 211 | if (!strMaxDebugSize.empty()) |
| 212 | { | 212 | { |
| 213 | int64 nMB = atoi64(strMaxDebugSize.c_str()); | 213 | // Parsed with atoi64() before, which is strtoll() with the endptr |
| 214 | if (nMB < 0) | 214 | // thrown away: it returns 0 for anything it cannot read, so |
| 215 | fprintf(stderr, "Ignoring /maxdebugfilesize=%s: not a size in MB\n", | 215 | // /maxdebugfilesize=1G and =1024MB both came out as 0 -- "never |
| 216 | strMaxDebugSize.c_str()); | 216 | // roll", identical to asking for that on purpose, with nothing said |
| 217 | // to the operator. The old code also multiplied without a range | ||
| 218 | // check, so a big enough N wrapped to a negative cap, which the roll | ||
| 219 | // reads as "off" too. Every rejection is now reported and leaves the | ||
| 220 | // default in place; the value is a plain count of MB, no suffix. | ||
| 221 | const char* psz = strMaxDebugSize.c_str(); | ||
| 222 | char* pszEnd = NULL; | ||
| 223 | errno = 0; | ||
| 224 | int64 nMB = strtoll(psz, &pszEnd, 10); | ||
| 225 | // INT64_MAX, without depending on which limits header this tree pulls in. | ||
| 226 | const int64 nMaxMB = (int64)((~(uint64)0) >> 1) / (1024 * 1024); | ||
| 227 | const char* pszWhy = NULL; | ||
| 228 | if (pszEnd == psz) | ||
| 229 | pszWhy = "not a number"; | ||
| 230 | else if (*pszEnd != '\0') | ||
| 231 | pszWhy = "trailing characters -- the value is a count of MB, with no unit suffix"; | ||
| 232 | else if (errno == ERANGE || nMB < 0) | ||
| 233 | pszWhy = "not a size in MB"; | ||
| 234 | else if (nMB > nMaxMB) | ||
| 235 | pszWhy = "larger than a file size can be"; | ||
| 236 | if (pszWhy) | ||
| 237 | fprintf(stderr, "Ignoring /maxdebugfilesize=%s: %s (keeping %lld MB)\n", | ||
| 238 | strMaxDebugSize.c_str(), pszWhy, | ||
| 239 | (long long)(nMaxDebugFileSize / 1024 / 1024)); | ||
| 217 | else | 240 | else |
| 218 | nMaxDebugFileSize = nMB * 1024 * 1024; | 241 | nMaxDebugFileSize = nMB * 1024 * 1024; |
| 219 | } | 242 | } |