HPCC-36035 Remove coverity-flagged overflows#21127
HPCC-36035 Remove coverity-flagged overflows#21127asselitx wants to merge 1 commit intohpcc-systems:candidate-10.2.xfrom
Conversation
|
Jira Issue: https://hpccsystems.atlassian.net//browse/HPCC-36035 Jirabot Action Result: |
🔄 Upmerge Test ResultsStatus: ✅ All branches merged successfully ✅ Successful Branches (1)
|
There was a problem hiding this comment.
Pull request overview
This PR addresses Coverity-reported integer underflow/overflow patterns in two ESP C++ components: the ws_machine service and the fragmented XML pull parser.
Changes:
- Replaced a post-decrement
while (numIps--)loop with a boundedforloop to avoid unsigned wraparound inCws_machineEx::setProcessRequest. - Replaced a
do { ... } while (laIndex-- != 0);construct with an explicit break/decrement loop to avoiduint8_twraparound inCFragmentedXmlPullParser::next.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| esp/services/ws_machine/ws_machineService.cpp | Adjusts IP-range iteration loop to avoid unsigned underflow. |
| esp/bindings/SOAP/xpp/fxpp/FragmentedXmlPullParser.cpp | Adjusts lookahead frame-ignoring loop to avoid uint8_t underflow. |
Comments suppressed due to low confidence (1)
esp/services/ws_machine/ws_machineService.cpp:521
- In this loop,
ipAddr.ipsetrange(address1)supports inputs like192.168.1.4-6(it setsipAddrto the first IP and returns a count), butaddProcessRequestToMachineInfoData()is still passedaddress1(the original range string). That means the resultingCMachineData::m_networkAddresscan be an invalid hostname like192.168.1.4-6, which later gets used forgetMachineByAddress()/runCommand()viagetNetworkAddress(). Consider deriving the current IP string fromipAddreach iteration (beforeipincrement) and passing that instead of the original range text so each machine entry targets a real host.
for (; numIps > 0; --numIps)
{
unsigned numAddr;
if (ipAddr.getNetAddress(sizeof(numAddr),&numAddr)!=sizeof(numAddr))
throw MakeStringException(ECLWATCH_INVALID_INPUT, "Invalid network address.");
ipAddr.ipincrement(1);
//Clean possible duplication
StringBuffer valuesToBeChecked;
valuesToBeChecked.append(numAddr);
if (machineInfoData.getOptions().getGetSoftwareInfo())
valuesToBeChecked.appendf(":%s:%s:%d", processTypeStr.str(), compName, processNumber);
bool* found = uniqueProcesses.getValue(valuesToBeChecked.str());
if (found && *found)
continue;
uniqueProcesses.setValue(valuesToBeChecked.str(), true);
addProcessRequestToMachineInfoData(machineInfoData, address1, address2, processTypeStr.str(), compName, path, processNumber);
}
timothyklemm
left a comment
There was a problem hiding this comment.
I don't get it. Once the loop terminating condition is met based on the value of a loop counter, the loop counter is invalid whether it is held at zero or decrements and wraps around. What future use would not require a reset?
If valid code is going to change to satisfy a tool, I would change both loops to something like for (<typename> i = 0; i < <limit>; i++)
The counter still ends with an invalid value, but ceases to exist so reuse with that invalid value is a non-issue.
|
@timothyklemm good suggestion, switched |
🔄 Upmerge Test ResultsStatus: ✅ All branches merged successfully ✅ Successful Branches (1)
|
Unlikely to cause a serious problem, but switched to use dedicated for loop indices to avoid overflow/underflow or misuse after loop ends. - CFragmentedXmlPullParser::next - Cws_machineEx::setProcessRequest Signed-off-by: Terrence Asselin <terrence.asselin+copilot@lexisnexisrisk.com>
f818113 to
423b1e1
Compare
|
@GordonSmith or @ghalliday approved and squashed |
🔄 Upmerge Test ResultsStatus: ✅ All branches merged successfully ✅ Successful Branches (1)
|
ghalliday
left a comment
There was a problem hiding this comment.
If used infrequently/unused then happy to merge as is. If used often and number of frames is high then it could do with more thought.
| else | ||
| { | ||
| do | ||
| for (uint8_t i=0; i<=laIndex; ++i) |
There was a problem hiding this comment.
@asselitx where is this code used? How many data frames are typical.
This code is O(N^2) in the number of frames. Each call to peekDataFrame walks a std::list until it finds the match.
There was a problem hiding this comment.
@ghalliday The number of cumulative frames iterated in the outer laIndex (lookahead Index) loop is small - about 10. Each call to peekDataFrame bounds the number it iterates by the index passed in. That index is trying to match an end tag for a node that will be replaced by imported content. Since the lookahead is going over at most a start + content + whitespace + end XML nodes it won't be more than [0..3]. So although the number of frames overall in the pendingData() list could be larger it is only looking over the last laIndex of them.
Unlikely to cause a serious problem, but switched to use dedicated for loop
indices to avoid overflow/underflow or misuse after loop ends.
Type of change:
Checklist:
Smoketest:
Testing: