[BUG] readModelParams: Segfault on missing parameter value and unvalidated strtod silently accepts non-numeric strings
Maintainers usually reply within 2 days
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 68/100
Research direction
Start with src/common/modelParams.c, especially readModelParams() around the tokenization and strtod() calls; compare the missing-value handling in src/sipnet/frontend.c:83-88. Then inspect tests/sipnet/test_sipnet_infrastructure/testNonfiniteParams.c for the existing test pattern. Done means missing values and malformed numeric strings produce the specified errors, with tests covering both cases.
Written by the indexing model from the issue text.
Description
Summary
In src/common/modelParams.c:readModelParams(), the .param file reader contains two input validation flaws:
- Segmentation Fault (SIGSEGV): When a parameter record has a parameter name without a corresponding value,
strtok()returnsNULL, and passing it intostrcpy()causes an immediate segmentation fault (signal 11 / exit code 139). - Silent Acceptance of Invalid Strings: When a parameter value contains non-numeric characters (e.g.,
plantWoodCInit not_a_numberorsoilRespQ10 2.2abc),value = strtod(strValue, &errc)parses the string, buterrcis never validated. As a result,strtod()returns0.0(or2.2), and SIPNET silently accepts the corrupted parameter value and runs with exit code 0.
Detailed Problem & Root Cause
1. Crash on Missing Parameter Value
In src/common/modelParams.c:170-172:
// tokenize line:
strcpy(pName, strtok(line, SEPARATORS)); // copy first token into pName
strcpy(strValue, strtok(NULL, SEPARATORS));
When a line in the .param file contains only a parameter name without a following value (for example, plantWoodCInit alone on a line, or trailing whitespace without a value token):
strtok(line, SEPARATORS)returns the parameter name.strtok(NULL, SEPARATORS)returnsNULL.strcpy(strValue, NULL)invokes undefined behavior and immediately causes a Segmentation fault (core dumped).
In contrast, src/sipnet/frontend.c:83-88 explicitly checks:
if (inputValue == NULL) {
logError("Error in input file: No value given for input item %s\n", inputName);
logError("Please fix %s and re-run\n", ctx.inputFile);
exit(EXIT_CODE_BAD_PARAMETER_VALUE);
}
2. Silent Acceptance of Non-Numeric Parameter Values
In src/common/modelParams.c:149, 180:
char *errc;
...
value = strtod(strValue, &errc);
While errc is passed to strtod(), it is never checked afterwards.
According to the C standard (strtod(3)), if no conversion can be performed, strtod returns 0.0 and sets *errc = strValue. If conversion stops partway through (e.g., 12.5xyz), *errc != '\0'.
Because errc is completely ignored, invalid strings are silently converted to 0.0 (or truncated values), and the model proceeds without any warning or error, silently compromising scientific simulation results.
Steps to Reproduce
Reproduction 1: Segmentation Fault
- Add an empty parameter line to
sipnet.param:echo "plantWoodCInit" >> tests/smoke/niwot/sipnet.param - Run SIPNET:
./sipnet -i tests/smoke/niwot/sipnet.in - Process crashes with
SIGSEGV(exit code 139):Program received signal SIGSEGV, Segmentation fault. __strcpy_avx2 () at ../sysdeps/x86_64/multiarch/strcpy-avx2.S:80 #0 __strcpy_avx2 () #1 0x0000555555575bcb in readModelParams (modelParams=0x555555586d60, paramFile=0x555555586b80) at src/common/modelParams.c:171 #2 0x0000555555557970 in readParamData (modelParamsPtr=0x7fffffffd2c8, paramFile=0x7fffffffd510 "sipnet.param") at src/sipnet/sipnet.c:403 #3 0x000055555555aff4 in initModel (modelParams=0x7fffffffd2c8, paramFile=0x7fffffffd510 "sipnet.param", climFile=0x7fffffffd610 "sipnet.clim") at src/sipnet/sipnet.c:1993 #4 0x00005555555655ca in main (argc=1, argv=0x7fffffffda58) at src/sipnet/frontend.c:212
Reproduction 2: Silent Conversion of Non-Numeric String
- Edit any parameter in
sipnet.paramto a non-numeric string:sed -i 's/^plantWoodCInit .*/plantWoodCInit not_a_number/' sipnet.param - Run SIPNET:
./sipnet - Outcome: SIPNET completes with
Exit code: 0, silently treatingplantWoodCInitas0.0.
Proposed Solution
-
Guard
strtokreturn value:
Check if the value token isNULLbefore copying:char *pNameToken = strtok(line, SEPARATORS); char *valToken = strtok(NULL, SEPARATORS); if (pNameToken == NULL) { continue; // empty line / comment } if (valToken == NULL) { logError("Error in parameter file: No value given for parameter %s\n", pNameToken); exit(EXIT_CODE_INPUT_FILE_ERROR); } strncpy(pName, pNameToken, sizeof(pName) - 1); pName[sizeof(pName) - 1] = '\0'; strncpy(strValue, valToken, sizeof(strValue) - 1); strValue[sizeof(strValue) - 1] = '\0'; -
Validate
errcfromstrtod:
Verify that the entire value string was consumed as a valid number:value = strtod(strValue, &errc); if (errc == strValue || *errc != '\0') { logError("parameter %s has invalid numeric value: '%s'\n", pName, strValue); exit(EXIT_CODE_BAD_PARAMETER_VALUE); } -
Add Unit Tests:
Extendtests/sipnet/test_sipnet_infrastructure/testNonfiniteParams.c(or add cases to a new unit test suite) verifying that:- Parameters with missing values exit with
EXIT_CODE_INPUT_FILE_ERROR. - Parameters with non-numeric strings (
"not_a_number","12.3foo", etc.) exit withEXIT_CODE_BAD_PARAMETER_VALUE.
- Parameters with missing values exit with
- Dominant language
- C
- Stars
- 42
- Forks
- 38
- Avg merge
- 3d 21h
- Merged PRs (30d)
- 10
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from PecanProject/sipnet
-
Make sure that documentation of sipnet.out header reflects implementationPossibly taken @TianHengZhuang claimed this 19 days ago. Opendocumentation good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
PecanProject/sipnet#345 · 8 comments · 1 reaction ·
Maintainers usually reply within 2 days
-
Remove unused `Tracker` fieldsMay be free again @ANAMASGARD claimed this 8 days ago, and no pull request is open. Opengood first issue on hold
Difficulty 4/5 3-5 days Newbie friendliness 45/100
PecanProject/sipnet#430 · 1 comment · 1 reaction ·
Maintainers usually reply within 2 days
-
Event checks ignore every events.in record after the firstPossibly taken @ANAMASGARD claimed this 9 days ago. Open
Difficulty 3/5 1-2 days Newbie friendliness 70/100
PecanProject/sipnet#429 · 3 comments · 1 assignee ·
Maintainers usually reply within 2 days
-
Events: revamp handling of "big delta" events to post-pool-updatePossibly taken @Alomir claimed this 11 days ago. Open
PecanProject/sipnet#423 · 1 assignee ·
Maintainers usually reply within 2 days
-
Missed event across a year boundary silently blocks later eventsPossibly taken @ANAMASGARD claimed this 11 days ago. Open
Difficulty 3/5 1-2 days Newbie friendliness 73/100
PecanProject/sipnet#421 · 4 comments · 1 assignee ·
Maintainers usually reply within 2 days
All issues in PecanProject/sipnet
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
kmod-project/kmod#492 ·
Maintainers usually reply within 4 days
-
SDL_GPU Vulkan: wrong screen orientation on OpenHarmony (preTransform set without pre-rotation)Open
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
libsdl-org/SDL#16670 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
要トリアージ 辞書
Difficulty 1/5 1-3 hours Newbie friendliness 86/100
yksr-melt/Meltype#1625 · 1 reaction ·
Maintainers usually reply within 1 day
-
kind/bug priority/medium qa_automation
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
yugabyte/yugabyte-db#37324 ·
Maintainers usually reply within 1 day