Skip to content

HPCC-36035 Remove coverity-flagged overflows#21127

Open
asselitx wants to merge 1 commit intohpcc-systems:candidate-10.2.xfrom
asselitx:coverity-overflows-h36035
Open

HPCC-36035 Remove coverity-flagged overflows#21127
asselitx wants to merge 1 commit intohpcc-systems:candidate-10.2.xfrom
asselitx:coverity-overflows-h36035

Conversation

@asselitx
Copy link
Copy Markdown
Contributor

@asselitx asselitx commented Mar 20, 2026

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

Type of change:

  • This change is a bug fix (non-breaking change which fixes an issue).
  • This change is a new feature (non-breaking change which adds functionality).
  • This change improves the code (refactor or other change that does not change the functionality)
  • This change fixes warnings (the fix does not alter the functionality or the generated code)
  • This change is a breaking change (fix or feature that will cause existing behavior to change).
  • This change alters the query API (existing queries will have to be recompiled)

Checklist:

  • My code follows the code style of this project.
    • My code does not create any new warnings from compiler, build system, or lint.
  • The commit message is properly formatted and free of typos.
    • The commit message title makes sense in a changelog, by itself.
    • The commit is signed.
  • My change requires a change to the documentation.
    • I have updated the documentation accordingly, or...
    • I have created a JIRA ticket to update the documentation.
    • Any new interfaces or exported functions are appropriately commented.
  • I have read the CONTRIBUTORS document.
  • The change has been fully tested:
    • I have added tests to cover my changes.
    • All new and existing tests passed.
    • I have checked that this change does not introduce memory leaks.
    • I have used Valgrind or similar tools to check for potential issues.
  • I have given due consideration to all of the following potential concerns:
    • Scalability
    • Performance
    • Security
    • Thread-safety
    • Cloud-compatibility
    • Premature optimization
    • Existing deployed queries will not be broken
    • This change fixes the problem, not just the symptom
    • The target branch of this pull request is appropriate for such a change.
  • There are no similar instances of the same problem that should be addressed
    • I have addressed them here
    • I have raised JIRA issues to address them separately
  • This is a user interface / front-end modification
    • I have tested my changes in multiple modern browsers
    • The component(s) render as expected

Smoketest:

  • Send notifications about my Pull Request position in Smoketest queue.
  • Test my draft Pull Request.

Testing:

Copilot AI review requested due to automatic review settings March 20, 2026 20:33
@github-actions
Copy link
Copy Markdown

Jira Issue: https://hpccsystems.atlassian.net//browse/HPCC-36035

Jirabot Action Result:
Workflow Transition To: Merge Pending
Updated PR

@github-actions
Copy link
Copy Markdown

🔄 Upmerge Test Results

Status: ✅ All branches merged successfully
PR: #21127 - HPCC-36035 Remove coverity-flagged overflows
Base Branch: candidate-10.2.x
Test Time: 2026-03-20 20:36:29 UTC

✅ Successful Branches (1)

  • master
    This comment was automatically generated by the upmerge test workflow.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 bounded for loop to avoid unsigned wraparound in Cws_machineEx::setProcessRequest.
  • Replaced a do { ... } while (laIndex-- != 0); construct with an explicit break/decrement loop to avoid uint8_t wraparound in CFragmentedXmlPullParser::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 like 192.168.1.4-6 (it sets ipAddr to the first IP and returns a count), but addProcessRequestToMachineInfoData() is still passed address1 (the original range string). That means the resulting CMachineData::m_networkAddress can be an invalid hostname like 192.168.1.4-6, which later gets used for getMachineByAddress() / runCommand() via getNetworkAddress(). Consider deriving the current IP string from ipAddr each iteration (before ipincrement) 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);
    }

@asselitx asselitx requested a review from timothyklemm March 24, 2026 22:25
Copy link
Copy Markdown

@timothyklemm timothyklemm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@asselitx
Copy link
Copy Markdown
Contributor Author

@timothyklemm good suggestion, switched

@github-actions
Copy link
Copy Markdown

🔄 Upmerge Test Results

Status: ✅ All branches merged successfully
PR: #21127 - HPCC-36035 Remove coverity-flagged overflows
Base Branch: candidate-10.2.x
Test Time: 2026-03-25 20:39:16 UTC

✅ Successful Branches (1)

  • master
    This comment was automatically generated by the upmerge test workflow.

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>
@asselitx asselitx force-pushed the coverity-overflows-h36035 branch from f818113 to 423b1e1 Compare March 26, 2026 15:58
@asselitx
Copy link
Copy Markdown
Contributor Author

@GordonSmith or @ghalliday approved and squashed

@github-actions
Copy link
Copy Markdown

🔄 Upmerge Test Results

Status: ✅ All branches merged successfully
PR: #21127 - HPCC-36035 Remove coverity-flagged overflows
Base Branch: candidate-10.2.x
Test Time: 2026-03-26 15:59:32 UTC

✅ Successful Branches (1)

  • master
    This comment was automatically generated by the upmerge test workflow.

Copy link
Copy Markdown
Member

@ghalliday ghalliday left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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.

Copy link
Copy Markdown
Contributor Author

@asselitx asselitx Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants