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

Correct handler range checks #235

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

frmdstryr
Copy link
Contributor

My IDE was giving a warning because the if statements were always false.

After looking at it more it looks like it was accidentally doing a size instead of array size check.

Since all the modes except for validate behavior have less than 15 handlers I made it fill out the array with the default handler and cast the mode to a 0xf so no if statement is needed.

@frmdstryr
Copy link
Contributor Author

I think the extra_modes field could be deleted from member if everything other than validate mode was collapsed to a size of 0xf?

@frmdstryr
Copy link
Contributor Author

Not sure if it really matters but moving index to after the other fields allows everything else to be aligned to 8 bytes.

Copy link

codecov bot commented Jan 21, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 97.67%. Comparing base (54adc3f) to head (3644c89).
Report is 2 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #235   +/-   ##
=======================================
  Coverage   97.67%   97.67%           
=======================================
  Files          24       24           
  Lines        1074     1074           
  Branches      162      162           
=======================================
  Hits         1049     1049           
  Misses         12       12           
  Partials       13       13           

@frmdstryr
Copy link
Contributor Author

frmdstryr commented Jan 21, 2025

I guess there's no need to add so many empty entries, think I should reduce some of them?

@frmdstryr
Copy link
Contributor Author

I did my static assert's wrong.. it should be 16.

@MatthieuDartiailh MatthieuDartiailh self-requested a review January 21, 2025 18:15
@sccolbert
Copy link
Member

Let me know when you are done making changes, and I will review.

@frmdstryr frmdstryr force-pushed the handler-size-checks branch from 02a7da9 to 8b32c1b Compare January 21, 2025 18:27
@frmdstryr
Copy link
Contributor Author

Ok, I think it's good now.

@frmdstryr
Copy link
Contributor Author

Since the Validate enum size is right at the limit of 5 bits do you think it should do a check on the handler size (in case someone tries to add something later)?

@@ -1007,7 +1007,7 @@ handlers[] = {
PyObject*
Member::validate( CAtom* atom, PyObject* oldvalue, PyObject* newvalue )
{
if( get_validate_mode() >= sizeof( handlers ) )
if( get_validate_mode() >= sizeof( handlers ) / sizeof( handler ) )
Copy link
Member

Choose a reason for hiding this comment

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

This looks different that the rest?

@sccolbert
Copy link
Member

Are we making this change just to satisfy an IDE linter?

@sccolbert
Copy link
Member

I think all we really need to static assert is that the largest **Mode enum value is < sizeof(**handlers).

@sccolbert
Copy link
Member

That way, things could still grow more handlers in the future if need-be.

@frmdstryr
Copy link
Contributor Author

Agree, let me update it.

@sccolbert
Copy link
Member

Maybe we convert these C-arrays into C++ arrays:
https://en.cppreference.com/w/cpp/container/array

Then we don't have to do the division to compute the length.

@frmdstryr
Copy link
Contributor Author

Good idea, do you want to take over or should I just update this?

@sccolbert
Copy link
Member

I think you are well equipped to do it. I'm just a gray-hair giving advice nowadays.

@frmdstryr frmdstryr force-pushed the handler-size-checks branch from c2a03c1 to 6797be7 Compare January 22, 2025 00:18
Comment on lines 215 to 214
if( get_default_value_mode() >= sizeof( handlers ) )
return no_op_handler( this, atom ); // LCOV_EXCL_LINE
return handlers[ get_default_value_mode() ]( this, atom );
Copy link
Member

Choose a reason for hiding this comment

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

Here you basically eliminated bound checks. It may be better to use std::array::at to benefit from the stdlib bound checks.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The check is done when it parses the enum value, but I agree it's still possible to go OOB if the mode bits somehow get misparsed or that check is bypassed.

My goal of originally looking at this was to try and delete if's... I'd rather go back to re-adding no_op_handlers than add another if.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

std::array<handler, 8> doesn't give a compile error if you give less than 8 entries so I'd rather just go back to 8b32c1b with maybe an additional static_assert check on the sentinel?

Copy link
Member

Choose a reason for hiding this comment

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

Can we statically assert that we do not have more enum variants than we have handlers? if we can do that we should be good.

@@ -187,8 +187,7 @@ typedef PyObject*
( *handler )( Member* member, CAtom* atom );


static handler
handlers[] = {
static const std::array<handler, DefaultValue::Mode::Last> handlers = {
Copy link
Member

Choose a reason for hiding this comment

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

I must be missing something but I cannot find in any doc that kind of syntax creation for an array (i.e. using a sentinel value). Could you share a reference ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it just implicitly casts the enum to size_t?

@frmdstryr frmdstryr force-pushed the handler-size-checks branch from 6797be7 to 0395936 Compare January 22, 2025 16:22
@frmdstryr frmdstryr force-pushed the handler-size-checks branch from 0395936 to 3644c89 Compare January 22, 2025 16:35
Copy link
Member

@MatthieuDartiailh MatthieuDartiailh left a comment

Choose a reason for hiding this comment

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

@sccolbert do you want to have another look ?

@sccolbert
Copy link
Member

Yes, I'd like a stab at it. Please don't merge this yet.

I will make another PR with a differing implementation of these same ideas.

@MatthieuDartiailh
Copy link
Member

@sccolbert are you still planning to make an alternate version ?

@sccolbert
Copy link
Member

sccolbert commented Mar 6, 2025 via email

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.

3 participants