fix parse param bug and set default when overflow - #186
Conversation
|
It seems that the patch is incomplete: Besides that:
|
|
Ah, when submitting the new version, please add a proper description and place your name at the from/SOB, like: |
Date: Mon, 9 Dec 2024 19:41:54 +0800 Subject: [PATCH] fix parse param bug and set default when overflow 1. Check if the value is overflow before parsing the value with its unit, replacing sscanf with strtoul cause the strtoul has clear errno ERANGE for overflow case; 2. Delete the wrong logic unit_matched=0. When the param is set with a high level unit (e.g. PAGE_CE_THRESHOLD=1m), the real expected value is 1000000(1*1000*1000), but currently, it only matches the unit 'm' and multiply 1000 once, so the value we get is 1000 rather than 1000000; 3. Fix an overflow bug, as sscanf produces Undefined Behavior (https://man7.org/linux/man-pages/man3/sscanf.3.html#BUGS). The final value after being truncated is confusing. So set it to default value on overflow. Signed-off-by: Guo Dashun <guodashun1@huawei.com>
|
This would do the same: The only thing is that 86400 seconds would need to be stored there as |
|
To be clearer, I'm talking about what would be stored on things like these: That you're already adding the same default in seconds, via .var variable: The above could be stored, instead, as: (where .unit could either be seconds, minutes, hours or days - not sure what would work best ) |
|
on a separate but related issue, "var" is a terrible name (and "env"). The default value should be called "default". The one in use I would call "value". |
Under normal circumstances, you’re totally right. But here’s the edge case I’m thinking about: If I set a crazy huge value like 213503982334062d, here’s what happens in the code logic. First, it doesn’t hit the maximum int limit, so no truncation. Then when converting it to the default unit, boom—(213503982334062d to 18446744073662956800s )suddenly the converted value exceeds the max limit. But here’s the catch: If I only use either 'env' or 'unit' to store the working value, I completely lose track of the original value the user actually input. That means when I need to show error messages later, I can’t tell the user 'Hey your original 213503982334062d was invalid'—I’d only have the messed-up converted value. So here’s the thing—we can’t have both accurate value processing AND accurate error reporting if we only use one storage variable. That’s why I ended up keeping both 'env' (for the original user input) and 'val' (for the working value). This way we handle the math correctly while still being able to point to exactly what the user typed when things go wrong. |
The issue is because we're declaring things like: And then let user change what's there. I'm not a big fan of having a non-const default structure, as this makes it harder to identify changes. Anyway, the imutable data including the default value should be const. Also, the name seems to be const as well. IMO, the best solution is to split const from non-const data, e.g.: And ensure that Please notice that I removed overflow, as, on overflow, the logic should set to default. |
Thanks for the suggestion! Just to clarify one thing: if we detect a value overflow during unit conversion, we currently fall back to the default "24h". But since "24h" itself needs to be converted to seconds (→ 86400s), wouldn't it be simpler to initialize |
works for me. |
sscanfwithstrtoulcause thestrtoulhas clear errnoERANGEfor overflow case.unit_matched=0. When we set the param with a high level unit (e.g.PAGE_CE_THRESHOLD=1m), the real value we expect is 1000000(1*1000*1000), but now we only match the unit 'm' and multiply 1000 once, so the value we get is 1000 rather than 1000000. In this patch we fix the bug.sscanfwill produce Undefined Behavior (https://man7.org/linux/man-pages/man3/sscanf.3.html#BUGS). The final value after being truncated is confusing. So in this patch we will set to default value when the value is overflow.