Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

i.smap: fix possible pole error with log in extract function #4499

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

ymdatta
Copy link
Contributor

@ymdatta ymdatta commented Oct 11, 2024

Using logarithm function call with zero argument will lead to a pole error, which occurs if the mathematical function has an exact infinite result.

Refactor the conditional to only execute the code when number of subclasses are more than 1, which would preemptively stop us from getting into situation where log would have a zero argument. In cases where number of subclasses are <= 0, set the default value to 0. This is necessary as ll points to malloc'd memory and can contain renadom value.

References:

[1] https://en.cppreference.com/w/c/numeric/math/log
[2] SEI CERT C Coding Standard

@github-actions github-actions bot added C Related code is in C module imagery labels Oct 11, 2024
@nilason nilason added this to the 8.5.0 milestone Oct 12, 2024
imagery/i.smap/model.c Outdated Show resolved Hide resolved
@nilason
Copy link
Contributor

nilason commented Oct 16, 2024

I gather this issue originates from cppcheck, this is the relevant part for this:

cppcheck imagery/i.smap/model.c
...
imagery/i.smap/model.c:158:43: warning: Invalid log() argument nr 1. The value is 0 but the valid values are '4.94066e-324:'. [invalidFunctionArg]
                        ll[i][j][m] = log(subsum) + maxlike;
                                          ^
imagery/i.smap/model.c:154:34: note: Assignment 'subsum=0', assigned value is 0
                        subsum = 0;
                                 ^
imagery/i.smap/model.c:155:39: note: Assuming condition is false
                        for (k = 0; k < C->nsubclasses; k++)
                                      ^
imagery/i.smap/model.c:158:43: note: Invalid argument
                        ll[i][j][m] = log(subsum) + maxlike;

The static analysis, takes the path where C->nsubclasses are 0, which leaves subsum with the initialised value of 0.0. log(0) return "-infinity and raise the "divide-by-zero" floating-point exception"1, which is the real issue here.

Now, in this branch of the if-else statement:

else {
/* find the most likely subclass */
for (k = 0; k < C->nsubclasses; k++) {
if (k == 0)
maxlike = subll[k];
if (subll[k] > maxlike)
maxlike = subll[k];
}
/* Sum weighted subclass likelihoods */
subsum = 0;
for (k = 0; k < C->nsubclasses; k++)
subsum += exp(subll[k] - maxlike) * C->SubSig[k].pi;
ll[i][j][m] = log(subsum) + maxlike;
}
}

there are two loops over C->nsubclasses which only does anything if C->nsubclasses > 1.

Wouldn't it better to change the else to a else if (C->nsubclasses > 1) on line 144, which guarantees that the for-loops are entered and the initialised value of subsum is altered?

Footnotes

  1. man 3 log

@ymdatta ymdatta force-pushed the cppcheck_imagery_log1 branch from b1597d6 to 4d30fc3 Compare October 17, 2024 21:45
@ymdatta
Copy link
Contributor Author

ymdatta commented Oct 17, 2024

@nilason : I agree with your suggestion, it's a much cleaner way. Thanks!

I have modified the code to reflect that and I also added an else condition, which should cover the cases where nsubclasses <= 0 to set the value for ll to 0.0.

Using logarithm function call with zero argument will lead to
a pole error, which occurs if the mathematical function has
an exact infinite result.

Refactor the conditional to only execute the code when number
of subclasses are more than 1, which would preemptively stop
us from getting into situation where log would have a zero
argument. In cases where number of subclasses are <= 0, set
the default value to 0. This is necessary as `ll` points to
malloc'd memory and can contain renadom value.

Signed-off-by: Mohan Yelugoti <[email protected]>
@ymdatta ymdatta force-pushed the cppcheck_imagery_log1 branch from 4d30fc3 to cf4a759 Compare October 23, 2024 21:43
ymdatta added a commit to ymdatta/grass that referenced this pull request Nov 27, 2024
Documented each supression issue with comments to distinguish between
false positives and true positives awaiting resolution.

For the false positives supressions, appropriate information is
provided on why those were considered as false positive.

True positives will be removed from the suppression file once
their corresponding fixes(OSGeo#4702, OSGeo#4638, OSGeo#4500, OSGeo#4499) are merged.

Run:

`cppcheck --suppressions-list=.cppcheck-supressions <path>`

Signed-off-by: Mohan Yelugoti <[email protected]>
ymdatta added a commit to ymdatta/grass that referenced this pull request Nov 27, 2024
Documented each suppression issue with comments to distinguish between
false positives and true positives awaiting resolution.

For the false positives suppressions, appropriate information is
provided on why those were considered as false positive.

True positives will be removed from the suppression file once
their corresponding fixes(OSGeo#4702, OSGeo#4638, OSGeo#4500, OSGeo#4499) are merged.

Run:

`cppcheck --suppressions-list=.cppcheck-suppressions <path>`

Signed-off-by: Mohan Yelugoti <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C Related code is in C imagery module
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants