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

Fix upAp7 signed integer overflow #735

Merged

Conversation

isaacbrodsky
Copy link
Collaborator

@isaacbrodsky isaacbrodsky commented Dec 6, 2022

Adds versions of _upAp7/_upAp7r that check for signed integer overflow on integer operations, for use in the LocalIJ functions. Replaces #733.

@coveralls
Copy link

coveralls commented Dec 6, 2022

Coverage Status

Coverage increased (+0.02%) to 98.657% when pulling 5e1e2cd on isaacbrodsky:fix-upap7-signed-integer-overflow into 975de7a on uber:master.

src/h3lib/lib/coordijk.c Show resolved Hide resolved
src/h3lib/include/mathExtensions.h Outdated Show resolved Hide resolved
@isaacbrodsky isaacbrodsky force-pushed the fix-upap7-signed-integer-overflow branch from 975a7ff to d5e49e5 Compare December 7, 2022 04:38
@isaacbrodsky isaacbrodsky marked this pull request as ready for review December 11, 2022 15:18
@@ -27,6 +27,14 @@
*/
#define MAX(a, b) (((a) > (b)) ? (a) : (b))

// TODO: Verify
Copy link
Collaborator

Choose a reason for hiding this comment

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

What needs to be verified here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This comment seems to be on an outdated version of the file. That comment was removed when I added tests for these macros.

// This function needs a guard check to be safe and that guard
// check assumes k = 0.
CoordIJK ijkCopy3 = args->ijk;
if (ijkCopy3.k == 0 && !_ijkNormalizeCouldOverflow(&ijkCopy3)) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Would it make more sense to actually set ijkCopy3.k = 0, rather than discarding all random input where this was not the case?

@nrabinowitz
Copy link
Collaborator

Is there a strong reason to keep the unchecked versions of these functions? Is there a significant perf difference?

@isaacbrodsky
Copy link
Collaborator Author

Is there a strong reason to keep the unchecked versions of these functions? Is there a significant perf difference?

I didn't evaluate the performance difference. I don't believe there is a strong reason to keep the unchecked versions of the functions, although in use in cell indexing it should not be possible to overflow them, so they would have a bunch of if (NEVER(_upAp7(...))) guards.

return true;
}
if (SUB_INT32S_OVERFLOWS(0, min)) {
// 0 - INT32_MIN would overflow
Copy link
Collaborator

Choose a reason for hiding this comment

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

This comment should be:

Suggested change
// 0 - INT32_MIN would overflow
// 0 - min would overflow

Right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

In this case, min would be INT32_MIN, which is I believe the only case that would hit this condition.

@@ -27,6 +27,14 @@
*/
#define MAX(a, b) (((a) > (b)) ? (a) : (b))

/** Evaluates to true if a + b would overflow for int32 */
#define SUM_INT32S_OVERFLOWS(a, b) \
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: SUM and SUB look nearly identical so I didn't even notice they were different macros in the conditionals below at first. Maybe this one can be:

Suggested change
#define SUM_INT32S_OVERFLOWS(a, b) \
#define ADD_INT32S_OVERFLOWS(a, b) \

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That's reasonable. Renamed to ADD_...

Comment on lines 322 to 329
if (SUM_INT32S_OVERFLOWS(i, i)) {
return E_FAILED;
}
int i2 = i + i;
if (SUM_INT32S_OVERFLOWS(i2, i)) {
return E_FAILED;
}
int i3 = i2 + i;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe it would make sense to make a MUL_INT32S_OVERFLOWS(i, 3) check and skip this intermediate addition and check?

Copy link
Collaborator Author

@isaacbrodsky isaacbrodsky Dec 22, 2022

Choose a reason for hiding this comment

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

Is there a reference for a MUL_INT32S_OVERFLOWS we can use? I looked at the implementation you pointed to in a conversation last week but that involved floating point math, and I was skeptical there would be a significant difference with the intermediate addition+check approach. If another macro is being used for performance reasons, I'd prefer there be some form of benchmarking.

Comment on lines 371 to 378
if (SUM_INT32S_OVERFLOWS(j, j)) {
return E_FAILED;
}
int j2 = j + j;
if (SUM_INT32S_OVERFLOWS(j2, j)) {
return E_FAILED;
}
int j3 = j2 + j;
Copy link
Collaborator

Choose a reason for hiding this comment

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

A MUL_INT32S_OVERFLOWS check would work here, too.

@isaacbrodsky isaacbrodsky merged commit fc7f3dd into uber:master Dec 22, 2022
@isaacbrodsky isaacbrodsky deleted the fix-upap7-signed-integer-overflow branch December 22, 2022 23:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants